admin管理员组文章数量:1318565
I want to remove an event listener from an element and later assign it back. Is there a way to get it and store in a variable smth like var storedListener = Element.getEventListener('click')
, so that later I can do something like Element.addEventListener('click', storedListener)
?
UPDATE
Listener is assigned inside template, I use Angular 2. It's
<div *ngFor="let entry of data; let i=index">
<div class="element-description" (click)="editElementDescription(i)">{{entry.description}}</div>
</div>
What I want to do is to make contents of inside <div>
an <input>
after I click it, so that I can change value and send it to server. And inside editElementDescription()
I do the following:
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 + '"/>';
}
I remove that click
listener because otherwise contents of <input>
will get that innerHTML
if I click it one more time. So the idea is to assign that <input>
element a change
listener, which will replace <input>
by it's value and bring the parent <div>
it's original listener back.
I want to remove an event listener from an element and later assign it back. Is there a way to get it and store in a variable smth like var storedListener = Element.getEventListener('click')
, so that later I can do something like Element.addEventListener('click', storedListener)
?
UPDATE
Listener is assigned inside template, I use Angular 2. It's
<div *ngFor="let entry of data; let i=index">
<div class="element-description" (click)="editElementDescription(i)">{{entry.description}}</div>
</div>
What I want to do is to make contents of inside <div>
an <input>
after I click it, so that I can change value and send it to server. And inside editElementDescription()
I do the following:
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 + '"/>';
}
I remove that click
listener because otherwise contents of <input>
will get that innerHTML
if I click it one more time. So the idea is to assign that <input>
element a change
listener, which will replace <input>
by it's value and bring the parent <div>
it's original listener back.
-
Your call to
elementDescription.removeEventListener
is invalid since this method takes 2 arguments. You need to pass a direct reference to the listener function as second argument. – lleaff Commented Feb 8, 2017 at 14:50 -
Now I got your situation (after edit). But I suggest another approach: instead of controlling your events, you can use
data-
attribute to control your element state. I edited my answer. – luiscrjr Commented Feb 8, 2017 at 14:59 -
Ok, i guess i'll just introduce a local variable for the ponent, which will be
boolean
for clicked condition and depending on that html template will show either<a>
with value or<input>
, controlled by*ngIf
. Thx for answers! – Leonid Bor Commented Feb 8, 2017 at 15:11
3 Answers
Reset to default 3In order to remove a listener added with .addEventListener()
, you must keep track of the listener function reference and remove it later with .removeEventListener()
.
Something like that:
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);
});
Working demo: https://jsfiddle/mrlew/k5m1nog3/
Other approach (added after question update)
Considering your actual problem, I suggest another approach: instead of handle events, you can set a data-
attribute in the element indicating it's open. Then you just modify your inner HTML if the attribute is not present.
Something like this:
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 + '"/>';
}
}
Working demo: https://jsfiddle/mrlew/e0yrL08v/
You are getting it a bit wrong... there is no list of event listeners accessible from JavaScript... the only thing you can do is to remove/add an event if you know the origin.
There are 2 functions to manipulate event listeners:
- addEventListener(event_type,function);
- removeEventListener(event_type,function);
One object can have multiple events of same type... the only way to distinguish them is by giving an exact function being called.
Please note that if it's jQuery
, it is possible, as it has own event stack... example below:
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);
}
}
No, this isn't possible since .getEventListener
is only available for debugging purposes.
There is unfortunately no way in standard JavaScript to programmatically get back the EventListeners
attached to an object, and any library that tries to acplish this will rely on unstable non-standard interfaces that may be discontinued any day.
So if your goal was to manipulate the listeners added by a library you have no control over, you're out of luck.
On the other hand if you control the environment then you can store a reference to the attached callback if you want to attach the same listener to multiple objects, or remove it afterwards with .removeEventListener
.
You could actually monkey-patch EventTarget.prototype.addEventListener
to support this before anything else runs on your page, that wouldn't be a very clean solution to whatever problem you are having but if you think you really need to, here is a quick imperfect implementation of it (doesn't support useCapture
argument):
// 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);
本文标签: javascriptGet element event listener and store itStack Overflow
版权声明:本文标题:javascript - Get element event listener and store it - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742049488a2417989.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论