草庐IT

javascript - 触摸移动到第二次注册时出现问题

coder 2024-01-25 原文

我正在尝试为使用鼠标或 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>

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

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

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

最佳答案

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

关于javascript - 触摸移动到第二次注册时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19122926/

有关javascript - 触摸移动到第二次注册时出现问题的更多相关文章

  1. ruby - ECONNRESET (Whois::ConnectionError) - 尝试在 Ruby 中查询 Whois 时出错 - 2

    我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.

  2. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  3. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  4. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  5. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  6. ruby - Fast-stemmer 安装问题 - 2

    由于fast-stemmer的问题,我很难安装我想要的任何ruby​​gem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=

  7. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  8. ruby - 安装 Ruby 时遇到问题(无法下载资源 "readline--patch") - 2

    当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub

  9. ruby-on-rails - 如何重命名或移动 Rails 的 README_FOR_APP - 2

    当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?

  10. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

随机推荐