javascript - addEventListener 指向作为对象属性的函数,加载时不触发函数
问题描述
我正在为朋友制作一个基于文本的、浏览器内的简单 RPG。我想从对象生成菜单元素,并向它们添加事件监听器,以便在单击时激活存储在对象内的相关功能。我有密码——
var inventory = [
{
name: "first",
},
{
name: "second",
use: function(){
alert ("placeholder function");
}
},
{
name: "third",
},
];
function displayInventory(){
for(i = 0; i < inventory.length; i++){
document.getElementById("div_name").innerHTML += '<div class="big_div" id="additional_div_' + inventory[i].name + '"> ' + inventory[i].name + ' div';
if(inventory[i].hasOwnProperty("use")){
document.getElementById("additional_div_" + inventory[i].name).innerHTML += '<div class="item_use" id="additional_div_use_' + inventory[i].name + '">click here to use item'
document.getElementById("additional_div_use_" + inventory[i].name).addEventListener("click", inventory[i].use()); // fires upon loading
document.getElementById("additional_div_" + inventory[i].name).innerHTML += '</div>'
}
document.getElementById("div_name").innerHTML += '</div>'
}
}
document.onload = displayInventory();
<style>
.big_div{
background-color:#ccc;
margin:10px;
}
.item_use{
cursor:pointer;
}
<html>
<head>
<title>GAME</title>
<meta charset="utf-8">
</head>
<body>
<div id="div_name"></div>
</body>
</html>
这将在加载时触发旨在使用该项目的功能,而不是在单击时。我知道发生这种情况是因为浏览器在代码中到达函数调用时会读取函数调用,但我无法想出一个也保留生成器样式加载的解决方法。
我需要生成器工作,因为会有大量的项目、地图、敌人等,都以相同的方式加载到菜单中。
我更喜欢在整个过程中使用香草 JS。
解决方案
您可以为此使用纯 js(forEach 等)。您不需要为此求助于innerHTML。使用createElement
代替(如果你想最小化 dom 修改考虑使用new DocumentFragment
orcreateDocumentFragment
代替,这里我没有使用它):
https://jsfiddle.net/ibowankenobi/9uo8wuro/
var inventory = [
{
name: "first",
},
{
name: "second",
use: function(){
alert ("placeholder function");
}
},
{
name: "third",
},
];
var container = document.getElementById("div_name");
inventory.forEach(function(d,i){
var div = document.createElement("div");
div.textContent = d.name && d.name || "placeholder";
div.className = "item_use";
div.id = "additional_div_use"+i;
d.use && div.addEventListener("click",d.use,false);
this.appendChild(div);
},container);
这是基于您想要的更新版本。如果对象有 children 属性,那么它将使用该数组添加元素([ elementType , text , class ]),否则它将使用该name
属性添加文本内容:
https://jsfiddle.net/ibowankenobi/9uo8wuro/2/
var inventory = [
{
name: "first",
},
{
name: "second",
use: function(){
alert ("placeholder function");
},
children:[["div","click here to use item","item_use"]]
},
{
name: "third",
},
];
var container = document.getElementById("div_name");
inventory.forEach(function(d,i){
var div = document.createElement("div");
!d.children && (div.textContent = d.name && d.name || "placeholder");
div.id = "additional_div_use"+i;
d.use && div.addEventListener("click",d.use,false);
d.children && d.children.forEach(function(dd,ii){
var el = document.createElement(dd[0]);
el.textContent = dd[1] || "";
el.className = dd[2] || "";
this.appendChild(el);
},div);
this.appendChild(div);
},container);
推荐阅读
- sml - 我能得到一些关于不使用 isSome、SOME、NONE、null 而是模式检查的例子吗?
- python-3.x - 在 Python 中更改列表中混合元素的类型
- javascript - 使用类似功能的纯javascript重现scrollIntoView
- android - .overrides 在预设选项中是不允许的 React Native
- r - 在R中如何对R6对象数组进行排序
- go - 在 gin 中使用 go-assets 的示例
- ssh - 将远程 ssh 连接到 pc... pc 连接 vpn
- python - 如何删除 Pandas 系列 (pandas.core.series.Series) 的索引以返回 numpy.ndarray?
- r - 在指定间隔内将 0 值添加到 R 中的现有绘图
- python - 无法保存使用 Keras 功能 API 制作的模型