Причина этого заключается в том, что вызов bind()
для функции возвращает новый экземпляр этой функции:
function someHandler() {
alert('hi');
}
const someHandlerBinded = someHandler.bind(document);
// Returns false, seeing as these are different instances of the function
console.log( someHandlerBinded === someHandler );
При установке обработчика событий напрямую через результат bind()
, как вы находитесь во втором блоке кода, это приводит к тому, что новый экземпляр этого обработчика функции будетперешел на addEventListener()
.Это, в свою очередь, означает, что последующая попытка удалить этот обработчик в строке:
document.removeEventListener("click", checkClick);
не удастся, поскольку определенная функция checkClick
отличается от фактической функции обработчика, используемой для этого события щелчка(т. е. новый экземпляр функции, возвращаемый из function checkClick(){ ... }.bind()
)
Один из способов решения этой проблемы может быть следующим:
choicesList.addEventListener("click", function() {
// Declare the bound version of the click handler
const boundClickHandler = function checkClick(e) {
if (!e) e = event;
if (!this.contains(e.target)) {
// Removing the result of bind, rather than the declared
// checkClick handler
document.removeEventListener("click", boundClickHandler);
}
}.bind(this)
// Adding the result of bind as you currently are doing
document.addEventListener("click", boundClickHandler, false);
});