如何以普通方式复制事件侦听器 Javascript
How to copy an event listener in plain Javascript
所以我正在对 Wordpress 插件进行一些覆盖。我需要在一个元素上复制事件侦听器,然后替换该元素并将其添加回去。事件侦听器由插件生成。
我认为 getEventListeners() 会起作用,但我读到它只能在控制台中起作用。如果是这种情况,我真的很震惊。我们正处于可怕的 2020 年,我没有找到一个明显的解决方案。
这里的解决方案是什么?
下面是我在假设 getEventListeners 不仅仅是一个控制台函数的情况下尝试实现的代码。
// Edit Affirm
(function replaceAffirm() {
if (document.querySelector(".affirm-modal-trigger")) {
const learnMore = document.querySelector("#learn-more");
const modalTrigger = document.querySelector(".affirm-modal-trigger");
const clickHandler = getEventListeners(modalTrigger).click[0].listener;
const substr = learnMore.innerHTML
.toString()
.substring(
learnMore.innerHTML.indexOf("h") + 2,
learnMore.innerHTML.length
);
learnMore.innerHTML = "Easy Financing with " + substr;
modalTrigger.addEventListener("click", clickHandler);
} else {
setTimeout(function () {
replaceAffirm();
}, 250);
}
})();
HTML
<p id="learn-more" class="affirm-as-low-as" data-amount="20000" data-affirm-color="white" data-learnmore-show="true" data-page-type="product">
Starting at
<span class="affirm-ala-price"></span>
/mo with
<span class="__affirm-logo __affirm-logo-white __ligature__affirm_full_logo__ __processed">Affirm</span>.
<a class="affirm-modal-trigger" aria-label="Prequalify Now (opens in modal)" href="javascript:void(0)">Prequalify now</a>
</p>
是的,等待 Html 元素加载并检查直到它加载是可以的,这是等待它的正确方法之一。
根据我对你的问题的理解,你只需要更改 learn-more 元素的文本即可。
为此,没有必要复制事件侦听器然后再次绑定它。
无需替换整个元素,只需更改保留相同元素的文本即可。
所以它默认与事件监听器绑定。
您无法复制事件侦听器,但似乎由于您 HTML 的结构,您更有可能不需要重新添加它。与其编辑 HTML 并通过这样做删除事件侦听器,最好的办法是围绕它进行编辑。
如果您想删除文本节点,您可以遍历 childNodes
并分离出应该删除的内容。
然后要在需要的位置重建适当的文本,您可以使用 insertAdjacentText
if (document.querySelector(".affirm-modal-trigger")) {
const learnMore = document.querySelector("#learn-more");
const modalTrigger = document.querySelector(".affirm-modal-trigger");
const children = Array.from(learnMore.childNodes);
children.forEach(child => {
if (child.nodeType === Node.TEXT_NODE || child.matches(".affirm-ala-price")) {
if (learnMore.contains(child)) {
learnMore.removeChild(child);
}
}
});
learnMore.insertAdjacentText("afterBegin", "Easy Financing With ");
modalTrigger.insertAdjacentText("beforeBegin", " ");
} else {
setTimeout(function() {
replaceAffirm();
}, 250);
}
<p id="learn-more" class="affirm-as-low-as" data-amount="20000" data-affirm-color="white" data-learnmore-show="true" data-page-type="product">
Starting at
<span class="affirm-ala-price"></span> /mo with
<span class="__affirm-logo __affirm-logo-white __ligature__affirm_full_logo__ __processed">Affirm</span>.
<a class="affirm-modal-trigger" aria-label="Prequalify Now (opens in modal)" href="javascript:void(0)">Prequalify now</a>
</p>
所以我正在对 Wordpress 插件进行一些覆盖。我需要在一个元素上复制事件侦听器,然后替换该元素并将其添加回去。事件侦听器由插件生成。
我认为 getEventListeners() 会起作用,但我读到它只能在控制台中起作用。如果是这种情况,我真的很震惊。我们正处于可怕的 2020 年,我没有找到一个明显的解决方案。
这里的解决方案是什么?
下面是我在假设 getEventListeners 不仅仅是一个控制台函数的情况下尝试实现的代码。
// Edit Affirm
(function replaceAffirm() {
if (document.querySelector(".affirm-modal-trigger")) {
const learnMore = document.querySelector("#learn-more");
const modalTrigger = document.querySelector(".affirm-modal-trigger");
const clickHandler = getEventListeners(modalTrigger).click[0].listener;
const substr = learnMore.innerHTML
.toString()
.substring(
learnMore.innerHTML.indexOf("h") + 2,
learnMore.innerHTML.length
);
learnMore.innerHTML = "Easy Financing with " + substr;
modalTrigger.addEventListener("click", clickHandler);
} else {
setTimeout(function () {
replaceAffirm();
}, 250);
}
})();
HTML
<p id="learn-more" class="affirm-as-low-as" data-amount="20000" data-affirm-color="white" data-learnmore-show="true" data-page-type="product">
Starting at
<span class="affirm-ala-price"></span>
/mo with
<span class="__affirm-logo __affirm-logo-white __ligature__affirm_full_logo__ __processed">Affirm</span>.
<a class="affirm-modal-trigger" aria-label="Prequalify Now (opens in modal)" href="javascript:void(0)">Prequalify now</a>
</p>
是的,等待 Html 元素加载并检查直到它加载是可以的,这是等待它的正确方法之一。
根据我对你的问题的理解,你只需要更改 learn-more 元素的文本即可。 为此,没有必要复制事件侦听器然后再次绑定它。
无需替换整个元素,只需更改保留相同元素的文本即可。 所以它默认与事件监听器绑定。
您无法复制事件侦听器,但似乎由于您 HTML 的结构,您更有可能不需要重新添加它。与其编辑 HTML 并通过这样做删除事件侦听器,最好的办法是围绕它进行编辑。
如果您想删除文本节点,您可以遍历 childNodes
并分离出应该删除的内容。
然后要在需要的位置重建适当的文本,您可以使用 insertAdjacentText
if (document.querySelector(".affirm-modal-trigger")) {
const learnMore = document.querySelector("#learn-more");
const modalTrigger = document.querySelector(".affirm-modal-trigger");
const children = Array.from(learnMore.childNodes);
children.forEach(child => {
if (child.nodeType === Node.TEXT_NODE || child.matches(".affirm-ala-price")) {
if (learnMore.contains(child)) {
learnMore.removeChild(child);
}
}
});
learnMore.insertAdjacentText("afterBegin", "Easy Financing With ");
modalTrigger.insertAdjacentText("beforeBegin", " ");
} else {
setTimeout(function() {
replaceAffirm();
}, 250);
}
<p id="learn-more" class="affirm-as-low-as" data-amount="20000" data-affirm-color="white" data-learnmore-show="true" data-page-type="product">
Starting at
<span class="affirm-ala-price"></span> /mo with
<span class="__affirm-logo __affirm-logo-white __ligature__affirm_full_logo__ __processed">Affirm</span>.
<a class="affirm-modal-trigger" aria-label="Prequalify Now (opens in modal)" href="javascript:void(0)">Prequalify now</a>
</p>