Наблюдение за событиями на динамически вставленных объектах в DOM - PullRequest
1 голос
/ 17 июля 2009

При загрузке я добавляю требуемое поведение ко всем текстовым областям на странице.

Event.observe(window, 'load', function() {
  $$('textarea').each(function(x) {
    x.observe('keydown', dosomethinghere)
  });
});

Это работает, потому что текстовые области уже находятся в DOM, но как мне относиться к текстовым областям, которые динамически добавляются после загрузки страницы (например, если у меня есть кнопка с надписью «Добавить еще»). Я бы хотел, чтобы эти недавно созданные текстовые зоны имели такое же поведение. Спасибо.

Ответы [ 5 ]

1 голос
/ 22 июля 2009

Я делаю это, просто наблюдая за новой текстовой областью, когда я добавляю ее, например:

function doSomethingWithTextAreas(){
   //do something.
}

document.observe("dom:loaded", function() {
  $$('textarea').each(function(s){
   s.observe('keydown', doSomethingWithTextareas);
  });

 $('add_more').observe('click', function(){
   textarea = new Element('textarea');
   textarea.observe('keydown', doSomethingWithTextareas); //Observes the new textarea.
   Element.insert($('textarea_container'), {bottom:textarea});
 });

});
0 голосов
/ 05 августа 2009

Хороший способ сделать это - использовать функцию javascript, которая добавляет текстовые области для запуска события, которое любая другая функция может наблюдать и действовать. Итак:

function add_textarea() {
    // Code creates a new <textarea> and adds it to the page
    var textarea = new Element("textarea");
    $("some-form").insert(textarea);
    textarea.fire("textarea:add")
}

document.observe("textarea:add", function(event) {
    event.target.observe('keydown', dosomethinghere);
});

Это позволяет вашим двум функциям - одна, которая добавляет новую текстовую область, и одна, которая прикрепляет наблюдателей, - слабо связаны и ничего не знают друг о друге. Один просто должен запустить пользовательское событие, которое может наблюдать другой.

0 голосов
/ 17 июля 2009

$. Live () будет работать, как упоминает STAii, но обсуждает реализацию аналогичной функции в прототипе . Это, вероятно, принесет больше пользы, поэтому вам не нужно добавлять другую библиотеку.

0 голосов
/ 21 июля 2009

Ну, ответ немного хитрый. Единственный способ сделать это - сохранить кеш слушателей событий для ваших текстовых полей. При добавлении новой текстовой области на вашу страницу вам нужно будет вызвать Event.stopObserving для всех ваших кэшированных событий. Затем вы должны снова вызвать свой код $$ ('textarea'). Each (...) для привязки ко всем элементам.

К счастью , кто-то уже сделал это для вас в очень удобном облегченном прототипе расширения под названием lowpro: http://www.danwebb.net/2006/9/3/low-pro-unobtrusive-scripting-for-prototype

Вы можете делать то, что хотите, просто:

Event.addBehavior({
  'textarea:keydown': function(e) {
    dosomethinghere(); // e.g. this.hide();
  }
});

Затем, когда вы динамически добавляете новую текстовую область, вы просто вызываете Event.addBehavior.reload ();

Я должен указать, что «e» - это объект Event, а «this» - это элемент в контексте определения функции (e) {}.

0 голосов
/ 17 июля 2009

Рассмотрите возможность использования jQuery Live .

...