سؤال

I am developing a page that will create many <div>s and appending them to a container <div>. I need to know which one of them is being clicked on. At first, I figured putting an eventListener on each one of them would be fine. However, I just read an article about using Smart Event Handlers here: Best Practices for Speeding Up Your Web Site. And it talks about using only 1 eventListener and figuring out which one of the elements the event originates from.

EDIT

I removed the previous example, here is a small example that is much closer to my target functionality and illustrates why it would be preferable to have one listener that dispatches what was clicked on. The main thing is that the <div> is what knows which index in an array needs to be grabbed for data. However, the data gets presented in <div>s that are inside the <div> that knows the array index and the event doesn't hook with him for some reason.

When you run it, you see that the log only lists the contact whenever the green "middle" <div> gets clicked but not the red "information" <div>s. How can I get the red information <div>s to trigger the listener as well without adding a zillion listeners?

JSFiddle

<!DOCTYPE html>
<html>
   <head>
      <title>Bubbling</title>
      <meta charset="UTF-8">
      <style>
         div{
            margin: 10px;
            padding: 10px;
            width: 200px;
         }
         #big{
            background: #ccffcc;
         }
         .contactDiv{
            background: #99ff99;
         }
         .nameDiv, .phoneDiv{
            background: #ff9999;
         }
         #log{
            background: #ccccff;
         }
      </style>
   </head>
   <body>
      <div id="log">I log stuff</div>
      <button id="adder">Add Some Div</button>
      <!--Highest div that encloses multiple other div-->
      <div id="big"></div>
      <script>
         var log = document.getElementById("log"),
                 adderButton = document.getElementById("adder"),
                 bigDiv = document.getElementById("big"),
                 numDivsToMake = 100,
                 i, contactDiv, nameDiv, phoneDiv,
                 contacts = [];

         for (i = 0; i < numDivsToMake; i++) {
            contacts.push({
               name: "Bob-" + i,
               phone: "555-1234"
            });
         }

         // Make more divs whenever we click the super button
         adderButton.addEventListener("click", function() {
            // Don't make more
            adderButton.setAttribute("disabled");

            // Make the divs with data
            for (i = 0; i < numDivsToMake; i++) {

               // Make name and number divs
               contactDiv = document.createElement("div");
               nameDiv = document.createElement("div");
               phoneDiv = document.createElement("div");

               // Add classes
               contactDiv.className = "contactDiv";
               nameDiv.className = "nameDiv";
               phoneDiv.className = "phoneDiv";

               // Set their values
               nameDiv.innerHTML = contacts[i].name;
               phoneDiv.innerHTML = contacts[i].phone;

               // Set the container to know how to get back to the data in the array
               contactDiv.setAttribute("data-contactId", i);

               // Add them to the dom
               bigDiv.appendChild(contactDiv);
               contactDiv.appendChild(nameDiv);
               contactDiv.appendChild(phoneDiv);
            }
         });

         // Make smart handler
         bigDiv.addEventListener("click", function(e) {
            // Get whether the element has the attribute we want
            var att = e.target.getAttribute("data-contactId");
            // Say if it does or not
            if (att) {
               log.innerHTML = "You clicked: " +
                       contacts[att].name + " " +
                       contacts[att].phone;
            }
            else {
               console.log("No attribute");
            }
         });
      </script>
   </body>
</html>
هل كانت مفيدة؟

المحلول

I think I understand what you're doing. The event delegation you've set up in the fiddle seems to work well. The data attribute you want to select could easily be selected inside your click handler by querying the DOM. Instead of looking at the source of the click if you know you always want the data, just do another document.getElementById to retrieve your data. I think you're trying to collapse two steps into one in a way that won't work with your design.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top