P. Lau
P. Lau

Reputation: 165

use addEventListener to replace each onClick

I have unordered lists below for fruits, animals, trees....about 100 buttons with same class:

<ul>
   <li><button class="bb" value="apple" onClick="aJax(value)">Apple</button></li>
   <li>Banana
      <ul>
         <li><button class="bb" value="green_banana" onClick="aJax(value)">Green_banana</button></li>
         <li><button class="bb" value="yellow_banana" onClick="aJax(value)">Yellow Banana</button></li>
      </ul>
   </li>
   <li><button class="bb" value="cherry" onClick="aJax(value)">Cherry</button></li>
   <li><button class="bb" value="cow..................and more....
</ul>

If clicked, I want to pass value to Ajax to return data from mySql:

  <script>
  function aJax(value)
      xmlhttp = new XMLHttpRequest();
      xmlhttp.open("GET","some_page.php?q="+value,true);
      xmlhttp.send();
      xmlhttp.onreadystatechange = function() {
      if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
       document.getElementById("some_id").innerHTML = xmlhttp.responseText;}
                                                }
                 }
  </script>

Is it possible to use addEventListener in my case above to replace each onClick? How to do it if I want to put the JS code on the header? Pls help, I need it in native JS. Thanks.

Upvotes: 0

Views: 558

Answers (4)

n00dl3
n00dl3

Reputation: 21564

While other answers are right, if your list is long, you might delegate the click to the ul element :

function logValue(evt){
  let target = evt.target;
  // only console.log if the click target has class "bb"
  if(target.classList.contains("bb")){
    console.log(target.value)
  }
}

// wait for the document to be loaded
window.addEventListener("load",()=>{
  let list = document.querySelector(".my-list");
  if(list){
    //delegate click handler to the <ul> element
    list.addEventListener("click", logValue);
  }
});
<ul class="my-list">
  <li><button class="bb" value="apple">Apple</button></li>
  <li>Banana
    <ul>
       <li><button class="bb" value="green_banana">Green_banana</button></li>
       <li><button class="bb" value="yellow_banana">Yellow Banana</button></li>
    </ul>
  </li>
  <li><button class="bb" value="cherry">Cherry</button></li>
</ul>

Upvotes: 1

taha
taha

Reputation: 1017

the simplest way (no loops needed)

var container = document.querySelector("ul");
container.addEventListener("click", doSomething, false);
 
function doSomething(e) {
    if (e.target !== e.currentTarget) {
        var clickedItem = e.target.value;
        console.log(clickedItem);
    }
    e.stopPropagation();
}
<ul>
   <li><button class="bb" value="apple" >Apple</button></li>
   <li><button class="bb" value="banana">Banana</button></li>
   <li><button class="bb" value="cherry">Cherry</button></li>
</ul>

check this awesome article, I'm pretty sure it's what you're looking for Handling Events for Many Elements

Upvotes: 1

Rostyslav Kuzmovych
Rostyslav Kuzmovych

Reputation: 241

Yes, you can do it :

var bbs = document.getElementsByClassName("bb");
for(var i =0; i< bbs.length; i++){
  bbs[i].addEventListener('click', function(){
    var attr = this.value;
    console.log(attr);
  });
}
<ul>
   <li><button class="bb" value="apple" >Apple</button></li>
   <li><button class="bb" value="banana">Banana</button></li>
   <li><button class="bb" value="cherry">Cherry</button></li>
</ul>

Instead of console.log(attr); you can call your custom function

Upvotes: 3

Liara T&#39;soni
Liara T&#39;soni

Reputation: 28

try that :

window.addEventListener( 'load' , function () {

    var list = document.querySelectorAll( 'ul > li > button' );

    for ( var i = 0 , l = list.length ; i < l ; i++ ) {

        list[ i ].addEventListener( 'click' , function () {
            aJax( this.value );
        } );

    }

} );

Upvotes: 1

Related Questions