getElementById + 变量控制另一个 getElementById + 变量

getElementById + variable controlling another getElementById + variable

我有不同的 div,每个都有一个调用相同功能的按钮。

<div id="div1">. . .</div>
<button id="btn1" > INIT </button>
<div  id="div2">. . .</div>
<button id="btn2"> INIT </button>

棘手的部分是每个按钮应该只执行他自己的 div 的功能(#btn1#div1#btn2#div2,等等) 而不是其他人。我编写的代码对每个 div 执行相同的功能,而无需我单击按钮。我想答案很简单,但我不知道我做错了什么。

var b = 1;

for (var b = 1; b < 5 ; b++) {
    document.getElementById("btn" + b).onclick = 
    document.getElementById("div" + b).innerHTML = "HELLO WORLD";
}

fiddle : https://jsfiddle.net/balleronde/tr8wntmL/

如何只在单击 #btn1 时执行到 #div1 的功能,而不是一次全部执行? 谢谢

我假设你想要这样的东西:

使用参数创建函数处理程序

function myAwesomeHandler(param){
   document.getElementById("div" + param).innerHTML = "HELLO WORLD";
};

绑定此处理程序,这样您的处理程序将以计数器值作为参数被调用。查看有关 bind

的文档
for (var b = 1; b < 5 ; b++) {
    document.getElementById("btn" + b).onclick = myAwesomeHandler.bind(this, b);
}

尽管有更优雅的方式来使用不同的 html,但我假设您已经预定义了 html 结构并且只是演示了 "only js" 方法。

试试这个,

<div id="div1">. . .</div>
<button id="btn1" onclick="changeText('div1')"> INIT </button>
<div  id="div2">. . .</div>
<button id="btn2" onclick="changeText('div2')"> INIT </button>

并创建一个函数,

function changeText(divId){
        document.getElementById(divId).innerHTML = 'some text';
    }

这是您的代码:

document.getElementById("btn" + b).onclick = 
document.getElementById("div" + b).innerHTML = "HELLO WORLD"

据 JavaScript 所知,它看起来像这样:

x = y = "HELLO WORLD"

执行此操作时会发生以下情况:

x =
y = "hello world"

console.log("x is:", x)
console.log("y is:", y)

因此您的代码最终设置了 innerHTML 属性 of #div(b) and the onclick 属性 #btn(b)!哎呀,这不是你想要的。

您真正想要的是在您单击 #btn(b) 时设置 #div(b)innerHTML

为此,您需要将 函数 回调 分配给 #btn(b)onclick 属性:

function setTheText(b) {
  document.getElementById('div' + b).innerHTML = 'HELLO WORLD'
}

for (var b = 1; b < 5; b++) {
  document.getElementById('btn' + b).onclick = function() {
    setTheText(b)
  }
}
<div id='div1'>Div 1</div>
<div id='div2'>Div 2</div>
<div id='div3'>Div 3</div>
<div id='div4'>Div 4</div>
<button id='btn1'>Button 1</button>
<button id='btn2'>Button 2</button>
<button id='btn3'>Button 3</button>
<button id='btn4'>Button 4</button>

嗯..当我们点击按钮时出现错误:"Uncaught TypeError: Cannot set property innerHTML of null"。哎呀!

让我们调查一下。下面是当我们将 setTheText 函数的代码替换为记录 b:

的代码时会发生什么

function setTheText(b) {
  console.log(b)
}

for (var b = 1; b < 5; b++) {
  document.getElementById('btn' + b).onclick = function() {
    setTheText(b)
  }
}
<button id='btn1'>Button 1</button>
<button id='btn2'>Button 2</button>
<button id='btn3'>Button 3</button>
<button id='btn4'>Button 4</button>

它总是输出5!这没有多大意义。

基本上问题是 b 在 JavaScript 调用您的 onclick 函数之前被 for 循环更改为 5

所以我们真正需要做的是使用一个函数来创建回调函数,这样回调函数就可以记住它是什么索引(b)创建于:

function makeSetTheText(b) {
  function setTheText() {
    document.getElementById('div' + b).innerHTML = 'HELLO WORLD'
  }
  return setTheText
}

for (var b = 1; b < 5; b++) {
  document.getElementById('btn' + b).onclick = makeSetTheText(b)
}
<div id='div1'>Div 1</div>
<div id='div2'>Div 2</div>
<div id='div3'>Div 3</div>
<div id='div4'>Div 4</div>
<button id='btn1'>Button 1</button>
<button id='btn2'>Button 2</button>
<button id='btn3'>Button 3</button>
<button id='btn4'>Button 4</button>

这仍然有点令人困惑,别担心,关于闭包和函数如何在 Whosebug 上生成函数有很多非常好的解释 here

如果您已经做到了这一点,希望:

  1. 您将对调试有所了解。
  2. 您将找到解决问题的方法。
  3. 您将学会一些花哨的 JavaScript 技巧。
  4. 您会对我在输入此答案时不得不处理的大量延迟以及我所做的所有研究和测试表示同情。

希望对您有所帮助!