【问题标题】:How to cleanup events and attached objects from DOM elements before Intercooler.JS removes them?如何在 Intercooler.JS 删除事件和附加对象之前从 DOM 元素中清除它们?
【发布时间】:2020-04-01 12:38:44
【问题描述】:
我有一个用 Laravel 制作的静态服务器端生成表单,我正在尝试将 Intercooler.js 添加到其中。在此表单中,我使用 javascript 库将输入掩码应用于某些文本字段。如果没有 Intercooler,提交表单后,页面会被重定向,并且该页面中的所有 DOM 对象都会被浏览器销毁,因此我不必关心清理工作。
使用 Intercooler.js 和其他类似框架,无需重新加载页面。相反,页面的内容被交换并且 DOM 对象被从页面中移除,但是由于它们仍然可以附加到其他对象和事件,它们仍然可以在内存中。
所以我的问题是:我在哪里连接 Intercooler.js 中的清洁代码?我知道 Intercooler.ready(function(elt)) 存在,但根据文档,我只收到添加的新元素,而不是旧元素。它没有让我有机会清理附加到要删除的元素的任何东西。
我通读了文档,但找不到任何可以用于此目的的内容。
【问题讨论】:
标签:
javascript
dom
code-cleanup
intercooler.js
【解决方案1】:
我在 Gitter 社区询问过这个问题。为了在元素被移除之前清理代码,你应该监听 beforeSwap.ic 事件。为了简化它的使用,我创建了一个函数,灵感来自 turbolinks、stimulus 和 unpoly 如何处理这种情况。
const compiler = function(selector, fn) {
Intercooler.ready(function(elt) {
let cleanupFn;
const $el = $(elt).find(selector);
if ($el.length > 0) {
cleanupFn = fn($el);
}
// Cleanup
$(document).on("beforeSwap.ic", function(e) {
const el = e.target;
//Check if the element selected is inside the element being swapped
if ($(el).find(selector).length > 0) {
if (cleanupFn) cleanupFn();
}
});
});
};
export default compiler;
这是一个使用它的例子:
compiler("form.userForm", elt => {
const im = new Inputmask("999.999.999-99");
const inputCpf = $("input[name=cpf]")[0];
im.mask(inputCpf);
return () => {
if (inputCpf.inputmask) inputCpf.inputmask.remove();
};
});
当您调用 compiler 函数时,您会从要监控的元素中传递 CSS 选择器。当该元素进入页面时,他会通过 jQuery 被选中并传递给提供的回调。
为了清理,您从回调中返回一个函数,该函数将在删除所选元素之前被调用。