-3

In javascript coding, there is an event delegation technique.

This is the way to delegate event that I only know :

Give an event(like click) to father elem, and get that event using 'target'.

For example :

document.addEventListener('click', function(event), true/false);

function(event){
get event codes;
get target codes;

switch (target.id) {
case 'outside_1': blah~~~; break;
case 'outside_2': blah~~~; break;
}}

In these codes, if target has some child node and clicked it, event will not run.

situation : click the <a>;;

case 1: <a id="outside_1"> nav 1 </a>  // this will work.

case 2: <a id="outside_2"> <img class="navImg"> <p> nav 2 </p> </a>   // this will not work.

And if there is no way to make 'code:case 2' works, I think delegate event technique is not that good way of js coding...

How do you think about that, guys?

goJson
  • 173
  • 2
  • 5
  • 11
  • 2
    If event delegation is done wrong (and only checks the explicit target), it doesn't work of course. But there *is* a way to make case 2 work - just traverse the parentNodes until the currentTarget. In general, [event delegation](http://stackoverflow.com/q/1687296/1048572) works very well and can [often be applied](http://stackoverflow.com/a/18818647/1048572) – Bergi Sep 01 '14 at 15:49

1 Answers1

0

Because the event has bubbled all the way up to the document level (assuming you've attached the handler in the bubble phase; if not, then the question doesn't make sense because that's not how event delegation works), all you need to do is check to see if:

  • the event target is the element identified as one whose events you want to handle, or
  • the event target is a descendant of a delegated element.

In modern browsers, this is pretty easy. Say you wanted to catch "click" events on your <a> element with the id "outside_2". In a WebKit browser that'd look like:

document.addEventListener('click', function(event) {
    var target = event.target;
    if (target.webkitMatchesSelector("#outside_2, #outside_2 *")) {
        // yes, handle event
    }
}, false);

Here's a handy function to give you a "matches" function for any element:

function matcher(element) {
  var names = [
      "matches",
      "matchesSelector",
      "webkitMatchesSelector",
      "mozMatchesSelector",
      "msMatchesSelector",
      "oMatchesSelector"
  ];
  for (var i = 0; i < names.length; ++i) {
      if (element[names[i]])
          return element[names[i]].bind(element);
  }
  throw new Error("No matches facility in this environment.");
}

Then the handler can work for all (modern) browsers:

document.addEventListener('click', function(event) {
    var target = event.target;
    if (matcher(target)("#outside_2, #outside_2 *")) {
        // yes, handle event
    }
}, false);

The "matches" method is available in all modern browsers (IE9+).

Pointy
  • 371,531
  • 55
  • 528
  • 584