iScroll中事件点击触发两次解决方案

 更新时间:2015年03月11日 09:52:01   投稿:hebedich  
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源代码,通过一个公共函数来实现。

以上就是本文所讲述的全部内容了,希望对大家学习使用iscroll滑动控件有所帮助

相关文章

  • JavaScript快速调试的两个技巧

    JavaScript快速调试的两个技巧

    这篇文章主要给大家介绍了关于JavaScript快速调试的两个技巧,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • JS实现点击发送验证码 xx秒后重新发送功能

    JS实现点击发送验证码 xx秒后重新发送功能

    在一些注册类的网站,经常遇到这样的需求,点击发送验证码,xx秒后重新发送,这样的功能怎么实现呢,接下来通过本文给大家分享js点击发送验证码 xx秒后重新发送功能,需要的朋友参考下吧
    2019-07-07
  • 深入探讨如何利用Canvas实现图片压缩与Base64转换

    深入探讨如何利用Canvas实现图片压缩与Base64转换

    随着Web应用的日益普及,图片的处理和优化已经成为现代开发的关键部分,本文主要介绍了如何利用Canvas技术,将图片进行压缩,并将其转换为Base64格式,感兴趣的小伙伴可以学习下
    2023-10-10
  • zepto.js 实时监听输入框的方法

    zepto.js 实时监听输入框的方法

    今天小编就为大家分享一篇zepto.js 实时监听输入框的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-12-12
  • JS验证邮件地址格式方法小结

    JS验证邮件地址格式方法小结

    这篇文章主要介绍了JS验证邮件地址格式方法,结合两个实例形式分析了JavaScript基于正则表达式进行邮件格式验证的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-12-12
  • javascript的回调函数应用示例

    javascript的回调函数应用示例

    回调函数就是一个通过函数指针调用的函数。下面以示例的方式为大家介绍下其具体的使用
    2014-02-02
  • 仿谷歌主页js动画效果实现代码

    仿谷歌主页js动画效果实现代码

    昨天看到谷歌的主页上出现了几个动画,发现不是flash做的,而是用js+图片实现的!今天把拷贝到的图片,用js实现了动画效果!
    2013-07-07
  • JavaScript对象封装的简单实现方法(3种方法)

    JavaScript对象封装的简单实现方法(3种方法)

    这篇文章主要介绍了JavaScript对象封装的简单实现方法,结合实例形式分析了3种简单实现方法与相关注意事项,需要的朋友可以参考下
    2017-01-01
  • uni-app 中清除定时器实现方法详解

    uni-app 中清除定时器实现方法详解

    这篇文章主要为大家介绍了uni-app 中清除定时器实现方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • 详解如何使用JSZip实现在浏览器中操作文件与文件夹

    详解如何使用JSZip实现在浏览器中操作文件与文件夹

    这篇文章主要介绍了如何使用JSZip实现在浏览器中操作文件与文件夹,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下
    2024-04-04

最新评论