简体   繁体   English

单击时调用变量函数

[英]Calling a variables function on click

I am trying to trigger an items effect in an adventure game I am building and I can't seem to figure out how to do it. 我正在尝试在我正在制作的冒险游戏中触发物品效果,但我似乎不知道该怎么做。 Basically when clicked I would like whichever item it is to run their effect function. 基本上,当我单击时,我希望运行它的效果功能的任何项目。 I'm getting quite confused. 我很困惑。

    function showItems() {
      for (var i = 0; i < items.length; i++) {
        playerUi.innerHTML += '<div class="item-container"><a href="#" 
    class="item-name" onclick="items[i].effect">' + items[i].name + '</a><br 
    /><p class="desc-p">' + items[i].description + '<br />Value: ' + 
    items[i].price + '</p></div>';
      }
    }

    // Shows the inventory interface.
    $('#inv-btn').on('click', function() {
      playerUi.innerHTML = '<h3>Your Inventory:</h3>';
      showItems();
      playerUi.innerHTML += '<br /><br /><div class="gold-box">Gold: ' + 
    player.gold + '</div>';
    });

The below is the code I have for my items at the minute: 下面是我目前为物品准备的代码:

    // I  T  E  M  S
    function invItem(name, type, desc, price, eff) {
      this.name = name;
      this.type = type;
      this.description = desc;
      this.price = price;
      this.effect = eff;
    };

    var weakPotion = new invItem('Weak Potion', 'Consumable', 'A weak health 
    potion.', 10, healSelf(20));
    var brewersPotion = new invItem('Brewers Potion', 'Consumable', 'A 
    standard health potion.', 23, healSelf(45));

    function healSelf(amt) {
      if (player.currentHealth < player.maxHealth) {
        player.currentHealth += amt;
        if (player.currentHealth >= player.maxHealth) {
          player.currentHealth = player.maxHealth;
        }
      }
    }

To see what I currently have so far on this click here . 要查看我目前对此的了解, 请单击此处

Below is my player object. 以下是我的播放器对象。

    // Create our player object.
    var player = new Object();
    player.gold = 0;
    player.level = 1;
    player.strength = 5;
    player.intellect = 5;
    player.endurance = 5;
    player.agility = 5;
    player.currentExp = 0;
    player.reqExp = 100;
    player.skillPoints = 0;
    player.attPoints = 2;
    player.maxHealth = 0;
    player.currentHealth = 0;
    player.maxMana = 0;
    player.currentMana = 0;

Lets start at the beginning here. 让我们从这里开始。 This line 这条线

var weakPotion 
     = new invItem('Weak Potion', 'Consumable', 'A weak health potion.', 10, healSelf(20));

Already does not do what you think it does! 已经没有按照您的想法去做! It will immediately execute the function - which is not what you're trying to do. 它将立即执行该功能-这不是您要尝试执行的操作。 Instead you should be storing a reference to the function to execute . 相反,您应该存储对要执行的函数引用 Fix it by returning a new function to be called later 通过返回一个以后要调用的新函数来修复它

function healSelf(amt) {
  return function(){
    if (player.currentHealth < player.maxHealth) {
      player.currentHealth += amt;
      if (player.currentHealth >= player.maxHealth) {
        player.currentHealth = player.maxHealth;
      }
    }
  }
}

Next, when you pass a reference to a function, to later execute that function use parentheses: 接下来,当您传递对函数的引用时,要在以后执行该函数,请使用括号:

onclick="items[i].effect()"

But this still wont work - items[i] only exists in the loop - not when the page is running. 但这仍然行不通-items items[i]仅存在于循环中-不在页面运行时。 One way to solve this is to not attach an onclick directly (especially when using jQuery) and instead attach a click handler to those links using index() to find the right item 解决此问题的一种方法是不直接附加onclick (尤其是在使用jQuery时),而是使用index()将click处理程序附加到那些链接以找到正确的item

function showItems() {
  for (var i = 0; i < items.length; i++) {
    playerUi.innerHTML += '<div class="item-container"><a href="#" class="item-name">' + items[i].name + '</a><br /><p class="desc-p">' + items[i].description + '<br />Value: ' + items[i].price + '</p></div>';
  }
}

and elsewhere 和其他地方

$(document).on('click','.item-name',function(){
   var index = $(this).index();
   items[index].effect();
});

Items should have unique IDs so you can easily access them, remove from item list etc. So, ended up with something like that. 项目应具有唯一的ID,以便您可以轻松访问它们,将其从项目列表中删除等。因此,最终得到了类似的结果。

 let playerUi = $('#inv'); let player = { currentHealth: 100, maxHealth: 100 }; let items = []; function showItems() { for (var i = 0; i < items.length; i++) { let item = '<li data-itemid="' + items[i].id + '">' + items[i].name + '<br>Description: ' + items[i].description + '</li>'; playerUi.append(item); } } function makeid() { var text = ""; var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for (var i = 0; i < 5; i++) // Change 5 to higher number for more unique IDs text += possible.charAt(Math.floor(Math.random() * possible.length)); return text; } function invItem(name, type, desc, price, eff) { this.id = makeid(); this.name = name; this.type = type; this.description = desc; this.price = price; this.effect = eff; }; function healSelf(amt) { return function() { console.log("Before heal:" + player.currentHealth); player.currentHealth = Math.min(player.currentHealth+amt, player.maxHealth); console.log("After heal:" + player.currentHealth); } } items[0] = new invItem('Weak Potion', 'Consumable', 'A weak health potion.', 10, healSelf(20)); items[1] = new invItem('Brewers Potion', 'Consumable', 'A standard health potion.', 23, healSelf(45)); items[2] = new invItem('Strongest Potion', 'Consumable', 'This potion is too strong.', 100, healSelf(80)); showItems(); $('li').on('click', function(e) { let id = e.target.dataset.itemid; let item = $.grep(items, function(e) {return e.id == id;})[0]; console.log("Using: " + item.name); player.currentHealth -= 40; item.effect(); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <ul id="inv"> </ul> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM