菜鸟教程小白 发表于 2022-12-12 15:11:11

javascript - 联系第二次注册时出现问题


                                            <p><p>我正在尝试为使用鼠标或 iPhone 等触摸屏设备工作的网站制作签名板。我成功地让垫子与鼠标一起工作,但在 iPhone 上使用触摸屏时遇到了一些奇怪的问题。签名板本身都是在客户端完成的,方法是在 3 个单独的数组中记录移动到、行到和新行位置,然后在用户绘图时使用 div 段中的 svg 标签构建行。 </p>

<p>我遇到的问题是,当使用触摸屏时,您绘制的第一条线一切正常,但如果您将手指放在屏幕上并将其放回以绘制新线,系统将停止记录移动用户的手指。这是代码示例。</p>

<p>Javascript:</p>

<pre><code>var moved;

//Load Event Listeners
function LoadList(){

    document.getElementById(&#39;SigCan&#39;).addEventListener(&#39;touchstart&#39;,function(e){e.preventDefault();TrackNow();},false);
    document.getElementById(&#39;SigCan&#39;).addEventListener(&#39;touchmove&#39;,function(e){e.preventDefault();touchMove(e);},false);
    document.getElementById(&#39;SigCan&#39;).addEventListener(&#39;touchend&#39;,function(e){e.preventDefault();StopTrack();},false);
    document.getElementById(&#39;SigCan&#39;).addEventListener(&#39;touchenter&#39;,function(e){e.preventDefault();TrackNow();},false);
}

function touchMove(e){
    e.preventDefault;
    //var sigobj = e.changedTouches;
    //var length;
    //length = length - 1

    //alert(length);
    getMouseXY(e.changedTouches);
}


//Set value to isSig to true (mainly for mouse movement to track when button is pressed down
function TrackNow(){
document.getElementById(&#39;&lt;%=isSig.ClientId%&gt;&#39;).value = &#39;True&#39;;

}


//Set new line flag and reset moved flag. Reset isSig value
function StopTrack(){
    if(moved == 1){
      //alert(&#39;Stopped&#39;);
      document.getElementById(&#39;&lt;%=isSig.ClientId%&gt;&#39;).value = &#39;False&#39;;
      newline = 1;
      moved = 0;
    }
}

// Main function to retrieve mouse x-y pos.s, fill textboxes for server side code.
function getMouseXY(e) {
    var signon;
    var obj;
    signon = document.getElementById(&#39;&lt;%=isSig.ClientId%&gt;&#39;).value;
    if (signon == &#39;True&#39;){

      OX = tempX;
      OY = tempY;



      if (OX == 0){
            OX = tempX;
      }
      if (OY == 0){
            OY = tempY;
      }
      obj = document.getElementById(&#39;SigCan&#39;);

      tempX = e.clientX - document.getElementById(&#39;SigCan&#39;).offsetLeft;
      tempY = e.clientY - document.getElementById(&#39;SigCan&#39;).offsetTop;

      //Remove all offsets
      if(obj.offsetParent){
            do{
                tempX -= obj.offsetLeft;
                tempY -= obj.offsetTop;
            }while (obj = obj.offsetParent)
      }

      //Fill newline array, reset new line flag, set the old X &amp; Y to current X &amp; Y so line starts and new position.
      if (newline == 1){
            newobj = OX + &#39;,&#39; + OY;
            OX = tempX;
            OY = tempY;
            newline = 0;
            n = n + 1;
      }
      //Fill moveto and lineto arrays
      mtarray = OX + &#34;,&#34; + OY;
      ltarray = tempX + &#34;,&#34; + tempY;

      //Fill textboxes to be used in server side code
      i = i + 1;
      if (mtarray != &#39;&#39;) {
            //document.getElementById(&#39;&lt;%=mtAr.ClientId%&gt;&#39;).value = tempX + &#34;,&#34; + tempY;
            document.getElementById(&#39;&lt;%=mtAr.ClientId%&gt;&#39;).value = mtarray.join(&#39;|&#39;);
            document.getElementById(&#39;&lt;%=ltAr.ClientId%&gt;&#39;).value = ltarray.join(&#39;|&#39;);
            document.getElementById(&#39;&lt;%=nobj.ClientId%&gt;&#39;).value = newobj.join(&#39;|&#39;);
      }
      mtarray = ltarray;

      //set moved flag to 1 so touchend code only runs after finger has been moved
      moved = 1;

      //Build svg and insert into inner html of the div segment
      return DrawSig();

    }
return true;
}

function DrawSig(){
    var inhtml;

    sigpath = &#39;&#39;

    //check browser
    ubrow = BrowserDetect.browser + &#39; &#39; + BrowserDetect.version;

    //get path information
    sigpath = BuildPath();

    //if using IE 8 or 7 insert vml into inner HTML of div
    if(ubrow == &#39;Explorer 8&#39;||ubrow == &#39;Explorer 7&#39;){

      document.namespaces.add(&#39;v&#39;, &#39;urn:schemas-microsoft-com:vml&#39;, &#34;#default#VML&#34;);
      inhtml = &#34;&lt;v:group style=&#39;position:absolute;antialias:true;height:100px;width:500px&#39; coordsize=&#39;500,100&#39; coordorigin=&#39;0,0&#39;&gt;&lt;v:shape style=&#39;postition:absolute;height:100px;width:500px&#39; strokeweight = &#39;3pt&#39; &gt;&lt;v:stroke joinstyle=&#39;round&#39; endcap=&#39;round&#39;/&gt;&#34;;
      inhtml = inhtml + &#34;&lt;v:path v =&#39;&#34; + sigpath + &#34; &#39;/&gt;&#34;;
      inhtml = inhtml + &#34;&lt;/v:shape&gt;&lt;/v:group&gt;&#34;;
      document.getElementById(&#39;SigCan&#39;).innerHTML = inhtml;
      //document.getElementById(&#39;ctl00_mtAr&#39;).value = inhtml

    }
    //if using any other browser insert svg into inner HTML of div
    else{
      inhtml = &#34;&lt;svg&gt;&lt;g fill=&#39;none&#39; stroke=&#39;black&#39; stroke-width=&#39;4&#39;&gt;&lt;path d=&#39;&#34; + sigpath + &#34;&#39;/&gt;&lt;/g&gt;&lt;/svg&gt;&#34;;
      document.getElementById(&#39;SigCan&#39;).innerHTML = inhtml;
      //document.getElementById(&#39;&lt;%=mtAr.ClientId%&gt;&#39;).value = &#39;Working as it should&#39;;
    }

    return false;
}   

function BuildPath(){
    var path;
    //Build vml path for ie 7 &amp; 8
    if(ubrow == &#39;Explorer 8&#39;||ubrow == &#39;Explorer 7&#39;){
            path = &#39;M &#39; + mtarray + &#39; L &#39; + ltarray;
      for(var p = 1;p &lt; i; p++){
            path = path + &#39; M &#39; + mtarray +&#39; L &#39; + ltarray;
      }
    }
    //Build svg path for other browsers
    else{
      path = &#39; M &#39; + mtarray.replace(&#39;,&#39;,&#39; &#39;) + &#39; L &#39; + ltarray.replace(&#39;,&#39;,&#39; &#39;);
      for(var p = 1;p &lt; i; p++){
            path = path + &#39; M &#39; + mtarray.replace(&#39;,&#39;,&#39; &#39;) +&#39; L &#39; + ltarray.replace(&#39;,&#39;,&#39; &#39;);
      }

    }
    return path;
}
</code></pre>

<p>HTML:</p>

<pre><code>&lt;body&gt;
    &lt;table&gt;
      &lt;tr&gt;
            &lt;td colspan=3&gt;
                &lt;div id =&#34;SigCan&#34; style=&#34;width:500px;height:100px;border:1px solid #c3c3c3;background:white;cursor:crosshair&#34; onmousemove = &#34;return getMouseXY(event);&#34; onmousedown = &#34;return TrackNow();&#34; onmouseup = &#34;return StopTrack();&#34;&gt;

                &lt;/div&gt;
                &lt;script&gt;
                  LoadList();
                &lt;/script&gt;
                &lt;asp:image runat = &#34;Server&#34; id =&#34;SigImg&#34;/&gt;
            &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
            &lt;td&gt;&lt;asp:textbox runat=&#34;Server&#34; id=&#34;mtAr&#34;/&gt;&lt;/td&gt;
            &lt;td&gt;&lt;asp:textbox runat=&#34;Server&#34; id=&#34;ltAr&#34;/&gt;&lt;asp:textbox runat=&#34;Server&#34; id =&#34;nobj&#34;/&gt;&lt;/td&gt;
            &lt;td&gt;&lt;asp:hiddenfield runat=&#34;Server&#34; id=&#34;isSig&#34;/&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
            &lt;td&gt;&lt;asp:button runat=&#34;Server&#34; id = &#34;btnSave&#34; text=&#34;Save Signature&#34; autopostback = &#34;False&#34;/&gt;&lt;asp:checkbox id=&#34;chkVerify&#34; runat=&#34;Server&#34; text=&#34;I verify the above signature is mine.&#34; visible=&#34;false&#34;/&gt;&lt;/td&gt;
            &lt;td&gt;&lt;asp:button id =&#34;btnVerify&#34; runat=&#34;server&#34; text=&#34;Verify&#34; visible = &#34;false&#34; onclick=&#34;VerifySig&#34; /&gt;&lt;/td&gt;
            &lt;td align=&#34;right&#34;&gt;&lt;asp:button id=&#34;btnClear&#34; runat=&#34;Server&#34; text = &#34;Clear Signature&#34; OnClientClick=&#34;return ClearSig();&#34;/&gt;&lt;/td&gt;
            &lt;td&gt;&lt;asp:button id=&#34;Sig&#34; runat=&#34;Server&#34; OnClientClick=&#34;return SigP();&#34; text=&#34;Give Me sig Path&#34;/&gt;&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
&lt;/body&gt;
</code></pre>

<p>我知道 Canvas 对象可能会更容易,但我需要让它在运行 IE8 的计算机和触摸屏上通过鼠标工作。到目前为止,我还没有找到解决方法,但我已将问题缩小到这行代码 <code>document.getElementById('SigCan').innerHTML = inhtml;</code> 如果我注释掉这一段代码一切正常,但这是将 SVG 路径放入 div 段的代码,所以我需要它。 </p>

<p>我发现的唯一另一件事是,当发生此错误时,由于某种原因,在绘制第一行后,touchend 事件似乎没有运行,我必须双击屏幕才能让 touchend 注册。当它停止响应时,我可以再次按下屏幕并将其记录为另一个触摸点。我对触摸屏非常陌生,并且在 Javascript 方面只是一个业余爱好者,所以我想知道是否有人可以提供帮助。 </p>

<p><strong>编辑 1:</strong> 我还没有找到解决办法,但我确实发现了实际发生的情况。出于某种原因,当您将手指从触摸屏上移开然后放回触摸屏上时,无论您在哪里移动手指,touchmove 事件都只会触发一次,并且永远不会再次触发。出于某种原因,如果您在发生这种情况时将手指从屏幕上移开,则 touchend 事件不会运行,但如果您在目标区域中点击屏幕,它就会运行。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>好的,找到问题了。显然,当将 DIV 的 innerHTML 设置为 SVG 时,触摸事件的目标第二次变成了没有触摸事件的 SVG 本身。在多次尝试修复它之后,最好的方法是在包含 SVG 的当前 DIV 上放置另一个 DIV,然后在新的 DIV 元素上触发所有触摸事件。我必须将两个 div 的位置都更改为绝对位置,以便新的 div 可以放在旧的 div 上。这会导致设计问题,但这些问题很容易解决。现在似乎一切正常。</p></p>
                                   
                                                <p style="font-size: 20px;">关于javascript - 联系第二次注册时出现问题,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/19122926/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/19122926/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: javascript - 联系第二次注册时出现问题