2016-03-30 6 views
2

Может ли кто-нибудь указать мне на решение для следующего? Я пытаюсь найти эквивалент JS для этого JQuery кода:JS-эквивалент для jQuery one()

var formSelector = 'my selector here'; 
var attribute = 'name'; 
var formHistory = []; 

$(formSelector).one('focusout', function(e) { 
    formHistory.push(e['target'].getAttribute(attribute)); 
}); 
+2

Вы можете прикрепить событие с [ 'addEventListener()'] (https: // разработчик .mozilla.org/EN-US/Docs/Web/API/EventTarget/а ddEventListener), а затем внутри него удалите с помощью ['removeEventListener()'] (https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener). Заметьте, что я не тестировал , – DontVoteMeDown

ответ

5

Вот очень простое решение с использованием атрибутов данных.

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>

+0

Спасибо, Джонатан! Это именно то, что я искал – quarrazzella

+0

Mate, это хорошо! Такой чистый и не-хаки. – PrometheanVigil

3

В EventListener обратного вызова, просто уничтожить слушатель событий :) Вот вспомогательная функция:

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>

+2

Возможно, было бы неплохо объявить функцию, прежде чем связывать ее с событием, поэтому вы можете ссылаться на функцию (вместо 'arguments.callee') при развязывании. Использование 'callee' сильно обескуражено. – ssube

+0

Спасибо за подсказку! – quarrazzella

0

Попробуйте написать реализацию 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);  
} 
+0

Спасибо за подсказку! – quarrazzella

0

Использование ES6 и некоторых закрытий это хороший способ сделать это.

const button = document.querySelector('button'); 
 

 
function composeHandler(element, event, handler, ...captureArgs) { 
 
    return function handlerFunc (...args) { 
 
    \t handler(...args); 
 
    element.removeEventListener(event, handlerFunc, ...captureArgs); 
 
    } 
 
} 
 

 
function addEventListenerOnce(element, event, handler, ...captureArgs) { 
 
\t 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>

0

Вы можете использовать once: true в параметре options передается addEventListener().

Поддержка браузера: 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>

Ссылка: