事件处理程序如何在函数内部工作?

时间:2018-03-10 18:25:24

标签: javascript

好的,所以我有一种过度思考的习惯。 虽然我对javascript相对较新,而且我的导师可能会在稍后介绍,但我很难理解事件处理程序如何在函数内部工作

例如,我将多个事件处理程序附加到对象。

function addListenerMulti(element, eventNames, listener){
  var events = eventNames.split('');
   for (var i=0, i<events.length; i++) {
      element.addEventListener(events[i], listener);
    }
}

addListenerMulti(color, 'change paste keyup', function(){

现在,当我开一个活动时,我说要按,然后放开钥匙。 addListenMulti函数将如何触发?

3 个答案:

答案 0 :(得分:3)

  

addListenMulti函数将如何触发?

它不会,它完成了它的工作。事件触发的函数是您将传递给 addListenMulti的函数,它是事件处理程序。 addListenMulti只是将处理程序挂钩到元素的函数。

旁注:该代码中有两个错误:

  1. for中,在,

  2. 之后,您有;而不是var i=0
  3. .split('')应为.split(' ')(带空格)

  4. 我不认为你是,但如果你想知道如何知道哪个事件触发了处理程序,那么它可以作为处理程序接收的对象的type属性。它的第一个论点。

    addListenerMulti(color, 'change paste keyup', function(e) {
        console.log(e.type); // Will be "change" or "paste" or "keyup"
    });
    

    function addListenerMulti(element, eventNames, listener){
        var events = eventNames.split(' ');
        for (var i = 0; i < events.length; i++) {
            element.addEventListener(events[i], listener);
        }
    }
    var color = document.getElementById("color");
    addListenerMulti(color, 'change paste keyup', function(e) {
        console.log(e.type); // Will be "change" or "paste" or "keyup"
    });
    <input id="color" type="text">

答案 1 :(得分:1)

您的代码包含语法错误,但逻辑是正确的。

事件处理程序通过在触发事件时调用函数来工作。例如 on keyup,将触发传递给事件侦听器的回调函数。 on keyup事件只会触发您为其设置'keyup'事件监听器的元素。如果输入已更改,则“更改”事件通常会在模糊时触发。当您将文本粘贴到type =“text”的输入中时,“粘贴”是您猜对了。并非所有元素都会被“改变”。具体细节可以在这里看到:

的addEventListener: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

事件(这是回调函数中的第一个参数): https://developer.mozilla.org/en-US/docs/Web/API/Event

但是你的代码可以改进,因为无需格式化这样的字符串并将其拆分,只需将每个事件名称放在一个数组中:

var color = document.getElementById("color-element");
['change', 'paste', 'keyup'].forEach(function(evt){
  color.addEventListener(evt, function(e){
    console.log("Event", evt, "fired");
  });
});
<input id="color-element" type="text">

通过对代码进行抽象化可以进一步改进这一点,因为这样可以更容易地再次使用代码。

var color = document.getElementById("color-element");
var events = ['change', 'paste', 'keyup'];
var eventCallback = function(e){
  console.log("Event", e.type, "fired");
}
function addListenerMulti(element, events, callback){
  events.forEach(function(evt){
    element.addEventListener(evt, callback);
  });
}
addListenerMulti(color, events, eventCallback);
<input id="color-element" type="text">

更简洁,使用ES6 - 加上调试错误处理......

const color = document.getElementById("color-element");
const events = ['change', 'paste', 'keyup'];
const eventCallback = function(e){
  console.log("Event", e.type, "fired");
}
function addListenerMulti(element, events, callback){
  if(typeof callback !== 'function'){
    throw new Error(`no callback function provided (of type ${typeof callback})`);
  }
  if(!element){
    throw new Error("no element provided");
  }
  if(!events){
    throw new Error("no events provided");
  }
  events.forEach(evt => {
    element.addEventListener(evt, callback);
  });
}
addListenerMulti(color, events, eventCallback);
<input id="color-element" type="text">

答案 2 :(得分:1)

只是为了澄清:

addListenerMulti(color, 'change paste keyup', function() {});

上面的调用只是将事件绑定到特定元素而没有别的,它的工作在那一刻就结束了。

  

当然,这是假设它以“编程方式”称为“#34;&#34;而不是从触发事件中执行。

实际触发的是来自绑定事件change paste keyup的处理程序。

function addListenerMulti(element, eventNames, listener){
  var events = eventNames.split('');
   for (var i=0, i<events.length; i++) {
                                          +---- This is what actually 
                                          |     will be triggered
                                          v
      element.addEventListener(events[i], listener);
    }
}