[英]Get element event listener and store it
我想从元素中删除事件侦听器,然后再将其分配回去。 有没有一种方法来获取它并存储在像var storedListener = Element.getEventListener('click')
一样的变量smth中,如var storedListener = Element.getEventListener('click')
,这样以后我就可以执行Element.addEventListener('click', storedListener)
这样的事情了?
更新
侦听器在模板内部分配,我使用Angular 2。
<div *ngFor="let entry of data; let i=index">
<div class="element-description" (click)="editElementDescription(i)">{{entry.description}}</div>
</div>
我想要做的是单击它后将<div>
内部的内容设置为<input>
,以便更改值并将其发送到服务器。 在editElementDescription()
内部,执行以下操作:
public editElementDescription(index: number): void {
var elementDescription: HTMLDivElement = <HTMLDivElement>document.getElementsByClassName('element-description')[index];
elementDescription.removeEventListener('click');
elementDescription.innerHTML = '<input id="change-description-input" type="text" value="' + elementDescription.innerHTML + '"/>';
}
我删除了该click
侦听器,因为如果再单击一次<input>
内容,它将获得该innerHTML
。 因此,我们的想法是为该<input>
元素分配一个change
侦听器,该侦听器将用它的值替换<input>
并将其父<div>
用作其原始侦听器。
您将其弄错了...没有可从JavaScript访问的事件侦听器列表...您唯一可以做的就是在知道来源的情况下删除/添加事件。
有两个函数可以操作事件侦听器:
一个对象可以具有多个相同类型的事件...区别它们的唯一方法是通过调用一个确切的函数。
请注意,如果它是jQuery
,则可以,因为它具有自己的事件堆栈...下面的示例:
var events = $("#object1").data('events');
var $object2 = $("#object2");
if (events) {
for(var eventType in events){
for(var idx in events[eventType]){
$object2[eventType](events[eventType][idx].handler);
}
$('#object1').off(eventType);
}
}
为了删除添加了.addEventListener()
的侦听.addEventListener()
,您必须跟踪侦听器函数引用,并稍后使用.removeEventListener()
删除它。
像这样:
var btn = document.getElementById('btn');
var btn_add = document.getElementById('btn-add-listener');
var btn_remove = document.getElementById('btn-remove-listener');
var fnListener = function(e) {
alert('Clicked!');
};
btn_add.addEventListener('click', function() {
btn.addEventListener('click', fnListener);
});
btn_remove.addEventListener('click', function() {
btn.removeEventListener('click', fnListener);
});
考虑到您的实际问题,我建议采用另一种方法:除了处理事件之外,还可以在元素中设置一个data-
attribute属性以指示其已打开。 然后,如果属性不存在,则只需修改内部HTML。
像这样:
function editElementDescription(index) {
var elementDescription = document.getElementsByClassName('element-description')[index];
var isOpen = elementDescription.getAttribute('data-isOpen');
if (!isOpen) {
elementDescription.setAttribute('data-isOpen', 'true');
elementDescription.innerHTML = '<input id="change-description-input" type="text" value="' + elementDescription.innerHTML + '"/>';
}
}
不,这是不可能的,因为.getEventListener
仅可用于调试目的 。 不幸的是,标准JavaScript中没有办法以编程方式取回附加到对象的EventListeners
,并且任何试图实现此目的的库都将依赖不稳定的非标准接口,该接口可能会在一天中停产。
因此,如果您的目标是操纵无法控制的库添加的侦听器,那么您将很不走运。
另一方面,如果您控制环境,那么如果您要将同一个侦听器附加到多个对象,则可以存储对附加回调的引用,或者之后使用.removeEventListener
将其删除。
实际上,您可以在页面上没有任何其他内容运行之前先猴子补丁EventTarget.prototype.addEventListener
以支持此功能,这对于您遇到的任何问题来说并不是一个很干净的解决方案,但是如果您确实需要,可以快速解决它的实现不完善(不支持useCapture
参数):
// getEventListener polyfill, run this before anything else on your page.
(function monkeyPatchGetEventListeners(EventTarget) {
const eventListeners = new WeakMap();
const origAddEventListener = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function patchedAddEventListener(eventType, listener, ...args) {
let allListeners;
if (eventListeners.has(this)) {
allListeners = eventListeners.get(this);
} else {
allListeners = new Map();
eventListeners.set(this, allListeners);
}
let listeners;
if (allListeners.has(eventType)) {
listeners = allListeners.get(eventType);
} else {
listeners = [];
allListeners.set(eventType, listeners);
}
listeners.push(listener);
return origAddEventListener.call(this, eventType, listener,...args);
}
const origRemoveEventListener = EventTarget.prototype.removeEventListener;
EventTarget.prototype.removeEventListener = function patchedRemoveEventListener(eventType, listener, ...args) {
const call = () => origRemoveEventListener(eventType, listener, useCapture, ...args);
const allListeners = eventListeners.get(this);
if (!allListeners) { return call(); }
const listeners = allListeners.get(this);
if (!listeners) { return call(); }
const index = listeners.indexOf(listener);
if (index === -1) { return call(); }
index.splice(index, 1);
return call();
}
EventTarget.prototype.getEventListeners = function patchedGetEventListeners(eventType) {
const allListeners = eventListeners.get(this);
return allListeners && allListeners.get(eventType);
}
})(EventTarget);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.