[英]JavaScript Dynamic Button onClick event (variable scope)
我正在根据从查询数据库的 AJAX 请求返回的 JSON 对象动态创建相当多的按钮。
然后,每个按钮都需要对同一个数据库进行后续 AJAX 调用,具体取决于我放入每个按钮的onClick
函数中的信息。
基本上,url 是"api/{foo}/{bar}/{thing}/"
,如果我只调用"api/"
它给了我所有可能的选项foo
。 如果我调用"api/book/"
它将为我提供bar
where foo = "book"
所有可能的选项......
//getJSON is a promise function that returns a JSON object
getJSON("api")
// volumes is the JSON object that contains an array of objects
// each object is {book:"someTitle",url:"titleShorthand"}
.then((volumes) => {
for (var vol in volumes) {
//create Button returns a document.crateElement(input)
//with type=button and value = the passed in param.
var btn = createButton(volumes[vol].book)
btn.addEventListener('click', function(){
getJSON("api/" + volumes[vol].url)
.then((books) => {
console.log(books)
})
})
volumeDiv.appendChild(btn)
}
})
所有 button.onClick 事件都是相同的,因为在console.log(books)
,无论我单击哪个按钮,都只会给我最后一组书籍。 volumes[vol].url
似乎随着 for 循环的每次迭代而被重写,对于每个按钮,而不仅仅是新创建的按钮。
那是因为您在for
循环中声明了一个函数。 由于闭包的工作方式,当您在循环中声明的函数运行时, volume[vol]
值始终是最后一个值。
为了解决这个问题,您可以使用高阶函数。
我必须模拟一些函数才能使此代码段起作用,但是您必须在代码中编写像getEventListener
这样的函数才能使其正常工作。
var volumeDiv = document.getElementById('container') function getJSON (url) { return new Promise (resolve => { var vol1 = { book: "vol1", url: "vol1" } var vol2 = { book: "vol2", url: "vol2" } var map = { 'api': { vol1, vol2 }, 'api/vol1': vol1, 'api/vol2': vol2 } resolve(map[url]) }) } function createButton (name) { console.log(`creating button ${name}`) var btn = document.createElement('input') btn.type = 'button' btn.value = name return btn } function getEventListener (url) { return () => { getJSON(url) .then((books) => { console.log(books) }) } } getJSON("api") .then(volumes => { for (var vol in volumes) { var volumeUrl = volumes[vol].url var btn = createButton(volumes[vol].book) btn.addEventListener('click', getEventListener("api/" + volumeUrl)) volumeDiv.appendChild(btn) } })
<div id="container" />
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.