Мне нужно знать, сколько раз нажата кнопка и что-то делать на каждом третьем клике ...
// Declare counter outside event handler's scope
var counter = 0;
var element = document.getElementById('button');
element.addEventListener("click", function() {
// Increment outside counter
counter++;
if (counter === 3) {
// Do something every third time
console.log("Third time's the charm!");
// Reset counter
counter = 0;
}
});
Теперь это сработает, но оно вторгнется во внешнюю область, добавив переменную, единственной целью которой является отслеживание счета , В некоторых ситуациях это было бы предпочтительнее, так как вашему внешнему приложению может потребоваться доступ к этой информации. Но в этом случае мы изменяем только поведение каждого третьего клика, поэтому предпочтительно включать эту функциональность внутри обработчика событий.
var element = document.getElementById('button');
element.addEventListener("click", (function() {
// init the count to 0
var count = 0;
return function(e) { // <- This function becomes the click handler
count++; // and will retain access to the above `count`
if (count === 3) {
// Do something every third time
console.log("Third time's the charm!");
//Reset counter
count = 0;
}
};
})());
Обратите внимание на несколько вещей.
В приведенном выше примере я использую поведение закрытия JavaScript. Такое поведение позволяет любой функции иметь доступ к области, в которой она была создана, на неопределенный срок. Чтобы практически применить это, я немедленно вызываю функцию, которая возвращает другую функцию, и потому что возвращаемая функция имеет доступ к внутренней переменной счетчика (из-за описанного выше поведения закрытия), это приводит к закрытой области для использования в результате функция ... Не так просто? Давайте разбавим его ...
Простое однострочное закрытие
// _______________________Immediately invoked______________________
// | |
// | Scope retained for use ___Returned as the____ |
// | only by returned function | value of func | |
// | | | | | |
// v v v v v v
var func = (function() { var a = 'val'; return function() { alert(a); }; })();
Все переменные за пределами возвращаемой функции доступны для возвращаемой функции, но они не доступны непосредственно для возвращаемый объект функции ...
func(); // Alerts "val"
func.a; // Undefined
Получите его? Таким образом, в нашем основном примере переменная count содержится в закрытии и всегда доступна для обработчика событий, поэтому она сохраняет свое состояние от щелчка до щелчка.
Кроме того, это состояние частной переменной полностью доступно для оба чтения и присвоение его частным переменным области.
Там вы идете; вы теперь полностью инкапсулируете это поведение.
Полная запись в блоге (включая соображения jQuery)