JS Native Implementation example of Fastclick event

Source: Internet
Author: User
Note: I study JavaScript time is not long, recently has been doing web-side mobile phone web and application, because recently useful to similar fastclick function, in the original program with Touchstart and Touchend event simulation, now try to encapsulate it, The following two problematic scenarios have been obtained. Share it with others and seek the guidance of the Great God

In mobile web App development, the 300ms latency of the Click event can cause slow response, especially in low-end machines. Using the Touchstart or Touchend event will conflict with the default wheel event, which is not what we expected.

So, self-made, clothed, wrote a quick Click event native JS code (considering the environment of web App development, we don't need to consider the compatibility of IE and other browsers for the time being).

Implementation Method 1 is as follows:

function Fastclickevent (handler) {var Fastclick = {handler:handler, bind:function (query) {var targetlist      = Document.queryselectorall (query);        for (Var i=0,len=targetlist.length;i<len;i++) {targetlist[i].addeventlistener (' Touchstart ', handleEvent);      Targetlist[i].addeventlistener (' Touchend ', handleevent);      }}, Unbind:function (query) {var targetlist = document.queryselectorall (query);         for (Var i=0,len=targetlist.length;i<len;i++) {targetlist[i].removeeventlistener (' Touchstart ', handleEvent);      Targetlist[i].removeeventlistener (' Touchend ', handleevent);   }}} var Touchx = 0, touchy = 0;        function Handleevent (event) {switch (event.type) {case ' Touchstart ': Touchx = Event.touches[0].clientx;        touchy = Event.touches[0].clienty;      Break        Case ' Touchend ': var x = Event.changedtouches[0].clientx;        var y = event.changedtouches[0].clienty; if (Math.Abs (Touchx-x) <5| |        Math.Abs (touchy-y) <5) Fastclick.handler (event);    Break   }  }; return fastclick;};

Principle: Determine whether a single click is based on the change in position of successive Touchstart and Touchend events.

Call: Registers a fastclickevent event with a handler function. The registered Fastclickevent event is then bound to the corresponding element through the bind method. As follows:

var handler = function (event) {  Console.log (event.target.id+ "fastclicked");} var fastclick = new Fastclickevent (handler); Fastclick.bind ("div");

In this code, we have registered the Fastclick handler event for all DIV elements. Call Fastclick.unbind to unbind the element.

But this code has a problem, in order to let the Handleevent event can access to Touchx,touchy. I used the method of closures, which means that every time new Fastclickevent event object is injected into memory, repeated handleevent functions are added. As for the repeated touchx,touchy, it is needless to say more.

Novice Help: Originally wanted to write the Handleevent function into the prototype, but one problem is that handleevent this object is Windows, that is, I do not get touchx and touchy and handler objects, caused an access error.

One simple solution is to register only one fastclickevent event, and then determine the content of the response in the handler based on the actual value of the event.target (that is, the object on which the event occurred).

However, this means that you must be very familiar with all Fastclick events.

The advantage of this approach is that since you have only one handleevent function, basically, you don't need to unbind any element of the Fastclick event (even if you do not want to trigger the Fastclick event) until the page is released. The handler function still exists in memory). Moreover, you can easily use bind (query) to add any dynamically generated elements of the Fastclick event, as long as you have written the appropriate handlers in the handler function.

If you want to add multiple Fastclick events, and you may want to register in more than one place, then just new Fastclickevent object and then bind to the corresponding element.

The following describes a method for using the Eventtarget class. First Look at Eventtarget

function Eventtarget () {  this.handlers = {};} Eventtarget.prototype = {  Constructor:eventtarget,  addhandler:function (type,handler) {    if (typeof This.handlers[type] = = "undefined") {      this.handlers[type]=[];    }    This.handlers[type].push (handler);  },  fire:function (event) {    if (!event.target) {      Event.target = This;    }    if (This.handlers[event.type] instanceof Array) {      var handlers = This.handlers[event.type];      for (Var i=0,len=handlers.length;i<len;i++) {        Handlers[i] (event);}}  ,  Removehandler:function (type,handler) {    if (This.handlers[type] instanceof Array) {      var handlers = This.handlers[type];      for (Var i=0,len=handler.length;i<len;i++) {        if (Handlers[i]==handler) {break          ;        }      }      Handlers.splice (i,1);}}}  

This class is an interface for adding, removing, and implementing custom classes. Refer to the third edition of Advanced JavaScript programming p616-617

So, how to turn this class into our Fastclick event interface?

Define a global variable that uses this variable to complete all Fastclick event registrations, deletions, and additions

var Fastclick = function () {var fastclick = new Eventtarget (), Touchx = 0, touchy = 0;        function Handleevent (event) {switch (event.type) {case ' Touchstart ': Touchx = Event.touches[0].clientx;        touchy = Event.touches[0].clienty;      Break        Case ' Touchend ': var x = Event.changedtouches[0].clientx;        var y = event.changedtouches[0].clienty; if (Math.Abs (touchx-x) <5| |        Math.Abs (touchy-y) <5) fastclick.fire ({type: ' Fastclick ', target:event.target});    Break  }  };    Fastclick.bind = function (query) {var targetlist = document.queryselectorall (query);      for (Var i=0,len=targetlist.length;i<len;i++) {targetlist[i].addeventlistener (' Touchstart ', handleEvent);    Targetlist[i].addeventlistener (' Touchend ', handleevent);    }} fastclick.unbind = function (query) {var targetlist = document.queryselectorall (query); for (Var i=0,len=targetlist.length;i<len;i++) {Targetlist[i].removeeventlIstener (' Touchstart ', handleevent);    Targetlist[i].removeeventlistener (' Touchend ', handleevent); }} return Fastclick;} ();

This global variable Fastclick can be used to add arbitrary fastclick events.

Let's talk about how to invoke it.

To add an event function:

Fastclick.addhandler (' Fastclick ', function (event) {});

Delete Event function://Anonymous event cannot be deleted

Fastclick.removehandler (' Fastclick ', handler);

Binding elements

Fastclick.bind ("div");

Unbind

Fastclick.unbind ("div");

In this way, we also need to pre-event.target in the handler event, because although this method can add multiple Fastclick events, the event is executed one at a-in the process of execution, that is, a function that you do not want to execute may be executed.

The benefit is that you can register multiple Fastclick events, and you can execute them without having to bind again.
For example

Fastclick.bind ("div"); Fastclick.addhandler (handler1); Fastclick.addhandler (Handler2);

Then, when a Quick Click event occurs on any div element, handler1 and Handler2 are executed sequentially.

If we call RemoveHandler to delete handler1 or handler2, then the corresponding function will no longer execute.

In addition, it should be noted that in the handler function, the This object is an array of fastclick.handlers[' Fastclick '], and in general, we use Event.target to get the object that the event occurred.

This method basically overcomes the problem of the above method, and it does not make much sense to repeat new for this object unless you do not want to pre-event.target it and generate a whole bunch of faskclick classes, but this is obviously not efficient.

Novice Help: How to implement a function that implements the binding of a particular element, that is, the ability to invoke Fastclick.bind (Query,handler), and to implement a Fastclick event that adds handler to an element that conforms to the query condition.

  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.