JS equivalent for jQuery one()

JS equivalent for jQuery one()

本文关键字:one jQuery equivalent for JS      更新时间:2023-09-26

有人能为我指出以下问题的解决方案吗?我正试图为这个jQuery代码找到一个等价的JS:

var formSelector = 'my selector here';
var attribute = 'name';
var formHistory = [];
$(formSelector).one('focusout', function(e) {
    formHistory.push(e['target'].getAttribute(attribute));
});

更新

在大多数浏览器中,您现在可以在选项对象中传递once: true

document.getElementById('btn').addEventListener('click', () => {
  console.log('Hello and goodbye');
}, {
  once: true,
});
<button id="btn">Click me</button>


老办法

在eventlistener回调中,只需销毁事件listener:)这里有一个辅助功能:

function oneTimeEvent(element, eventType, callback) {
  element.addEventListener(eventType, function(e) {
    e.target.removeEventListener(e.type, arguments.callee);
    return callback(e);
  });
}
var btn = document.querySelector('button');
oneTimeEvent(btn, 'click', function () {
  alert('♫ You clicked me once, but I won''t let you click me twice, yeah!');
});
<button>Click me!</button>

这里有一个使用数据属性的非常简单的解决方案。

document.querySelector('#click').addEventListener('click', function(e){
    if(e.currentTarget.dataset.triggered) return;
    e.currentTarget.dataset.triggered = true;
    alert('clicked');
})
<button id="click">Click me</button>

您可以在传递给addEventListener()options参数中使用once: true

浏览器支持:Chrome 55+,Firefox 50+,Safari 10,Edge 16,不支持IE。

document.getElementById('foo').addEventListener('click', function(e) {
  alert('This will be displayed only once.');
}, { once: true });
<button id="foo">Click me</button>

参考:

  • Once Upon an Event Listener
  • 我可以使用。。。"once"事件侦听器选项

使用ES6和一些闭包这是一种很好的方法

const button = document.querySelector('button');
function composeHandler(element, event, handler, ...captureArgs) {
  return function handlerFunc (...args) {
  	handler(...args);
    element.removeEventListener(event, handlerFunc, ...captureArgs);
  }
}
function addEventListenerOnce(element, event, handler, ...captureArgs) {
	element.addEventListener(event, composeHandler(element, event, handler, ...captureArgs), ...captureArgs);
}
addEventListenerOnce(button, 'click', (e) => alert('clicked on button ' + e.target.innerText), true)
<button>
  Click me once!
</button>

尝试编写one的实现。像这样:

function one(element,eventType,callback,self) {
    var one=function(event) {
        try{
            callback.call(self,event);
        } finally {
            element.removeEventListener(eventType,one);
        }
    }
    element.addEventListener(eventType,one);    
}