Добавление обработчика событий с помощью Mootools .addEvent () таинственным образом завершается неудачей в определенном месте - PullRequest
0 голосов
/ 28 сентября 2011

У меня довольно ошеломляющая проблема с некоторыми JS, над которыми я работаю для веб-приложения.К сожалению, я не могу опубликовать полный код для этого, так как это часть еще не выпущенного проекта.У этой проблемы есть и я, и некоторые коллеги, которых я спрашивал, в тупик - от того, что я могу сказать, это должно работать.

Теперь к актуальной проблеме: пользователь вводит некоторую информацию в некоторые поля формы и нажимает «подтвердить».изображение, после чего запрос AJAX отправляется обратно на сервер.Сервер выполняет некоторую обработку, затем отправляет обратно ответ со статусом и некоторыми прикрепленными данными.Сообщение о состоянии отображается в модальном диалоговом окне, которое использовал пользователь, и отображается значок со ссылкой.Вот обработчик «onComplete» для объекта Mootools Request.JSON с удаленной обработкой некоторых ошибок:

  onComplete: function(response) {
    if (response) {
      if (response.status == 0) {
        // this means the request was successful
        licenses = response.licenses;
        updateControls();
        licenseList();
        // here I add the status message...
        $("createform_result").innerHTML = "<img src=\'/media/com_supportarea/images/db_success.png\' /> License created. Download:<br /><br />";
        // ...and the download "link"
        if (response.tlsid) {
          $("createform_result").innerHTML += "<a href=\"#\" id=\"newtlslic-"+response.tlsid+"\"><img src=\'/media/com_supportarea/images/download_small.png\' /></a> <em>TLS</em>";
          // this line is here for debugging only, to make sure this
          // block of code is run (it is) and the element is found (it is)
          $("newtlslic-"+response.tlsid).style.border = "1px solid red";
          $("newtlslic-"+response.tlsid).addEvent("click", function(e) {
            // I've stripped out all other code, also for debugging
            e.stop();
          });
        }
      }
    }
  }

Появляется сообщение и значок со ссылкой, применяется стиль (красная граница) и ошибки нетсообщение появляется либо в Firefox, либо в Chrome.Однако нажатие на значок приводит к добавлению символа # в URL (e.stop ()) ничего не делает).Согласно плагину EventBug, никакое событие щелчка не прикреплено к ссылке.Кажется, что .addEvent () просто ничего не делает здесь.

Теперь, и вот они главный вопрос: почему это и как я могу это исправить?Помогите!

1 Ответ

1 голос
/ 28 сентября 2011

строк в JavaScript являются неизменными. когда вы делаете что-то вроде:

$("createform_result").innerHTML += "<a href=\"#\" id=\"newtlslic-"+response.tlsid+"\"><img src=\'/media/com_supportarea/images/download_small.png\' /></a> <em>TLS</em>";

вы ссылаетесь на innerHTML как строку. то, что это делает, это выбирает свойство в строку, объединяет его с другими передаваемыми строками и затем возвращает новую строку в конце, которая устанавливается как innerHTML.

при этом вы ЗАПИСЫВАЕТЕ содержимое элемента каждый раз, для каждой итерации.

события, прикрепленные к элементам, не выполняются обработчиком универсального идентификатора - они полагаются на элемент, находящийся в DOM, затем читается UID элемента (внутреннее свойство mootools присваивает всем переданным элементам) и добавляется обратный вызов события в хранилище элементов за этим UID.

Вы можете увидеть эту работу, выполнив console.log(element.retrieve("events"));

если переписать innerHTML, внутренний элемент воссоздается и получает НОВЫЙ UID, что означает, что обратный вызов теперь указывает на пустой указатель, поскольку UID является ключом в хранилище элементов.

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

лучший способ справиться с этим - это другое - использовать делегирование событий.

это может позволить вам добавить событие click к родительскому элементу вместо некоторого селектора. это будет работать для ЛЮБОГО элемента, добавленного любым способом в любое время, которое совпадает.

например.

// add this once, outside the loop 
$("createform_result").addEvent("click:relay(a.editLink)", function(event, element) {
    console.log(this === element); 
    console.log(this === event.target);
    console.log(this.get("data-id"));
}); 

// then as you loop the results, just inject the els or use innerHTML or whatever...
new Element("a.editLink", {
    html: '<img src=\'/media/com_supportarea/images/download_small.png\' /></a> <em>TLS</em>',
    "data-id": response.tlsid
}).inject($("createform_result"));

Делегирование событий теперь является частью ядра mootools в 1.4.0 или в предыдущих версиях mootools-more.

веселись!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...