The event click in iScroll triggers the solution twice

  • 2020-05-12 02:14:59
  • OfStack

I've read a lot of my friends' articles about this before. For example, use a variable to record the interval of execution. I feel like I have to go every time. I like to choose tools before moving bricks. The solution is simple. iScroll actually intercepts the touchstart and touchend events when a browser is clicked. Use js at touchend to trigger the element's onclick event (_end). In practice, touchend was executed first, then onclick's correlation function was executed once. This creates a headache with one click and two triggers. This is not a problem in itself. This is a problem because we have to look at the source code for iScroll. The solution to this problem is to reject the second execution of the function. And that's my logic. We can remove the function bound on the onclick event after executing the code that triggers the click event in the _end function. Then readd the event a few hundred milliseconds after the timer. Here's an example:


// To deal with before
<span onclick="test()"> Double-click on the test </span>
// After processing
<span onclick="void(0)"> Double-click on the test </span>

After removing the onclick correlation function this second time will naturally no longer trigger the test function. In order to use it again in the next time, we can restore the content of onclick by using setTimeout.

The modified iscroll source code (about 550 ~570 lines, _end function) :


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);
                                /** The following code is the new code **/
                                // Find the binding click The element of the event.
                                var obj = $(target).attr("onclick") != null ? $(target) : $(target).parents("[onclick]")[0];
                                if (obj != null) {
                                    var clickContent = $(obj).attr("onclick");
                                    if (clickContent != "void(0)") {
                                        // Use the new properties to store the old ones click function
                                        $(obj).attr("data-clickbak", $(obj).attr("onclick"));
                                        // change onclick Attribute values.
                                        $(obj).attr("onclick", "void(0)");
                                        // Prevent violence click
                                        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);

The _clickBack function and the hashBox snippet (added before the _end function)


       hashBox: [],
       /* Restores the event of the clicked object */
        _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);
        }

Of course, it is also possible to implement a public function without modifying the iscroll source code.

That's all for this article, and I hope it will help you learn to use iscroll slide controls


Related articles: