【问题标题】:Most efficient way to dynamically add elements to HTML from Javascript从 Javascript 向 HTML 动态添加元素的最有效方法
【发布时间】:2022-11-27 02:47:27
【问题描述】:

我正在尝试将在 JS 中创建的元素动态添加到 HTML,但想知道最有效的方法。例如将用户添加到列表中,结果将是:

<div id="user-list" style="display:flex; flex-direction:column">

 <div id="user-1">
  <span class="photo" style="width:25%">PHOTO</span>
  <span class="name" style="width:25%">name</span>
  <span class="surname" style="width:25%">surname</span>
  <span class="age" style="width:25%">age</span>
 </div>

 <div id="user-2">
  <span class="photo" style="width:25%">PHOTO</span>
  <span class="name" style="width:25%">name</span>
  <span class="surname" style="width:25%">surname</span>
  <span class="age" style="width:25%">age</span>
 </div>

</div>

我尝试了这两种方式:

document.getElementById("user-list").innerHtml +=  
       `<div id="user-${userId}">
         <span class="photo" style="width:25%">${userPhoto}</span>
         <span class="name" style="width:25%">${userName}</span>
         <span class="surname" style="width:25%">${userSurname}</span>
         <span class="age" style="width:25%">${userAge}</span>
        </div>`

var user = document.createElement("div");
user.id = `user-${userId}`

var photo = document.createElement("span");
photo.setAttribute('style','width:25%')
photo.innerHTML = userPhoto;

var name = document.createElement("span");
name.setAttribute('style','width:25%')
name.innerHTML = userName;

var surname = document.createElement("span");
surname.setAttribute('style','width:25%')
surname.innerHTML = userName;

var age = document.createElement("span");
age.setAttribute('style','width:25%')
age.innerHTML = userAge;

user.appendChild(photo);
user.appendChild(name);
user.appendChild(surname);
user.appendChild(age);

document.getElementById("user-list").appendChild(user);

它会循环创建和添加所有用户(例如 20 个用户)。

哪个更有效率?

【问题讨论】:

  • 第一种方法在我看来要简单得多。
  • .innerHTML 绝对不是最有效的方法。事实上,innerHTML 应该避免,因为它不仅存在性能问题(HTML 解析器每次使用时都必须重建 DOM),而且还可能使您的代码暴露于注入攻击。 document.createElement() 可能代码更多,但性能会更好,也更安全。
  • 此外,如果您正在使用不包含任何 HTML 的字符串,您绝对应该使用 .textContent 而不是 .innerHTML,因为 .textContent 不会重建 DOM(因此它的性能更好)。此外,除了这种语法:name.setAttribute('style','width:25%'),您还可以将 HTML 属性作为 JavaScript 属性访问,如下所示:name.style.width = "25%";
  • @Pranev 更简单并不总是更好。请参阅我上面关于为什么应始终避免使用 .innerHTML 的评论。
  • 它会比.innerHTML 好,但下面@Hewr Chelsea 关于使用template 的回答可能最适合较大的标记“块”。

标签: javascript html css


【解决方案1】:

我会使用 html &lt;template&gt; 标签。 您将拥有这些元素,并且能够通过循环用数据填充它。 例子:

const template = document.querySelector('template')
const clone = template.content.cloneNode(1).firstElementChild

并且您将能够在每个条目的循环中克隆此模板,并且能够使用以下方法从中选择元素:

clone.querySelector('<selector>')

当您用数据填充模板后,您可以将此克隆元素添加到 dom 或任何元素。像这样:

document.appendChild(clone)

欲了解更多信息,请查看html template tag with examples

【讨论】:

  • 感谢您的想法,将看看模板和克隆
【解决方案2】:

您可以通过多种方式修改 DOM。使用document.createElementinsertAdjacentHTMLinsertAdjacentTextinsertAdjacentElementcloneNode或最简单的是innerHTML

添加不会以任何方式与 use 交互的静态元素,insertAdjacentHTMLinsertAdjacentTextinsertAdjacentElementinnerHTML 会为您做的很好。


但是使用document.createElement,您可以更好地控制该 DOM 元素。允许您以最简单的方式添加侦听器、添加和更新属性,甚至从 DOM 中删除元素。

