Help destroying many events on tr mouseenter and mouseleave

40 views
Skip to first unread message

kstubs

unread,
Jul 9, 2011, 6:10:05 PM7/9/11
to prototype-s...@googlegroups.com
I have something like this:

            tr.on('mouseenter',thiz.Mousing.bindAsEventListener(thiz));
            tr.on('mouseleave',thiz.Mousing.bindAsEventListener(thiz));

This table is built frequently (every few keystrokes by the user) so I need to setup the mouseenter and mouseleave event and tear them down just as quickly.

So, when I go to update the table container (whipe it out each time) I'd like to call one or two very convenient inokes on the tr's, something like:

this.table.select('tr').invoke( ... tear down those events here ... );

Is this the correct approach, or must I itterate through the result of each tr and tear them down this way?

Karl..

Tom Gregory

unread,
Jul 9, 2011, 11:47:12 PM7/9/11
to Prototype & script.aculo.us
My first question is, what is it you're trying to accomplish that you
need mouseenter/mouseleave handlers on the tr? What's your use case or
user story?


TAG

Douglas

unread,
Jul 10, 2011, 5:55:07 AM7/10/11
to prototype-s...@googlegroups.com
I've been in a similar situation, where I had a list of search results which were updated on every key press (but at most once every 100ms), and I wanted each row in the results table to have mouse-hover effects. My solution was to attach an event handler only to the table, and then wait until the on mouse move event to work out which element the mouse was over by using Event.element(event). This means that you don't need to attach or detach any event handlers, since there is always just the one on the table itself.

Douglas

kstubs

unread,
Jul 10, 2011, 1:07:32 PM7/10/11
to prototype-s...@googlegroups.com
Color the row pink on rollover (mostly).  There is also a click event on the row for navigating to a new page based on which row you are on.

Tom Gregory

unread,
Jul 10, 2011, 3:27:06 PM7/10/11
to Prototype & script.aculo.us
It sounds like you're trying to do it the hard way.

Next question is what browsers do you need to support w/ the rollover
effect? It can be done entirely via CSS on most everything post IE-6.
No javascript required. Just add this line:
tr:hover {background-color:#eed;}

The click event (which is neither a mouseenter/mouseleave, which is
what you asked about), can be handled by attaching a single handler to
the table, which you've described as sticking around.
Event.observe('someTable', 'click', function(event) {
var element = Event.element(event).up('tr');
console.log(element);
});

No setup/teardown required. Full sample code at end.


TAG

On Jul 10, 1:07 pm, kstubs <kst...@gmail.com> wrote:
> Color the row pink on rollover (mostly).  There is also a click event on the
> row for navigating to a new page based on which row you are on.

======= SAMPLE =========
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/prototype/1.7.0.0/
prototype.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css">
table{ margin: 30px auto 0 auto;}
td {border:1px solid blue;}
tr:hover {background-color:#eed;}
</style>
</head>
<body>
<table id="someTable"><tbody>
<tr id="tr1">
<td>Lorem</td><td>ipsum</td><td>dolor</td>
</tr>
<tr id="t2">
<td>sit</td><td>amet,</td><td>consectetur</td>
</tr>
<tr id="t3">
<td>adipisicing</td><td>elit</td><td>sed.</td>
</tr>
</tbody></table>
<script type="text/javascript" charset="utf-8">
//<![CDATA[
Event.observe('someTable', 'click', function(event) {
var element = Event.element(event).up('tr');
console.log(element);
});
//]]>
</script>
</body>
</html>

Eric

unread,
Jul 12, 2011, 11:30:53 AM7/12/11
to Prototype & script.aculo.us
Hello,

If you're using on() instead of observe(), you can move the up()
outside of the event handler (which makes it reusable in other cases,
and probably has some other advantages since the feature has been
added in Prototype 1.7 :o) )

Event.observe('someTable', 'click', function(event) {
var element = Event.element(event).up('tr');
console.log(element);
});

can be written as:

$('someTable').on('click', 'tr', function(event,element) {
console.log(element);
});

Since Prototype 1.6, you also have Event.findElement() which is a
convenient way to call both Event.Element() and Element.tr().

Also, I am kind of sure using //<![CDATA[ and //]]> around javascript
code has been deprecated a few years ago (but I may be wrong).

Eric

Tom Gregory

unread,
Jul 12, 2011, 11:06:19 PM7/12/11
to Prototype & script.aculo.us
Good call on the 1.7 feature, Eric. Most of my Prototype experience
has been with earlier versions, so thanks for the update. For the
interested reader, a good tutorial link/feature announcement:
http://www.prototypejs.org/2010/4/5/prototype-1-7-rc1-sizzle-layout-dimensions-api-event-delegation-and-more
The documentation page is here: http://api.prototypejs.org/dom/Event/on/
(Yes, it's for Event#on, but this is the same documentation for
Element#on)

The big point for the original questioner to take from the discussion
is that it's not necessary to tie the event handler to each lowest-
level element; it's often easier (both on the programmer and the
browser) to observe it at a parent level once, and let the code handle
the difference.

Re CDATA ... yes, if you're using HTML5 (and you should be), you don't
need it. If you're doing anything that will go through an XML parser,
including XHTML, then you should include it.
See e.g., http://stackoverflow.com/questions/66837/when-is-a-cdata-section-necessary-within-a-script-tag

I'm a bit embarrassed to admit it slipped into the sample code through
a TextMate macro. I'll have to go back and tweak the macro. (But
goodness, autocomplete is nice!)


TAG
Reply all
Reply to author
Forward
0 new messages