标题不好,不太确定如何描述。
请看一下下面的对象,您可以看到有 4 个名为 data-click
的键。当从此 JSON 对象生成 HTML 时,这些键将被正确添加为属性。
但是,由于某种原因,当我对 HTML 对象进行 querySelectorAll
搜索时,它只找到其中 3 个属性,这是为什么?
https://codepen.io/anon/pen/zzovPE
var json = `{
"div": {
"id": "marvLightbox",
"data-click": "EventClose",
"0": {
"div": {
"class": "marvLightbox__left",
"data-click": "EventLeft"
}
},
"1": {
"div": {
"class": "marvLightbox__right",
"data-click": "EventRight"
}
},
"2": {
"div": {
"0": {
"div": {
"class": "marvLightbox__eschint",
"content": "Press <span>ESC</span> to close"
}
},
"1": {
"div": {
"class": "marvLightbox__close",
"data-click": "EventClose"
}
},
"2": {
"img": {
"src": "https://www.asphaltandrubber.com/wp-content/gallery/ducati-1199-panigale-r-launch-with-jensen-beeler/ducati-1199-panigale-r-launch-cota-jensen-beeler-07.jpg",
"class": "responsive-img image"
}
},
"class": "marvLightbox"
}
}
}
}`;
function buildHTML(code) {
"use strict";
var handleAttribute = function(element, attribute, value) {
if (value instanceof HTMLElement) {
return element.appendChild(value);
}
switch (attribute) {
case 'class':
case 'src':
case 'id':
case 'data-click':
return element.setAttribute(attribute, value);
case 'content':
return element.innerHTML = value;
// other keys...
default:
console.log(element.tagName, attribute, value);
}
}
var htmlReviver = function(key, value) {
// parse as element
if (isNaN(key) && typeof value === 'object') {
var element = document.createElement(key);
var subValue;
for (var attribute in value) {
handleAttribute(element, attribute, value[attribute]);
}
return element;
// move element from { index: { tagName: Element } } to { index: Element }
} else if (!isNaN(key)) {
return value[Object.keys(value)[0]];
// leave property alone
} else {
return value;
}
}
try {
var htmlObject = JSON.parse(code, htmlReviver);
} catch (e) {
console.log('marv.lightbox (Error): The HTML structure provided appears to have an error: ' + e);
}
return htmlObject;
}
(function() {
var html = buildHTML(json);
html.querySelectorAll('[data-click]').forEach(function(e) {
e.addEventListener('click', function() { events(e.dataset.click); });
document.getElementById('debug').innerHTML += 'Function: ' + e.dataset.click + ' Element: ' + e + '<br>';
});
document.getElementById('test').append(html);
}());
body > div {
width: 50%;
float: left;
display: inline-block;
}
img {
max-width: 80%;
max-height: 80%;
}
<html>
<head></head>
<body>
<div id="test"></div>
<div id='debug'></div>
</body>
</html>
编辑 1:
好吧,这没有道理。如果我将 html
对象附加到我的 div 中,就像我在上面的示例中所做的那样。然后,如果我对附加了 HTML 的 div 中的内容进行 querySelectorAll
搜索,它就会看到所有 4 个 data-click
属性...
(function() {
var html = buildHTML(json);
document.getElementById('test').append(html);
document.getElementById('test').querySelectorAll('[data-click]').forEach(function(e) {
document.getElementById('debug').innerHTML += 'Function: ' + e.dataset.click + ' Element: ' + e + '<br>';
});
}());
它应该对实际的 html
对象执行完全相同的操作,尽管它是相同的内容...
最佳答案
我认为问题不在于 querySelectorAll
部分。我在代码笔的第 103 行添加了一个 alert(html.innerHTML)
,作为查看已构建的 html 外观的快速方法。该 html
变量仅包含三个“data-click”属性,因此看起来问题出在这些 html 属性的生成中。
看起来它没有处理第一个数据点击
,它看起来也位于 json 结构中的不同位置,因此这可能就是它被忽略的原因。
编辑
嗯,这很奇怪,尽管现在我看到的与您所看到的相反,即我可以在“测试”中看到四个数据点击属性,在“调试”中看到三个。
我不确定这是否是您所期望的结构,但它似乎确实使用正确的数据点击属性正确添加了四个 div 标签。
关于javascript - 从 JSON 生成 HTML,分配点击事件但不适用于初始 div,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44566050/