CSS 对于动态创建的 html 无效

Posted

技术标签:

【中文标题】CSS 对于动态创建的 html 无效【英文标题】:CSS is inactive for dynamically created html 【发布时间】:2021-11-12 17:02:00 【问题描述】:

我想要一个用户可以更新(添加、删除和重命名节点)的树视图,但我遇到了问题。

我从这里描述的过程开始:https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_treeview。您可以在此处查看我如何尝试更新节点:https://jsfiddle.net/mervius68/4of5ung0/2/。如果我使用 javascript 替换元素的 outerhtml,则不再识别该文本内的类(打开和关闭树节点所必需的)。如何让 CSS 应用于 Javascript 创建的 HTML?名为“Tea”的节点成功重命名为“BEAR”,但无法再在折叠和打开之间切换。

我可以在仅更改 innerHTML 时使其工作,但我需要添加全新的节点,所以我认为我需要让 outerHTML 选项工作。请帮忙?

  <!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
ul, #myUL 
  list-style-type: none;


#myUL 
  margin: 0;
  padding: 0;


span.caret 
  cursor: pointer;
  -webkit-user-select: none; /* Safari 3.1+ */
  -moz-user-select: none; /* Firefox 2+ */
  -ms-user-select: none; /* IE 10+ */
  user-select: none;


span.caret::before 
  content: "\25B6";
  color: black;
  display: inline-block;
  margin-right: 6px;


span.caret-down::before 
  -ms-transform: rotate(90deg); /* IE 9 */
  -webkit-transform: rotate(90deg); /* Safari */'
  transform: rotate(90deg);  


.nested 
  display: none;


.active 
  display: block;

</style>
</head>
<body>

<h2>Tree View</h2>
<p>A tree view represents a hierarchical view of information, where each item can have a number of subitems.</p>
<p>Click on the arrow(s) to open or close the tree branches.</p>

<ul id="myUL">
  <li><span class="caret">Beverages</span>
    <ul class="nested">
      <li>Water</li>
      <li>Coffee</li>
      <li><span id="test" class="caret">Tea</span>
        <ul class="nested">
          <li>Black Tea</li>
          <li>White Tea</li>
          <li>Green Tea</li>
        </ul>
      </li>  
    </ul>
  </li>
</ul>
<button onclick="myFunction()">Click me</button>

<script>
    function myFunction()     
        document.getElementById("test").outerHTML =  `<li><span id="test2" 
              class="caret">BEAR</span>
              <ul class="nested">
              <li>Black Tea</li>
              <li>White Tea</li>
              <li>Green Tea</li>
              </ul>
              </li>`
    
</script>

<script>
     var toggler = document.getElementsByClassName("caret");
     var i;
     for (i = 0; i < toggler.length; i++) 
         toggler[i].addEventListener("click", function() 
         this.parentElement.querySelector(".nested").classList.toggle("active");
         this.classList.toggle("caret-down");
  );

</script>

</body>
</html>

【问题讨论】:

你不会丢失事件监听器 - 我看不到它与你新创建的元素相关联的任何地方。 【参考方案1】:

问题不在于未识别类。正如 cmets 中提到的 @A Haworth 那样,问题在于您没有将任何事件侦听器附加到新创建的元素。您拥有的将事件侦听器附加到所有 caret 类的脚本仅在加载时运行一次。之后,如果您要创建新元素,则必须将新的事件侦听器附加到此新元素。

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
ul, #myUL 
  list-style-type: none;


#myUL 
  margin: 0;
  padding: 0;


span.caret 
  cursor: pointer;
  -webkit-user-select: none; /* Safari 3.1+ */
  -moz-user-select: none; /* Firefox 2+ */
  -ms-user-select: none; /* IE 10+ */
  user-select: none;


span.caret::before 
  content: "\25B6";
  color: black;
  display: inline-block;
  margin-right: 6px;


span.caret-down::before 
  -ms-transform: rotate(90deg); /* IE 9 */
  -webkit-transform: rotate(90deg); /* Safari */'
  transform: rotate(90deg);  


.nested 
  display: none;


.active 
  display: block;

</style>
</head>
<body>

<h2>Tree View</h2>
<p>A tree view represents a hierarchical view of information, where each item can have a number of subitems.</p>
<p>Click on the arrow(s) to open or close the tree branches.</p>

<ul id="myUL">
  <li><span class="caret">Beverages</span>
    <ul class="nested">
      <li>Water</li>
      <li>Coffee</li>
      <li><span id="test" class="caret">Tea</span>
        <ul class="nested">
          <li>Black Tea</li>
          <li>White Tea</li>
          <li>Green Tea</li>
        </ul>
      </li>  
    </ul>
  </li>
</ul>
<button onclick="myFunction()">Click me</button>

<script>
    function myFunction()     
        document.getElementById("test").outerHTML =  `<li><span id="test2" 
              class="caret">BEAR</span>
              <ul class="nested">
              <li>Black Tea</li>
              <li>White Tea</li>
              <li>Green Tea</li>
              </ul>
              </li>`
        document.getElementById("test2").addEventListener("click", function() 
     this.parentElement.querySelector(".nested").classList.toggle("active");
     this.classList.toggle("caret-down");
        );
    
</script>

<script>
     var toggler = document.getElementsByClassName("caret");
     var i;
     for (i = 0; i < toggler.length; i++) 
         toggler[i].addEventListener("click", function() 
         this.parentElement.querySelector(".nested").classList.toggle("active");
         this.classList.toggle("caret-down");
  );

</script>

</body>
</html>

【讨论】:

你是对的!再次应用 addEventListener,它可以工作了。

以上是关于CSS 对于动态创建的 html 无效的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js:如何使动态创建的 HTML 使用作用域 CSS?

layUi 模板引擎动态创建元素之后,绑定的事件无效了;

创建与 CSS/HTML 相关的丰富动态单页 Django Web 应用程序的最佳方法

如何在 JavaScript 中动态创建 CSS 类并应用?

JQuery 动态加载 HTML 元素时绑定点击事件无效问题

怎么使用CSS3创建动态菜单