首页 > 解决方案 > JQuery on click event listeners and functions, fire differently with different parameters?

问题描述

I have elements that when I click on them I need to run a function and that function needs to know what element was clicked on.

Example A:

var elements = $(".config-cell");
        for (var i = 0; i < elements.length; i++) {
            elements[i].addEventListener("click", function() {
                console.log("clicked");
            });
        }

When calling the function right there it works fine, however I don't know how to pass through the element to the function so it can use it.

So I tried using this method and found something strange.

Example B:

var elements = $(".config-cell");
        for (var i = 0; i < elements.length; i++) {
            elements[i].addEventListener("click", this.cellCrop());
        }

When simply calling the function located elsewhere I noticed when loading the window it just automatically fires the function and then it doesn't even add the event listener so any time you click after that nothing happens.


Bottom line I would like to be able to pass through the current element being clicked on and have it fire a function. But I would like to know out of curiosity why method B works the way it does.

Learned that it knows which to use because 'forEach' has a callback with parameters

.forEach(function callback(currentValue[, index[, array]])

For instance: How does this call back know what is supposed to be 'eachName' and 'index'

var friends = ["Mike", "Stacy", "Andy", "Rick"];
friends.forEach(function (eachName, index){
  console.log(index + 1 + ". " + eachName); // 1. Mike, 2. Stacy, 3. Andy, 4. Rick
});

And can you do this with .addEventListener instead of setting it as a var?

That being said is there a way to have it pass variables with your own function? Like:

var passthrough = 5;
            $(".config-cell").on("click", function(passthrough) {
                var five = passthrough;
                console.log(five);
            });

标签: javascriptjqueryeventsonclickaddeventlistener

解决方案


首先,this.cellCrop()调用函数, this.cellCrop传递它。因此,如果您想设置侦听器,那将是

elements[i].addEventListener("click", this.cellCrop);

现在要在函数内实际点击元素,您可以通过几种方式进行操作。

从自动传递给事件监听器的事件对象中使用currentTarget / target

elements[i].addEventListener("click", function(event){
  //the actual element clicked on
  var target = event.target;
  //the element the event was set on, in this case whatever elements[i] was
  var currentTarget = event.currentTarget;
});
//same using jQuery
$(elements[i]).click(function(event){
  var target = event.target;
  var currentTarget = event.currentTarget;
});

使用this关键字

elements[i].addEventListener("click", function(event){
  //this will refer to whatever elements[i] was
  var target = this;
});
//same using jQuery
$(elements[i]).click(function(event){
  var target = $(this);
});

这与使用对象方法相同:

obj = {
  cellCrop:function(event){
     var target = event.target;
     /* etc */
  },
  someOtherMethod:function(){
     //...
     elements[i].addEventListener("click",this.cellCrop);
     //or jQuery
     $(elements[i]).click(this.cellCrop);
     //...
  }
};
obj.someOtherMethod();

这个回调如何知道应该是'eachName'和'index'

因为该forEach方法的文档告诉使用它的人将如何调用它。因此,您根据该文档编写回调。

例如,回调forEach通常采用以下形式

function callback(currentValue[, index[, array]])

这意味着forEach()它内部将以这种方式调用您的回调

function forEach(callback){
  //`this` inside forEach is the array
  for(let i=0; i<this.length; i++){
     callback(this[i], i, this);
  }
}

至于将任意数据传递给函数,有几种方法可以做到:

将对函数的调用包装在匿名函数中,并使用更多参数显式调用该函数

obj = {
  cellProp:function(event,a,b,c){
    var element = event.currentTarget;
  }
}
//normal anonymous function
elements[i].addEventListener('click',function(e){
  obj.cellProp(e,1,2,3);
});
//fat arrow function
elements[i].addEventListener('click',e=>obj.cellProp(e,1,2,3))

在上面的 a、b 和 c 将分别包含值 1,2 和 3

您还可以使用诸如bind之类的方法,这将更改函数的thisArg请参阅此问题以了解更多信息),但也可以将参数传递给函数

obj = {
   //note event comes last as bind, call, and apply PREPEND arguments to the call
   cellProp:function(a,b,c,event){
      //`this` will change depending on the first
      //argument passed to bind
      var whatIsThis = this;
      var element = event.target;
   }
}
//passing obj as the first argument makes `this` refer to 
//obj within the function, all other arguments are PREPENDED
//so a,b, and c again will contain 1,2 and 3 respectively.
elements[i].addEventListener('click', obj.cellProp.bind(obj,1,2,3) );

对于 jQuery,您还可以在设置事件时使用对象传递数据

obj = {
  cellProp:function(event){
    var data = event.data;
    console.log(data.five);
  }
}

jQuery(elements[i]).click({five:5},this.cellProp);

推荐阅读