我有下面的 html 代码,是根据这篇文章 Capture Signature using HTML5 and iPad 中的第五个答案改编的,以通过表单收集签名。然而,我遇到的问题是用户可以在不创建签名(签名)的情况下提交表单。有谁知道我如何才能提交表格?
<svg id="sig_panel" viewBox="0 0 300 100">
<rect id="r" width="100%" height="100%" fill="#ffa"/>
<line x1="0" y1="80" x2="300" y2="80" stroke="#000000"
stroke-width="1" stroke-dasharray="3"
shape-rendering="crispEdges" pointer-events="none" />
<path id="p" stroke="navy" stroke-width="2" fill="none"
pointer-events="none"/>
</svg>
<div class="flex">
<button id="clear">Clear signature</button>
</div>
下面的示例是此answer中代码的修改版本。它具有一个提交到实时测试服务器的
<form>
,并使用隐藏的<textarea>
来存储signaturePath
,并确保在使用以下命令提交<form>
之前有一个签名: required
属性。示例中注释了详细信息。
const rSVG = document.getElementById("rect"),
pSVG = document.getElementById("path"),
svg = document.getElementById("sig"),
clear = document.getElementById("clear"),
data = document.getElementById("data");
let signaturePath = "",
isDown = false;
function isTouchEvent(e) {
return e.type.match(/^touch/);
}
function getCoords(e) {
if (isTouchEvent(e)) {
return e.targetTouches[0].clientX + "," + e.targetTouches[0].clientY;
}
return e.clientX + "," + e.clientY;
}
/**
* Functions down(), move(), and up() will assign signaturePath
* to textarea#data [value]:
* data.value = signaturePath;
*/
function down(e) {
signaturePath += "M" + getCoords(e) + " ";
pSVG.setAttribute("d", signaturePath);
isDown = true;
if (isTouchEvent(e)) e.preventDefault();
data.value = signaturePath;
}
function move(e) {
if (isDown) {
signaturePath += "L" + getCoords(e) + " ";
pSVG.setAttribute("d", signaturePath);
}
if (isTouchEvent(e)) e.preventDefault();
data.value = signaturePath;
}
function up(e) {
isDown = false;
if (isTouchEvent(e)) e.preventDefault();
data.value = signaturePath;
}
rSVG.addEventListener("touchstart", down, false);
rSVG.addEventListener("touchmove", move, false);
rSVG.addEventListener("touchend", up, false);
rSVG.addEventListener("mousedown", down, false);
rSVG.addEventListener("mousemove", move, false);
rSVG.addEventListener("mouseup", up, false);
rSVG.addEventListener("mouseout", up, false);
function clearSignature() {
signaturePath = "";
pSVG.setAttribute("d", "");
data.value = "";
}
clear.addEventListener("click", clearSignature);
svg {
margin: .5em;
border: 1px solid gray;
border-radius: .5em;
}
.flex {
display: flex;
}
button {
margin: .5em;
}
/**
* <textarea id="data required> is hidden from user.
*/
#data {
display: block;
height: 0;
margin-top: -15px;
margin-left: 150px;
border: none;
outline: none;
font-size: 0;
resize: none;
}
<!--
Wrap everything in a <form>
This <form> will send the signaturePath to a live test server
if the <textarea id="data" required> (aka textarea#data) has
[value] (ie text). If textarea#data doesn't have any [value],
then <form> will not submit and a popup prompts user to,
"Please fill out this field".
-->
<form action="https://httpbin.org/post" method="post" target="response">
<svg id="sig" xmlns="http://www.w3.org/2000/svg" width="300" height="100" viewBox="0 0 300 100">
<rect id="rect" width="300" height="100" fill="#ffa"/>
<line x1="0" y1="80" x2="300" y2="80" stroke="#666" stroke-width="1" stroke-dasharray="3" shape-rendering="crispEdges" pointer-events="none"/>
<path id="path" stroke="navy" stroke-width="2" fill="none" pointer-events="none"/>
</svg>
<!--
- textarea#data needs [name] attribute in order to submit
it's [value] to server.
- [required] attribute ensures that <form> will not submit
- If textarea#data [value] is false (ie '').
textarea#data CSS styles conceals it from users.
-->
<textarea id="data" name="data" required></textarea>
<div class="flex">
<!--
If a <button> doesn't actually submit a <form>,
add [type="button"] to it.
-->
<button id="clear" type="button">Clear Signature</button>
<!--
Plain <button> will submit <form> when clicked
-->
<button>Submit Signature</button>
</div>
</form>
<!--
If <form> is successfully submitted (200), this <iframe>
will display the server response. Look for form.data to
review the signaturePath (ex. "M131,76 L131,76 L131,76 ...").
-->
<iframe name="response"></iframe>