javascript - 从 JSON 生成 HTML,分配点击事件但不适用于初始 div

标签 javascript json

标题不好,不太确定如何描述。

请看一下下面的对象,您可以看到有 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 结构中的不同位置,因此这可能就是它被忽略的原因。

编辑

嗯,这很奇怪,尽管现在我看到的与您所看到的相反,即我可以在“测试”中看到四个数据点击属性,在“调试”中看到三个。 enter image description here

我不确定这是否是您所期望的结构,但它似乎确实使用正确的数据点击属性正确添加了四个 div 标签。

关于javascript - 从 JSON 生成 HTML,分配点击事件但不适用于初始 div,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44566050/

相关文章:

javascript - HTML - 如何连接两个下拉菜单并使第二个下拉菜单可点击

json - REST:使用一个请求更新多个资源 - 它是标准的还是应该避免的?

android - 带有远程图像的 Phonegap + Photoswipe

javascript - 在 javascript 中测量 websockets 数据输入/输出的大小

javascript - 如何有条件地在 GraphQL 查询中包含过滤参数?

javascript - RequireJS:如何从一个模块加载多个函数?

javascript - 检测由shift键和其他键组合产生的特殊字符

javascript - 如何删除 (function() {'use strict' ; } 和 ());当与 grunt-contrib-concat 连接时

javascript - 编码 JSON 并存储在 MYSQL 中的正确方法?

ios - 如何在 iOS 中使用 post 方法通过传递参数来创建注册表单?