views:

217

answers:

2

I have written a news scroller which uses the Prototype and Script.aculo.us libraries to scroll through the news feed at a set interval. There are buttons included in each news item that allow the user to manually scroll the news feed up or down manually. When the page is loaded the buttons are assigned event handlers for when they are clicked:

$$('img.up').each(function(img) {
    img.observe('click', function(e) {
        window.clearTimeout(timeout);
        timeout = scrollTicker(-block_size, 2);
    });
});
$$('img.down').each(function(img) {
    img.observe('click', function(e) {
        window.clearTimeout(timeout);
        timeout = scrollTicker(block_size, 2);
    });
});

This works fine. The problem I have is when new news items are appended dynamically to the end of the existing news items they do not have the event handlers attached to them.

From what I've read it seems a better way to handle this would to use event bubbling. That way I wouldn't need to attach event handlers to each individual button. Unfortunately I am unable to find how to do this properly with Prototype. How is event bubbling done with Prototype?

(One option I do not have available to me is to remove the buttons from each news item and use one set of buttons for all of them as I do not have enough room in the allotted space to do so.)

+1  A: 

Event bubbling allows you to observe an event on a container rather than individual elements within the container.

It looks like this in Prototype:

$('records').observe('click', function(event) {
  var clickedRow;
  clickedRow = event.findElement('tr');
  if (clickedRow) {
    this.down('th').update("You clicked record #" + clickedRow.readAttribute("data-recnum"));
  }
});

Notice the observer and findElement used in this sample.

see http://api.prototypejs.org/dom/event.html for the complete reference.

Todd Moses
A: 

When creating the new row use new Element() and then attach behaviors to it. Lastly, insert it into the DOM.

var row = new Element('div', { 'class': 'row').update('<span>row</span>');
row.observe('click', function(e) {
    window.clearTimeout(timeout);
    timeout = scrollTicker(block_size, 2);
});
$('newsFeedGrid').insert(row);
Christian