Добавить прослушиватели событий через массив и цикл FOR - PullRequest
4 голосов
/ 28 декабря 2011

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

-HTML-сегмент-

<input type="button" id="googleSearchButton" />
<input type="button" id="youtubeSearchButton" />
<input type="button" id="wikiSearchButton" />
<input type="button" id="facebookSearchButton" />
<input type="button" id="twitterSearchButton" />
<input type="button" id="tumblrSearchButton" />
<input type="button" id="dropboxSearchButton" />

Сегмент JavaScript

var contIDArray = ["google", "youtube", "wiki", "facebook", "twitter", "tumblr", "dropbox"];

window.load = initAll();
function initAll(){
    applyProperties();
}

function applyProperties(){
        for (var i = 0; i < contIDArray.length; i++){
            addEventListeners(contIDArray[i] + "SearchButton");
        }
}

function addEventListeners(id){
    document.getElementById(id).addEventListener("click", testAlert(id), false);
}

function testAlert(id){
    alert(id + " clicked")
}

Теория

Как, я надеюсь, вы можете видеть, цикл FOR будет зацикливаться до тех пор, пока у него не закончатся значения в массиве контейнера. Каждый раз он будет выводить место в массиве с последующим «SearchButton». Например, при первом зацикливании он выдаст «googleSearchButton», второй раз - «youtubeSearchButton» и так далее.

Теперь я знаю, что цикл FOR работает для применения свойств, потому что я использую его для применения значений Button и текста заполнителя текстового поля в других сегментах моего проекта.

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

Проблема

Теперь, теоретически, я думал, что это будет работать. Но кажется, что цикл FOR запускает функцию «addEventListeners», которая, в свою очередь, добавляет прослушиватель событий для запуска «testAlert» при нажатии. Но он просто запускает функцию «testAlert», как только добавляет обработчик событий, и не срабатывает при нажатии.

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

Помощь будет высоко ценится. :)

Ответы [ 4 ]

6 голосов
/ 28 декабря 2011

Вы здесь близко, но есть несколько вещей не так.

Во-первых, вы не можете просто сделать id.addEventListener. Вам нужно сделать document.getElementById(id).addEventListener. id это просто строка, вам нужен элемент DOME.

Во-вторых, когда вы делаете testAlert(id), вы запускаете функцию, затем присваиваете ее возвращаемое значение (undefined) в качестве прослушивателя событий. Вам нужно передать функцию. Вот так:

id.addEventListener("click", function(){
  testAlert(this.id); // this is the DOMElement you clicked on
}, false);

Хотя я предлагаю добавить класс ко всем вашим кнопкам, а затем добавить подобное событие.

<input type="button" id="googleSearchButton" class="searchButton" />
<input type="button" id="youtubeSearchButton" class="searchButton" />
<input type="button" id="wikiSearchButton" class="searchButton" />
<input type="button" id="facebookSearchButton" class="searchButton" />
<input type="button" id="twitterSearchButton" class="searchButton" />
<input type="button" id="tumblrSearchButton" class="searchButton" />
<input type="button" id="dropboxSearchButton" class="searchButton" />

А потом:

var buttons = document.getElementsByClassName('searchButton');
for(b in buttons){
   if(buttons.hasOwnProperty(b)){
     buttons[b].addEventListener("click", function(){
        testAlert(this.id); // this is the DOMElement you clicked on
     }, false);
   }
}

ПРИМЕЧАНИЕ. addEventListener и getElementsByClassName могут быть доступны не во всех браузерах (я имею в виду, что они могут не работать в IE). Вот почему многие веб-сайты используют библиотеку JavaScript, например jQuery . JQuery обрабатывает все кросс-браузерные вещи для вас. Если вы хотите использовать jQuery, вы можете сделать это:

$('.searchButton').click(function(){
  testAlert(this.id);
});

ПРИМЕЧАНИЕ 2. В JavaScript функции являются переменными и могут передаваться как параметры.

document.getElementById(id).addEventListener('click', testAlert, false);

Обратите внимание, что после testAlert нет (), мы передаем саму функцию, когда вы делаете testAlert(), вы передаете ее возвращаемое значение. Если вы сделаете это таким образом, testAlert нужно будет немного изменить:

function testAlert(){
    alert(this.id + " clicked")
}
2 голосов
/ 28 декабря 2011

Изменение:


function addEventListeners(id){
    id.addEventListener("click", testAlert(id), false);
}

для:


function addEventListeners(id){
    document.getElementById(id).addEventListener("click", testAlert(id), false);
}

В противном случае вы применяете addEventListener к строке. В любом случае замените addEventListener назначением на событие, например onClick.

1 голос
/ 28 декабря 2011

id выглядит как строка для меня.Поэтому вместо этого сделайте что-то вроде этого:

function addEventListeners(id){
  var obj = document.getElementById(id);
  obj.addEventListener("click", testAlert(id), false);
}

Кроме того, вот рабочий код:

http://jsfiddle.net/ZRZY9/2/

obj.addEventListener("click", function() { testAlert(id); }, true);

Как Ракета упоминает выше "вывызов его и установка для события возвращаемого значения undefined ".

Плохая новость заключается в том, что addEventListener () в настоящее время не поддерживается в Internet Explorer 7.

0 голосов
/ 28 декабря 2011

Я пробежал по твоему коду. Первоначальная проблема, с которой я столкнулся, заключалась в том, что вы пытались найти элементы в документе до их создания. window.onLoad срабатывает до завершения страницы. Я проверил это, используя атрибут onload тега body, и он работает таким образом.

Итак, это комбинация вышеупомянутой проблемы с попыткой найти элемент с помощью строки "id" и запуска функции до полной загрузки страницы.

В любом случае, рад, что у вас все получилось!

Это JavaScript, который у меня был в конце:

    <script>
    var contIDArray = ["google", "youtube", "wiki", "facebook", "twitter", "tumblr", "dropbox"];

function initAll(){
    applyProperties();
}

function applyProperties(){
        for (var i = 0; i < contIDArray.length; i++){
    var newString = contIDArray[i] + "SearchButton"
            addEventListeners(newString);
        }
}

function addEventListeners(id){
    document.getElementById(id).addEventListener("click", testAlert, false);
}

function testAlert(){
    alert(this.id + " clicked")
}
</script>
...