只是快速向您展示,但您肯定可以比这更有效地使用 js 来管理文档中的元素。

const employees=[{userId:"56146443",age:52,jobTitleName:"Developer",firstName:"Romin",lastName:"Irani",preferredFullName:"Romin Irani",employeeCode:"E1",region:"CA",phoneNumber:"408-1234567",emailAddress:"romin.k.irani@gmail.com"},{userId:"28949847",age:45,jobTitleName:"Developer",firstName:"Neil",lastName:"Irani",preferredFullName:"Neil Irani",employeeCode:"E2",region:"CA",phoneNumber:"408-1111111",emailAddress:"neilrirani@gmail.com"},{userId:"8934656",age:29,jobTitleName:"Program Directory",firstName:"Tom",lastName:"Hanks",preferredFullName:"Tom Hanks",employeeCode:"E3",region:"CA",phoneNumber:"408-2222222",emailAddress:"tomhanks@gmail.com"}];
    const tableHeadings = ['User Id', 'Age', 'Job Title', 'First Name', 'Last Name', 'Preferred Full Name', 'Employee Code', 'Region', 'Phone Number', 'Email Address', 'Change Status', 'Remove'];

    function Cell(data){
      this.render = () => {
        const cell = document.createElement('td');
        cell.append(data);
        return cell;
      }
    }

    function Row(data, deleteRow){
      this.isDisabled = false;
      this.handleDisableAction = () => {
        this.isDisabled = true;
      }
      this.handleDeleteAction = () => {
        deleteRow(data.userId);
      }
      this.render = () => {
        const row = document.createElement('tr');
        row.classList.add(data.age > 50? 'danger': 'normal');
        row.append(...Object.values(data).map(d => {
          const cell = new Cell(d).render();
          cell.innerHTML = d;
          return cell;
        }))

        const buttonDisable = document.createElement('button');
        buttonDisable.textContent = this.isDisabled ? 'Enable' : 'Disable';
        buttonDisable.classList.add(this.isDisabled ? 'disabled': 'enabled');
        buttonDisable.addEventListener('click', this.handleDisableAction.bind(this));
        row.append(new Cell(buttonDisable).render());

        const buttonDelete = document.createElement('button');
        buttonDelete.textContent = 'Delete';
        buttonDelete.addEventListener('click', this.handleDeleteAction.bind(this));
        row.append(new Cell(buttonDelete).render());

        return row;
      }
    }

    function TableHeader(data){
      this.render = () =>{
        const tableHeader = document.createElement('tr');
        tableHeader.append(...data.map(d => new Cell(d).render()));
        return tableHeader;
      }
    }

    function Table(data){
      this.handleDeleteRow = (rowId) => {
        data = data.filter(d => d.userId !== rowId);
        alert(`${rowId} will be deleted soon`);
      }
      this.render = () =>{
        const table = document.createElement('table');
        table.setAttribute('border', 1);
        table.append(new TableHeader(tableHeadings).render())
        table.append(...data.map(d => {
          const row = new Row(d, this.handleDeleteRow).render();
          return row;
        }))
        return table;
      }
    }

    document.body.append(new Table(employees).render());
table{ width: 100%; }
tr.danger{ background-color: orange; }
td{ padding: 5px; }

欢迎提出建议。

【讨论】:

    【解决方案3】:

    要动态创建和附加 HTML 元素,请使用此代码 sn-p。

        <script>
    
        'use strict';
    
    
        const createDynamicElements = (elType,elId,elClass,elInnerHtml) => {
    
            const el = document.createElement(elType);
            el.setAttribute('id',elId);
            el.setAttribute('class',elClass);
            el.innerHTML = elInnerHtml
            document.body.appendChild(el);
    
        }
    
    
        let elType      = 'div';
        let elId        = 'div-id';
        let elClass     = 'div-class';
        let elInnerHtml = `<p>Hai this is para</p>`;
    
       createDynamicElements(elType,elId,elClass,elInnerHtml); 
    
       </script> 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-12
      • 1970-01-01
      • 2019-01-06
      • 1970-01-01
      相关资源
      最近更新 更多