Why do I recommend event delegation instead of batch binding?

Source: Internet
Author: User

I haven't written a blog for a long time. I 've been confused recently. It's another weekend. I 'd like to try my best to record something for myself. In case of amnesia, I want to go back and find no information.

What we want to record today is simple, that is, event delegation. I believe that anyone who is working in the frontend direction, or even not in the frontend direction, should be familiar with dom element event delegation. So today we are not talking about "event delegation? It means why it is needed.

[Development based on front-end templates]

Let's talk about this first. Why do we need to talk about it first, Because event delegation is quite valuable in this mode.

Front-end templates-I believe everyone is familiar with them and they are very easy to play. More and more web jobs begin to be handed over to the front-end. It contains this thing. Of course, we will not discuss the advantages of front-end templates today. It depends on some problems that may be encountered in the next use process.

For example, simple:

<! DOCTYPE html> <meta charset = "UTF-8"/> <body> <script> var $ T = new function () {var $ = this; // escape this. escape = function (string) {return (''+ string ). replace (// g ,'&'). replace (/</g, '<'). replace (/>/g, '> '). replace (/"/g ,'"'). replace (/'/g ,'''). replace (// g, '/') ;}; // template this. templateSettings = {evaluate:/{([\ s \ S] + ?)}} /G, interpolate:/{= ([\ s \ S] + ?)}} /G, escape:/{-([\ s \ S] + ?)}} /G}; var noMatch = /. ^/; var unescape = function (code) {return code. replace (// \\\\/g ,'\\'). replace (/\ '/g, "'") ;}; this. template = function (str, data) {var c = $. templateSettings; var tmpl = 'var _ p = [], print = function () {__ p. push. apply (_ p, arguments) ;}; '+' with (obj ||{}) {__ p. push (\ ''+ str. replace (// \/g ,'\\\\'). replace (/'/g ,"\\'"). replace (c. escape | noMatch, function (match, code) {return "', $. escape ("+ unescape (code) + "),'";}). replace (c. interpolate | noMatch, function (match, code) {return "'," + unescape (code) + ",'";}). replace (c. evaluate | noMatch, function (match, code) {return "');" + unescape (code ). replace (/[\ r \ n \ t]/g, '') +" ;__ p. push ('";}). replace (/\ r/g, '\ R '). replace (/\ n/g, '\ n '). replace (/\ t/g, '\ t') + "');} return _ p. join ('');"; var func = new Function ('obj ',' $ ', tmpl); if (data) return func (data, $ ); return function (data) {return func. call (this, data, $) ;}}}var tpl1 = '<div> I generated {= name }}< button onclick = "say. call (this) "> one </button> </div> ', tpl2 = '<div> I generated {= name }}< button onclick = "say. call (this) "> two </button> </div> '; function say () {alert (this. value | this. innerHTML)} document. body. innerHTML = $ T. template (tpl1, {name: 'horyun'}) </script> </body>

You may consider this:

Var tpl1 = '<div> I generated {= name }}< button onclick = "say. call (this) "> one </button> </div> ', tpl2 = '<div> I generated {= name }}< button onclick = "say. call (this) "> two </button> </div> ';

This onclick always feels awkward. But we still need to bind events. We can use addEventListener or attachEvent directly. Once the innerHTML is reset for the template, will the previous addEventListener be useless ....

I cannot rebind it once every time, right ?? It is also easy to bring out memory leaks and other things.

Therefore, event delegation is useful at this time.

[Use delegation to distribute events]

A simple delegate example may look like the following code:

<ul id="dele-ul"><li>1</li><li>2</li><li>3</li></ul><script>
var $E = {};$E.on = function (o, e, f) {return o.addEventListener ? o.addEventListener(e, f, false) : o.attachEvent('on'+e, function () { f.call(o) });};$E.on(document.getElementById('dele-ul'), 'click', function (e) {var tar = e.target || e.srcElement;if (tar.nodeName.toLowerCase() == 'li') {alert(tar.innerHTML);}})</script>

It may be noted that there is a code to filter the specified dom.

if (tar.nodeName.toLowerCase() == 'li') { ... }

When elements are simple, they are fine. When dom levels are complex. We need a little bit of effort.

We need to bind the event element, add a flag, and then use event bubbles.

Simple, such as the following code:

$E = new function () {    function on (o, e, f) {return o.addEventListener ? o.addEventListener(e, f, false) : o.attachEvent('on'+e, function () { f.call(o) });    };    function bubbleTo (el, endEl, key) {        if (!el || (el && el == document)) {            return null;        } else if (el == endEl || (el.getAttribute && el.getAttribute(key))) {            return el;        } else if (el.parentNode) {            return bubbleTo(el.parentNode, endEl, key);        } else {            return null;        }    }    function dispatch (el, type, key, distributor) {        if (typeof key == 'object') {            distributor = key;            key = 'data-cmd';        }        $E.on(el, type, function (e) {            var tar = bubbleTo(e.target, el, key);             if (tar) {                var cmd = tar.getAttribute(key);                distributor[cmd] && distributor[cmd].call && distributor[cmd].call(tar, e, tar);            }        });    }this.on = on;this.bubbleTo = bubbleTo;this.dispatch = dispatch;}

The principle is to add a designated flag. If a designated attribute is found to bubble up, the system stops and responds to the corresponding event. Of course, the premise is that there is a convention (this Convention attribute cannot be used in disorder ^. ^)

So we can use it like this:

<body><section>...<button data-custom-cmd="sayHi"><button>        <div id="tpl-con">            ...        </div>...</section><script>    var tpl1 = '<a data-custom-cmd="walk"><span>{{= name }}</span></a>';    // use tpl    ...        // dispatch Event$E.dispatch(document.body, 'click', 'data-custom-cmd', {'sayHi': function (e, tar) {// todo},'walk': function (e, tar) {// todo}...});</script></body>

As a result, almost all click events are put into the body for processing.

You don't have to worry about templated templete. The previous events will be lost.

At the same time, it can also greatly reduce some concerns about memory leakage.

[Postscript]

Of course, this is just a very simple technique and experience, and it is not applicable to all situations, such as resize and mousemove. However, for commonly used applications such as click, mousedown, and mouseup. In most cases, you can consider it.

Some unexpected problems may be solved. (^)

There is no need to talk about simple things. A little trick is just for reference. It is estimated that many of you have already started doing so.

  

  

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.