触摸问题移动到第二次注册

时间:2013-10-01 18:04:52

标签: javascript ios javascript-events svg touch

我正在尝试为使用鼠标或iPhone等触摸屏设备工作的网站制作签名板。我成功地使用鼠标操作垫,但是在iPhone上使用触摸屏时我遇到了一些奇怪的问题。签名板本身都是通过在3个单独的阵列中记录移动到,线到和新线位置完成客户端,然后在用户绘图时使用div段中的svg标记构建线。

我遇到的问题是,当使用触摸屏时,一切都可以正常显示您绘制的第一行但是如果你拿着屏幕的手指和它重新打开的位置来绘制一条新线,系统会停止注册这一动作用户的手指。以下是代码示例。

使用Javascript:

var moved;

//Load Event Listeners
function LoadList(){

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

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

    //alert(length);
    getMouseXY(e.changedTouches[0]);
}


//Set value to isSig to true (mainly for mouse movement to track when button is pressed down
function TrackNow(){
document.getElementById('<%=isSig.ClientId%>').value = 'True';

}


//Set new line flag and reset moved flag. Reset isSig value
function StopTrack(){
    if(moved == 1){
        //alert('Stopped');
        document.getElementById('<%=isSig.ClientId%>').value = 'False';
        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('<%=isSig.ClientId%>').value;
    if (signon == 'True'){

        OX = tempX;
        OY = tempY;



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

        tempX = e.clientX - document.getElementById('SigCan').offsetLeft;
        tempY = e.clientY - document.getElementById('SigCan').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 & Y to current X & Y so line starts and new position.
        if (newline == 1){
            newobj[n] = OX + ',' + OY;
            OX = tempX;
            OY = tempY;
            newline = 0;
            n = n + 1;
        }
        //Fill moveto and lineto arrays
        mtarray[i] = OX + "," + OY;
        ltarray[i] = tempX + "," + tempY;

        //Fill textboxes to be used in server side code
        i = i + 1;
        if (mtarray[1] != '') {
            //document.getElementById('<%=mtAr.ClientId%>').value = tempX + "," + tempY;
            document.getElementById('<%=mtAr.ClientId%>').value = mtarray.join('|');
            document.getElementById('<%=ltAr.ClientId%>').value = ltarray.join('|');
            document.getElementById('<%=nobj.ClientId%>').value = newobj.join('|');
        }
        mtarray[0] = ltarray[0];

        //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 = ''

    //check browser
    ubrow = BrowserDetect.browser + ' ' + BrowserDetect.version;

    //get path information
    sigpath = BuildPath();

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

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

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

    return false;
}   

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

    }
    return path;
}

HTML:

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

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

我知道画布对象可能会更容易,但我需要在运行ie8和触摸屏的计算机上使用鼠标。到目前为止,我还没有找到修复程序,但我已经将问题缩小到这行代码document.getElementById('SigCan').innerHTML = inhtml;如果我注释掉这段代码,一切正常,但这是放置svg路径的代码进入div部分所以我需要它 我发现的唯一另一件事是,当发生这个错误时,看来touchend事件在第一行被绘制之后没有运行由于某种原因我必须双击屏幕才能让touchend注册。它达到了这样的程度,当它停止响应时,我可以再次按下屏幕并将其记录为另一个触摸点。我是一个非常新的触摸屏,我只是一个业余的javascript,所以我想知道是否有人可以帮助。

谢谢

编辑1:我还没有找到修复程序,但我确实发现了实际发生的情况。出于某种原因,当您将手指从触摸屏上移开然后将其放回触摸移动事件时,只会触发一次并且无论您在何处移动手指都不会再次触发。出于某种原因,如果您在发生这种情况时将手指从屏幕上移开,则touchend事件不会运行,但如果您点击目标区域中的屏幕,它将会运行。

1 个答案:

答案 0 :(得分:1)

好的,发现了这个问题。显然,当将DIV的innerHTML设置为SVG时,第二次触摸事件的目标成为没有触摸事件的SVG本身。在多次尝试修复它之后,最有效的方法是在包含SVG的当前DIV上放置另一个DIV,然后在新的DIV元素上触发所有触摸事件。我不得不将div的位置更改为绝对位置,因此可以将旧div放在旧位置上。这会导致设计问题,但很容易修复。一切似乎现在都有效。