我想为这样的按钮分配 onclick 功能,但它不起作用,为什么?

I want to assign onclick function to buttons like this, but it not work, why?

我想为这样的按钮分配 onclick 功能

window.onload = function() {
  var tablinks = document.getElementsByClassName("tablinks");
  for (i = 0; i < tablinks.length; i++) {
    console.log(tablinks[i].innerText);
    tablinks[i].onclick = openCity(event,tablinks[i].innerText);
  }
}



function openCity(evt,cityName) {
    var i, tabcontent, tablinks;
    console.log(cityName);
    // Get all elements with class="tabcontent" and hide them
    tabcontent = document.getElementsByClassName("tabcontent");
    for (i = 0; i < tabcontent.length; i++) {
        tabcontent[i].style.display = "none";
    }

    // Get all elements with class="tablinks" and remove the class "active"
    tablinks = document.getElementsByClassName("tablinks");
    for (i = 0; i < tablinks.length; i++) {
        tablinks[i].className = tablinks[i].className.replace(" active", "");
    }

    // Show the current tab, and add an "active" class to the button that opened the tab
    document.getElementById(cityName).style.display = "block";
    evt.currentTarget.className += " active"}; 

我看到当 window 加载时它发送日志到控制台:

London panel.js:4:11 London panel.js:14:9 Paris panel.js:4:11 Paris panel.js:14:9 Tokyo panel.js:4:11 Tokyo panel.js:14:9

但是当我点击按钮时,onclick 并没有触发。为什么?

两个问题,首先用let声明变量(i)创建块作用域 为变量并在匿名函数中调用函数。

演示:

window.onload = function() {
  var tablinks = document.getElementsByClassName("tablinks");
  for (let i = 0; i < tablinks.length; i++) {
    tablinks[i].onclick = function(){openCity(event,tablinks[i].innerText)};
  }
}
function openCity(e, text){
  console.log(text);
}
<ul>
  <li class="tablinks">tab1</li>
  <li class="tablinks">tab2</li>
  <li class="tablinks">tab3</li>
</ul>

您正在通过以下方式调用函数:tablinks[i].onclick = openCity(event,tablinks[i].innerText);

相反,您可以将函数作为变量传递,并从事件的 currentTarget 获取城市名称。

示例:

window.onload = function() {
  var tablinks = document.getElementsByClassName("tablinks");
  for (i = 0; i < tablinks.length; i++) {
    console.log(tablinks[i].innerText);
    tablinks[i].onclick = openCity;
  }
};

  function openCity(evt) {
    const cityName = evt.currentTarget.innerText;
    var i, tabcontent, tablinks;
    console.log(cityName);
    // Get all elements with class="tabcontent" and hide them
    tabcontent = document.getElementsByClassName("tabcontent");
    for (i = 0; i < tabcontent.length; i++) {
      tabcontent[i].style.display = "none";
    }

    // Get all elements with class="tablinks" and remove the class "active"
    tablinks = document.getElementsByClassName("tablinks");
    for (i = 0; i < tablinks.length; i++) {
      tablinks[i].className = tablinks[i].className.replace(" active", "");
    }

    // Show the current tab, and add an "active" class to the button that opened the tab
    document.getElementById(cityName).style.display = "block";
    evt.currentTarget.className += " active"
  };
  
<button class="tablinks">TEST</button>
<div class="tablinks">TAB CONTENT</div>
<div id="TEST">TEST CITY</div>

您已经在调用该函数并将返回值设置为 onclick 属性 的 属性 值,因为它没有返回任何内容(应该是 undefined)将分配给 onclick 处理程序。

因此,改为使用匿名函数包装函数,将其引用用作 onclick 处理程序。除了将 i 初始化为 let 以将值保留在块上下文中。

var tablinks = document.getElementsByClassName("tablinks");
    for (let i = 0; i < tablinks.length; i++) {
        console.log(tablinks[i].innerText);
        tablinks[i].onclick = function(event) { openCity(event,tablinks[i].innerText); }
    }

}