cloneNode and iterating event listeners

C

Csaba Gabor

One of the things that I never understood was the motivation for not
being able to iterate over the event listeners added via
..addEventListener It's particularly vexing because if you do
element.cloneNode(bDeep), you frequently get a stunted clone, often
with several key features missing, and one of these is associated event
handlers. Of course, it could be the case that the event handlers have
a closure including a reference to the original node, but still...

So I rewrote addEventListener, and removeEventListener so that
cloneNode could be accomodated. The below is a framework, and needs
some work, (including the transfer of attributes).

Csaba Gabor from Vienna

How it works. When you enter a character, you get a message box.
This is what lets you verify that the cloning of event handlers
worked. Before cloning, make a selection to see that the selection
is transferred, too.

<form action="" method=get>
<textarea id=foo name=foo style="color:red">This is some
starter text in a textarea</textarea>
<button type=button onclick="replaceWithClone(elem('foo'))"
accesskey=c><u>C</u>lone</button>
</form>

<script type='text/javascript'>
function elem(id) { return document.getElementById(id); }
fixCloneNode(elem('foo'));
elem('foo').addEventListener("input",
function() { alert("New text: " + this.value); }, false);

function fixCloneNode(elem) {
var oldAEL = elem.addEventListener;
var aListeners = [];
elem.addEventListener =
function (oldAEL, aListeners) {
return function (evt, func, bCapture) {
oldAEL.call (this, evt, func, bCapture)
aListeners.push( [evt, func, bCapture] ); } }
(oldAEL, aListeners);

var oldREL = elem.addEventListener;
elem.removeEventListener =
function (oldREL, aListeners) {
return function (evt, func, bCapture) {
for (var i=aListeners.length;--i;)
if (aListeners[0]==evt && aListeners[1]==func &&
aListeners[2]==bCapture)
aListeners.splice(i,1);
} } (oldREL, aListeners);

var oldClone = elem.cloneNode;
elem.cloneNode =
function (oldAEL, aListeners, oldClone) {
return function (bDeep) {
// does not reproduce the event listeners
var elem = oldClone.call (this, bDeep);
elem.addEventListener = this.addEventListener;
elem.removeEventListener = this.removeEventListener;
elem.cloneNode = this.cloneNode;
if (elem.nodeName=="TEXTAREA") elem.value = this.value;
for (var i=0;i<aListeners.length;++i) {
var aList=aListeners;
this.removeEventListener(aList[0], aList[1], aList[2]);
oldAEL.call (elem, aList[0], aList[1], aList[2]); }
return elem; } } (oldAEL, aListeners, oldClone);
}

function replaceWithClone(ta) {
var newTa = ta.cloneNode(true);
var start = ta.selectionStart, end=ta.selectionEnd;
ta.parentNode.replaceChild(newTa, ta);
// Doesn't work properly with reverse selections
newTa.setSelectionRange (start, end);
}
</script>
 
T

Thomas 'PointedEars' Lahn

Csaba said:
One of the things that I never understood was the motivation for not
being able to iterate over the event listeners added via
.addEventListener It's particularly vexing because if you do
element.cloneNode(bDeep), you frequently get a stunted clone, often
with several key features missing, and one of these is associated event
handlers. Of course, it could be the case that the event handlers have
a closure including a reference to the original node, but still...

So I rewrote addEventListener, and removeEventListener so that
cloneNode could be accomodated. The below is a framework, and needs
some work, (including the transfer of attributes).
[...]
How it works. [...]

For appropriate values of "works". It has been pointed out many times
that it is error-prone to assume that you can add or modify properties
of host objects arbitrarily. You do it anyway.


PointedEars
 
C

Csaba Gabor

Another PointedEars INC post.
Csaba said:
One of the things that I never understood was the motivation for not
being able to iterate over the event listeners added via
.addEventListener It's particularly vexing because if you do
element.cloneNode(bDeep), you frequently get a stunted clone, often
with several key features missing, and one of these is associated event
handlers. Of course, it could be the case that the event handlers have
a closure including a reference to the original node, but still...

So I rewrote addEventListener, and removeEventListener so that
cloneNode could be accomodated. The below is a framework, and needs
some work, (including the transfer of attributes).
[...]
How it works. [...]

For appropriate values of "works".
Whatever

It has been pointed out many times

And you don't even back it up with a single reference? For shame.
that it is error-prone to assume

Assuming things is error prone in general.
that you can add or modify properties of host objects arbitrarily.

And this affects me how? Rather than making unsubstantiated and/or
irrelevant claims, it would be preferable to have either a concrete
counterexample or offer a method to improve upon, or at least
complement the subject matter of the post.
You do it anyway.

You do neither.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top