zoukankan      html  css  js  c++  java
  • iScroll4中事件点击一次却触发两次解决方案

      iScroll是我们在做手机网页中常用的滑动控件之一。单说其功能已相当丰富。但个别时候也是会掉坑的,正好这次就遇上了。在android的app中嵌入网页时不少手机会出现一次点击两次触发的现象。经过一段时间的折腾,总算想到了一个还算合理的解决放案。

      之前也看了很多朋友的文章里有讲这个问题。比如使用一个变量记录执行的间隔时间什么的。感觉每次都要去撸一下,比较累人。本人喜欢搬砖前先选工具。其实解决这个方法很简单。iScroll呢其实是截获了点击浏览器时的touchstart和touchend事件。在touchend的时候使用js去触发元素的onclick事件(_end这个函数)。而在实际操作中,先执行了touchend,然后再执行了一次onclick的相关函数。这样就形成了头疼的一次点击两次触发。这本来就一个不是问题的问题。之所以说这是个问题,是因为这样是我们不得不去看一看iScroll的源代码。解决这个问题的途径就是拒绝第二次执行函数。而我的逻辑也正是如此。我们可以在执行完_end函数中的触发click事件的代码后,移除onclick事件上绑定的函数。然后在定时几百毫秒之后在重新把这个事件添加上去。举个例子:

    //处理之前
    <span onclick="test()">双击测试</span>
    
    //处理之后
    <span onclick="void(0)">双击测试</span>

    在移除onclick相关函数之后这个第二次就自然不会再触发test函数了。为了下一次还能继续使用我们可以使用setTimeout的方式把onclick的内容还原回去。

    改造后的iscroll源代码(约550行~570行的样子,_end函数中):

    that.doubleTapTimer = setTimeout(function () {
                                that.doubleTapTimer = null;
    
                                // Find the last touched element
                                target = point.target;
                                while (target.nodeType != 1) target = target.parentNode;
    
                                if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA') {
    
    
                                    ev = doc.createEvent('MouseEvents');
                                    ev.initMouseEvent('click', true, true, e.view, 1,
                                        point.screenX, point.screenY, point.clientX, point.clientY,
                                        e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,
                                        0, null);
                                    ev._fake = true;
                                    target.dispatchEvent(ev);
                                    /**以下代码为新增代码**/
                                    //找到绑定click事件的元素。
                                    var obj = $(target).attr("onclick") != null ? $(target) : $(target).parents("[onclick]")[0];
                                    if (obj != null) {
                                        var clickContent = $(obj).attr("onclick");
                                        if (clickContent != "void(0)") {
                                            //利用新的属性来存储原有的click函数
                                            $(obj).attr("data-clickbak", $(obj).attr("onclick"));
                                            //改变onclick属性值。
                                            $(obj).attr("onclick", "void(0)");
                                            //防止暴力点击
                                            if (that.hashBox.length>0) {
                                                for (var _i = 0; _i < that.hashBox.length; _i++)
                                                {
                                                    if (that.hashBox[_i] == $(obj)) {
                                                        that.hashBox.splice(_i, 1);
                                                        break;
                                                    }
                                                }
                                            }  
                                            that.hashBox.push($(obj));
                                            that._clickBack();
                                        }
    
                                    }//end
                                }
                            }, that.options.zoom ? 250 : 0);

    _clickBack函数及hashBox代码片段(加在_end函数之前)

           hashBox: [],
           /*还原被点击对象的事件*/
            _clickBack: function () {
                var that = this;
                setTimeout(function () {
                    if (that.hashBox.length > 0) {
                        var obj = that.hashBox.pop();
                        obj.attr("onclick", obj.attr("data-clickbak"));
    
                        if (that.hashBox.length > 0) that._clickBack();
                    }
                }, 500);
            }

    当然,也可以不修改 iscroll源代码,通过一个公共函数来实现。 

  • 相关阅读:
    java内存模型
    类、对象和接口
    Python--数据存储:pickle模块的使用讲解
    Python--常用的内置函数
    Python--迭代器和生成器的定义和案例
    Python--作业2--对员工信息文件,实现增删改查操作
    Python--文本基本操作
    Python--字符串基本操作
    Python--字典基本操作
    Python--作业1--购物车程序
  • 原文地址:https://www.cnblogs.com/aser1989/p/4287976.html
Copyright © 2011-2022 走看看