将不同的事件侦听器添加到页面上的多个按钮

时间:2014-04-30 15:45:52

标签: javascript jquery html

一些背景:我一直在研究Dark Souls II统计计算器。我有一个带按钮的表,允许您向任何主要统计数据添加或减去一个值。然后,这将更新页面上的统计数据,最终将告诉您达到灵魂等级需要多少灵魂(经验值)。

无论如何,我想使用纯Javascript将addEventListeners添加到每个按钮来实现这个目标。问题是,我一直在添加几个不同的调用,我只是好奇,如果有一个更有效的方法来做到这一点。下面的代码示例将向您展示我的详细解决方案,为了简洁起见,我可以相当确定。如果你能用纯Javascript回答我的问题,它会被认为比jQuery更高,但如果你想出一个jQuery解决方案,我仍然会非常感激。我认为这个问题的优雅解决方案很有可能,但我不知所措。

以下是带有三个按钮的代码示例。

HTML片段(这显然在body标签内):

<tr id="rowVigor">
    <td>Vigor</td>
    <td id="baseVIG">0</td>
    <td class="increased" id="increasedVIG">0</td>
    <td id="currentVIG">0</td>
    <td><input type="button" value="-" class="buttonSubtract" id="minusVIG"/></td>
    <td><input type="button" value="+" class="buttonAdd" id="addVIG"/></td>
</tr>
<tr id="rowEndurance">
    <td>Endurance</td>
    <td id="baseEND">0</td>
    <td class="increased" id="increasedEND">0</td>
    <td id="currentEND">0</td>
    <td><input type="button" value="-" class="buttonSubtract" id="minusEND"/></td>
    <td><input type="button" value="+" class="buttonAdd" id="addEND"/></td>
</tr>
<tr id="rowVitality">
    <td>Vitality</td>
    <td id="baseVIT">0</td>
    <td class="increased" id="increasedVIT">0</td>
    <td id="currentVIT">0</td>
    <td><input type="button" value="-" class="buttonSubtract" id="minusVIT"/></td>
    <td><input type="button" value="+" class="buttonAdd" id="addVIT"/></td>
</tr>

Javascript片段:

window.onload = function() 
{
    //Global event listeners - Buttons
    //VIGOR
    document.getElementById("addVIG").addEventListener("click", function(){ addOne("increasedVIG"); }, false);
    document.getElementById("minusVIG").addEventListener("click", function(){ minusOne("increasedVIG"); }, false);

    //ENDURANCE
    document.getElementById("addEND").addEventListener("click", function() { addOne("increasedEND"); }, false);
    document.getElementById("minusEND").addEventListener("click", function() { minusOne("increasedEND"); }, false);

    //VITALITY
    document.getElementById("addVIT").addEventListener("click", function() { addOne("increasedVIT"); }, false);
    document.getElementById("minusVIT").addEventListener("click", function() { minusOne("increasedVIT"); }, false);

}

//The functions calls and objects within these two functions are for updating statistical values. 
function addOne(id)
{
        console.log(id);
    id = document.getElementById(id);
    id.innerText = parseInt(id.innerText) + 1;
    player.SoulLevel++;
    updateAll();
}

function minusOne(id)
{
        console.log(id);
    id = document.getElementById(id);
    if (parseInt(id.innerText) != 0)
    {
        id.innerText = parseInt(id.innerText) - 1;
        player.SoulLevel--;
        updateAll();
    }
}

现在,上面的代码正常工作,但问题是有九个统计数据(我只显示了三个)并且它变得非常冗长。这是做这样的事情的正确方法吗?我应该担心吗?

这是我的一个想法,但最终没有工作......(与上面相同的HTML)

Javascript片段:

//suffix has global scope
var suffix = ["VIG", "END", "VIT"];

window.onload = function()
{
    for (var i = 0; i < suffix.length; i++)
    {
        document.getElementById("add" + suffix[i]).addEventListener("click", function(){    addOne("increased" + suffix[i]);    }, false);
        document.getElementById("minus" + suffix[i]).addEventListener("click", function(){ minusOne("increased" + suffix[i]); }, false);
    }
}

当您点击加号或减号按钮时,console.log(id)会返回increasedundefined,因此我猜测您无法通过这种方式创建事件监听器。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

以下是您可能会觉得有用的一个选项:

请注意使用新的data-*属性:

<div id="statsHome">
    <tr id="rowVigor">
        <td>Vigor</td>
        <td id="baseVIG">0</td>
        <td class="increased" id="increasedVIG">0</td>
        <td id="currentVIG">0</td>
        <td><input type="button" value="-" class="buttonSubtract" data-type="increasedVIG"/></td>
        <td><input type="button" value="+" class="buttonAdd" data-type="increasedVIG"/></td>
    </tr>
</div>

在这种情况下,我将循环并添加到按钮而不是使用委托。不过,这真是一种折腾。

function addHandler(button, mode) {
  if (mode === "add") {
    button.addEventListener("click", function() { 
      var stat = this.getAttribute("data-type");
      addOne(stat);
    }, false);
  } else { 
    button.addEventListener("click", function() {
      var stat = this.getAttribute("data-type");
      minusOne(stat);
   }, false);
  }

}

var statsHome = docuemt.getElementById("statsHome");
var buttons = statsHome.getElementsByTagName("input");
for (var i = 0; i < buttons.length; i++) {
  var button = buttons[i];
  if (button.className === "buttonSubtract") {
    addHandler(button, "subtract");
  }
  if (button.className === "buttonAdd") {
    addHandler(button, "add");
  }
}

答案 1 :(得分:0)

除了不在当前事件处理程序中调用索引变量上的命名事件处理函数和作用域问题之外,您的代码没有任何问题