properly clean up events from event handlers (also handle corner case where multiple listeners are added for the same even)
This commit is contained in:
Carson Gross
2023-04-28 11:38:42 -06:00
parent 6c0aa11f62
commit 9ee51a59ff
2 changed files with 31 additions and 4 deletions

View File

@@ -921,8 +921,9 @@ return (function () {
});
}
if (internalData.onHandlers) {
for (var eventName of internalData.onHandlers) {
element.removeEventListener(eventName, internalData.onHandlers[eventName]);
for (let i = 0; i < internalData.onHandlers.length; i++) {
const handlerInfo = internalData.onHandlers[i];
element.removeEventListener(handlerInfo.name, handlerInfo.handler);
}
}
}
@@ -1867,12 +1868,12 @@ return (function () {
function addHxOnEventHandler(elt, eventName, code) {
var nodeData = getInternalData(elt);
nodeData.onHandlers ||= {};
nodeData.onHandlers = [];
var func = new Function("event", code + "; return;");
var listener = elt.addEventListener(eventName, function (e) {
return func.call(elt, e);
});
nodeData.onHandlers[eventName] = listener;
nodeData.onHandlers.push({event:eventName, listener:listener});
return {nodeData, code, func, listener};
}

View File

@@ -93,4 +93,30 @@ describe("hx-on attribute", function() {
delete window.foo;
});
it("de-initializes hx-on content properly", function () {
window.tempCount = 0;
this.server.respondWith("POST", "/test", function (xhr) {
xhr.respond(200, {}, "<button id='foo' hx-on=\"click: window.tempCount++;\">increment</button>");
});
var div = make("<div hx-post='/test'>Foo</div>");
// get response
div.click();
this.server.respond();
// click button
byId('foo').click();
window.tempCount.should.equal(1);
// get second response
div.click();
this.server.respond();
// click button again
byId('foo').click();
window.tempCount.should.equal(2);
delete window.tempCount;
});
});