javascript 如何从字符串顺序创建元素(js)

kfgdxczn  于 2023-05-21  发布在  Java
关注(0)|答案(2)|浏览(117)

请帮帮我!有一个源代码行html,需要从其中按顺序创建Element。也就是说,有一种方法可以一次创建所有内容,只需通过innerHTML或DOMParser解析字符串即可,但是要迭代所有元素,需要getElementsByTagName(“*”),这非常慢。有没有一种方法可以顺序地构建html,使它在一个循环中接受每个元素?
假设我们有一个html字符串:

<div>abc<span class="abc">123</span>567</div>

然后,用它来做一些像这样的代码:

let parentDiv = document.createElement("div");
for(let i=0;i<3;i++){
  switch(i){
    case 0:
     let txt1 = document.createTextNode("abc")
     parentDiv.appendChild(txt1);
    break
    case 1:
      let el1 = document.createElement("div");
      el1.setAttribute("class","abc");
      for(let j=0;j<1;j++){
        switch(j){
          case 0:
            let txt1 = document.createTextNode("123")
            el1.appendChild(txt1);
          break;
        }
      }
      parentDiv.appendChild(el1);
     break
     case 2:
      let txt2 = document.createTextNode("567")
      parentDiv.appendChild(txt2);
     break
  }
}

仅为任何有效的html字符串生成此类代码。
我将非常感谢的答案!
我认为这里需要一个模板来创建这样的代码,以及一个用于标记的正则表达式regexp。只是很难弄清楚怎么做。

3zwtqj6y

3zwtqj6y1#

在将字符串解析为HTML之后,可以使用TreeWalker API通过nextNode()顺序遍历(按前序遍历)节点的DOM子树。在访问每个节点时,可以检查nodeType和其他属性,以确定要生成的代码(即如果是元素节点,则使用getAttributeNames()提取每个属性并生成设置每个属性的代码,使用tagName获取标签等)。
唯一需要注意的是,API没有公开一个明显的方法来确定下一个Node是子节点、兄弟节点还是父链的上游节点。因此,您可能需要一种跟踪当前节点深度的方法,但我相信,如果您以某种递归方式实现此代码生成,您应该可以免费获得该行为。
下面是非常高级的伪代码:

let htmlStr = '<div>abc<span class="abc">123</span>567</div>';
let htmlElt = parseToHTML(htmlStr);
let walker = document.createTreeWalker(htmlElt, NodeFilter.SHOW_ALL);

function codeGenSeq(rootNode) {
  if (!rootNode) return "";

  let output = "";
  // ... check nodeType
  // ... extract attributes, tagName, nodeValue, etc. depending on the type
  // ... append the code for generating the node to `output`
  let childNodes = Array.from(rootNode.childNodes);
  walker.nextNode();
  if (childNodes.length > 0) {
    // add for loop and switch statement scaffolding to `output`
    while (childNodes.includes(walker.currentNode)) {
      let innerCodeGen = codeGenSeq(walker.currentNode);
      // ... wrap `innerCodeGen` in a new case block and append to `output`
      walker.nextNode();
    }
  }
 
  return output;
}

codeGenSeq(walker.currentNode);
6jjcrrmo

6jjcrrmo2#

问题

  • 注:我不确定我是否正确理解了你的问题。如果我误解了,请纠正我,我会编辑答案。

如果您正确理解了您的问题,您希望创建一个JavaScript函数,该函数接受一个带有HTML代码的字符串(例如'<div>abc</div>')作为参数,并创建相应的DOM元素。字符串可以包含任何HTML代码(例如div、span、table等)。此外,您不希望立即创建元素,而是希望在循环中顺序创建元素。
此外,您不希望使用innerHTML属性一次性创建所有元素,然后使用getElementsByTagName("*")方法迭代所有元素,因为您觉得它太慢了。

回答

我认为你想创建的JavaScript函数可以被创建,但它将是一个非常复杂的函数。您首先需要标识各个元素(可能使用正则表达式来查找开始和结束标记),包括它们各自的类和其他属性(如id、name、href等)。然后需要在循环中创建各个DOM元素。
我认为更简单、更安全(不太容易出错)、更清晰的方法是使用innerHTML属性和getElementsByTagName("*")方法。我不知道为什么你认为这个方法很慢。根据this testgetElementsByTagName("*")一点也不慢因为你可以在一秒钟内运行数百万个这样的操作。我认为你的自定义复杂JavaScript函数可能会慢得多,因为它必须完成上一段中描述的所有步骤。
如果决定使用**innerHTML属性和getElementsByTagName("*")方法**,代码可能如下所示:

function parse_html_string(html_string){
  let parent_div = document.createElement("parent_div");
  parent_div.innerHTML = html_string  // create DOM elements inside a parent div
  all_elems = parent_div.getElementsByTagName("*")  // get all elements inside the parent div
  for (let i=0, max=all_elems.length; i < max; i++) {
    console.log(all_elems[i].nodeName)  // do whatever you need with each element, e.g. print its type to console
  }
  document.body.appendChild(parent_div);
}

var html_string = '<div>abc<span class="abc">123</span>567</div>'
parse_html_string(html_string)
<html>
  <head>
    <meta charset="UTF-8">
  </head>
  <body>
    <script src="code.js"></script>
  </body>
</html>

但是,如果你真的想创建你的自定义函数,你可以尝试通读JourneyApps's domparser的源代码,并使用它来创建你自己的自定义函数。

补充说明

我不明白,为什么你要在你的示例JavaScript代码中使用循环和switch语句。你的JavaScript代码可以简单地重写为:

let parentDiv = document.createElement("div");

parentDiv.appendChild(document.createTextNode("abc"));

let el1 = document.createElement("div");
el1.setAttribute("class","abc");
el1.appendChild(document.createTextNode("123"));
parentDiv.appendChild(el1);

parentDiv.appendChild(document.createTextNode("567"));

相关问题