Передача параметров в событии Javascript onClick

Я пытаюсь передать параметр в событии onclick. Ниже приведен пример кода:

<div id="div"></div>

<script language="javascript" type="text/javascript">
   var div = document.getElementById('div');

   for (var i = 0; i < 10; i++) {
       var link = document.createElement('a');
       link.setAttribute('href', '#');
       link.innerHTML = i + '';
       link.onclick=  function() { onClickLink(i+'');};
       div.appendChild(link);
       div.appendChild(document.createElement('BR'));
       }

   function onClickLink(text) {
       alert('Link ' + text + ' clicked');
       return false;
       }
    </script>

Однако всякий раз, когда я нажимаю на любую из ссылок, предупреждение всегда показывает "Ссылка 10 нажата"!

Может ли кто-нибудь сказать мне, что я делаю неправильно?

Спасибо

+44
источник поделиться
8 ответов

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

for (var i = 0; i < 10; i++) {
   var link = document.createElement('a');
   link.setAttribute('href', '#');
   link.innerHTML = i + '';
   link.onclick = (function() {
      var currentI = i;
      return function() { 
          onClickLink(currentI + '');
      }
   })();
   div.appendChild(link);
   div.appendChild(document.createElement('BR'));
}

Или, если вы хотите более сжатый синтаксис, я предлагаю вам использовать решение Nick Craver.

+49
источник

Это происходит потому, что все они ссылаются на одну и ту же переменную i, которая меняет каждый цикл и остается как 10 в конце цикла. Вы можете решить эту проблему, используя следующее закрытие:

link.onclick = function(j) { return function() { onClickLink(j+''); }; }(i);

Вы можете попробовать здесь

Или сделайте this ссылкой, которую вы нажали в этом обработчике, например:

link.onclick = function(j) { return function() { onClickLink.call(this, j); }; }(i);

Вы можете попробовать эту версию здесь

+33
источник
другие ответы

Связанные вопросы


Похожие вопросы

link.onclick = function() { onClickLink(i+''); };

Является закрытием и сохраняет ссылку на переменную i, а не значение, которое i выполняется при создании функции. Одним из решений было бы обернуть содержимое цикла for в функции:

for (var i = 0; i < 10; i++) (function(i) {
    var link = document.createElement('a');
    link.setAttribute('href', '#');
    link.innerHTML = i + '';
    link.onclick=  function() { onClickLink(i+'');};
    div.appendChild(link);
    div.appendChild(document.createElement('BR'));
}(i));
+3
источник

Попробуйте следующее:

<div id="div"></div>

<script language="javascript" type="text/javascript">
   var div = document.getElementById('div');

   for (var i = 0; i < 10; i++) {
       var f = function() {
           var link = document.createElement('a');
           var j = i; // this j is scoped to our anonymous function
                      // while i is scoped outside the anonymous function,
                      //  getting incremented by the for loop
           link.setAttribute('href', '#');
           link.innerHTML = j + '';
           link.onclick=  function() { onClickLink(j+'');};
           div.appendChild(link);
           div.appendChild(document.createElement('br')); // lower case BR, please!
       }(); // call the function immediately
   }

   function onClickLink(text) {
       alert('Link ' + text + ' clicked');
       return false;
   }
</script>
+1
источник

или вы можете использовать эту строку:

 link.setAttribute('onClick', 'onClickLink('+i+')');

вместо этого:

link.onclick=  function() { onClickLink(i+'');};
+1
источник

Еще один простой способ (может быть, не лучшая практика), но работает как шарм. Создайте HTML-тег своего элемента (hyperLink или Button) динамически с помощью javascript и также можете передавать несколько параметров.

// variable to hold the HTML Tags 
var ProductButtonsHTML  ="";

//Run your loop
for (var i = 0; i < ProductsJson.length; i++){
// Build the <input> Tag with the required parameters for Onclick call. Use double quotes.

ProductButtonsHTML += " <input type='button' value='" + ProductsJson[i].DisplayName + "'  
onclick = \"BuildCartById('" + ProductsJson[i].SKU+ "'," + ProductsJson[i].Id + ")\"></input> ";

}

// Add the Tags to the Div innerHTML.
document.getElementById("divProductsMenuStrip").innerHTML = ProductButtonsHTML;
+1
источник

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

<div id="div"></div>

<script>
  function getLink(id)
  {
    var link = document.createElement('a');
    link.setAttribute('href', '#');
    link.innerHTML = id;
    link.onclick = function()
    {
      onClickLink(id);
    };
    link.style.display = 'block';
    return link;
  }
  var div = document.getElementById('div');
  for (var i = 0; i < 10; i += 1)
  {
    div.appendChild(getLink(i.toString()));
  }
</script>

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

+1
источник

onclick vs addEventListener. Возможно, предпочтительнее (где IE > 9).

// Using closures
function onClickLink(e, index) {   
    alert(index);
    return false;
}

var div = document.getElementById('div');

for (var i = 0; i < 10; i++) {
    var link = document.createElement('a');

    link.setAttribute('href', '#');
    link.innerHTML = i + '';
    link.addEventListener('click', (function(e) {
        var index = i;
        return function(e) {
            return onClickLink(e, index);
        }
    })(), false);
    div.appendChild(link);
    div.appendChild(document.createElement('BR'));
}

Как просто использовать простой атрибут data- *, а не такой классный, как закрытие, но..

function onClickLink(e) {       
    alert(e.target.getAttribute('data-index'));
    return false;
}

var div = document.getElementById('div');

for (var i = 0; i < 10; i++) {
    var link = document.createElement('a');

    link.setAttribute('href', '#');
    link.setAttribute('data-index', i);
    link.innerHTML = i + ' Hello';        
    link.addEventListener('click', onClickLink, false);
    div.appendChild(link);
    div.appendChild(document.createElement('BR'));
}
+1
источник

Посмотрите другие вопросы по меткам или Задайте вопрос