【问题标题】:Why won't JavaScript function create an HTML element?为什么 JavaScript 函数不会创建 HTML 元素?
【发布时间】:2019-02-10 05:59:00
【问题描述】:

我有一个方法,用于在另一个 div 中创建 div...但是它不起作用...

方法如下:

populateSquares(){
    let relatedTagToPopulation = document.getElementById("questionp");
    let whatTextIs = relatedTagToPopulation.textContent;
    for (let u=0;u<this.stemQuestions.length;u++){
        if (this.stemQuestions[u]==whatTextIs){
            var populateSquaresPertinentInt = u;
        }
    }
    for  (let i=0;i<this.stemAnswers.length;i++){
        if (i==populateSquaresPertinentInt){
            let numberOfSquaresToAdd = this.stemAnswers[i].length;
            for (let j=0;j<numberOfSquaresToAdd;j++){
                let elToAdd = document.createElement("<div id='ans"+j+"' class='lans'></div>"); 
                let elToAddInto = document.getElementById("answeri"); 
                elToAddInto.appendChild(elToAdd); 
            }
        }
    }
}

它给出了这个错误...

Uncaught DOMException: Failed to execute 'createElement' on 'Document': The tag name provided ('<div id='ans0' class='lans'></div>') is not a valid name.

【问题讨论】:

  • createElement 采用标签名称,例如 "div",而不是 HTML。您将单独分配属性。

标签: javascript html dom


【解决方案1】:

如果你使用 JavaScript,你应该关注文档:https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement,这里是:CreateElement with id?

let elToAdd = document.createElement('div')
// then call `elToAdd.xxxx` to add attributes or do other operation on the element
elToAdd.setAttribute("id", "ans" + i);
// ... more

如果你使用的是 jQuery,你可以使用:

let elToAdd = jQuery("<div id='ans"+j+"' class='lans'></div>")

【讨论】:

  • 注意id属性也被一个属性所反映,所以你可以这样做:elToAdd.id = "ans" + j
【解决方案2】:

创建标签的三种方法

以下示例都做同样的事情:
使用类创建一个&lt;article&gt; 标记:.post 并将其添加到&lt;main id="main"&gt; 标记中。
有一个例外请参阅#2 .innerHTML


document.createElement(tagName)

唯一的参数是tagName(例如"DIV""SPAN""IFRAME" 等)。创建完成后,需要将其添加到 DOM:

const post = document.createElement("ARTICLE");
post.className = "post";
document.getElementById('main').appendChild(post);

这是一种古老但稳定的方法,但创建一个准系统标签需要两行代码。需要更多代码来分配属性和内容。


.innerHTML += htmlString

此属性将从目标标记内的给定字符串中解析出一个标记。如果使用= 运算符,则目标标签的所有内容都会被htmlString 覆盖。如果使用+= 运算符,htmlString 将被附加到目标标签内的内容中。

document.querySelector('main').innerHTML += `<article class='post'></article>`;

这种模式简单而通用。在一行中,可以使用属性和内容创建多个标签。它仅限于覆盖内容:= 或附加到内容:+=

编辑: Kaiido 通知我.innerHTML 将替换所有内容,因此如果您担心事件绑定或引用,请不要使用它。请参阅下面的 cmets。


.insertAdjacentHTML(position, htmlString)

这是使用类固醇的.innerHTML。它将在目标标签的给定htmlString 之前/之后/内部/外部插入。第一个参数是确定插入相对于目标标签的位置的四个字符串之一:

"beforebegin" <div id="target"> "afterbegin" text content "beforeend" </div> "afterend"

第二个参数是要插入的htmlSting

document.getElementsByTagName('MAIN')[0].insertAdjacentHTML('afterbegin', `
  <article class='post'></article>
`);                    

我无法遵循您的代码,但它应该是一种方法?所以演示中有一个名为populate 的对象,还有一个名为documentSection() 的工厂函数,它创建对象并从populate 继承方法.createSection()

演示

let text = ['post 1', 'post 2', 'post 3'];
let archives = ['document 1', 'document 2', 'document 3'];

const populate = content => ({
  createSections: () => {
    let idx = 0;
    const target = document.querySelector("main");
    /* 
    Pattern 1 - document.createElement(tagName)
    */
    const section = document.createElement('SECTION');
    section.id = content.title;
    target.appendChild(section);
    /*
    Pattern 2 - .innerHTML += htmlString
    */
    section.innerHTML += `<h2>${content.title}</h2>`;
    for (let text of content.text) {
      idx++;
      /*
      Pattern 3 - .insertAdjacentHTML(position, htmlString)
      */
      section.insertAdjacentHTML('beforeend', `<article id="${content.title}-${idx}" class="t">${text}</article>`);
    }
  }
});

const documentSection = (title, text) => {
  let content = {
    title: title,
    text: text
  };
  return Object.assign(content, populate(content));
};

const post = documentSection('Post', text);
const archive = documentSection('Archive', archives);

post.createSections();
archive.createSections();
main {
  display: table;
  border: 3px ridge grey;
  padding: 2px 10px 10px;
}

h1 {
  font: 900 small-caps 1.5rem/1 Tahoma;
  margin-bottom: 8px
}

h2 {
  font: 700 small-caps 1.2rem/1 Tahoma;
  margin-bottom: 8px
}

section {
  border: 2px solid #000;
  padding: 2px 8px 8px;
}

article {
  font: 400 1rem/1.25 Arial;
}

.t::before {
  content: attr(id)': ';
  font-weight: 700;
}
<main>
  <h1>Documents</h1>
</main>

【讨论】:

  • 不,#2 根本不做同样的事情。从 DOM 的角度来看,它确实删除了
    元素及其所有子元素,然后添加一个具有相同标记的新元素,以及与前一个
    的子元素共享相同标记的新元素> 和一个新的
    元素。如果您有任何变量指向这些子元素之一,那么它们指向的元素现在不在文档中。如果你有任何事件监听器,它们就消失了。
  • 请注意,先生,谢谢。 @Kaiido 用 .innerText.textContent 清除任何东西 +=
猜你喜欢
  • 1970-01-01
  • 2018-02-13
  • 1970-01-01
  • 2017-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-27
  • 2018-07-05
相关资源
最近更新 更多