如何使用JavaScript在第一个文本元素之后的链接中附加元素?

时间:2019-01-05 09:46:40

标签: javascript

我想在链接内附加一个元素-例如<span>extracontent</span>-但仅当内部有文字且仅在第一个文字之后才添加文字。

有很多组合,我用不同的代码处理了它们(寻找插入我的元素的位置):

  • 简单:elem.childNodes.length == 1
  • 在子级中循环:!currChildren[j].childElementCount && currChildren[j].textContent.trim().length

是否可以通过一个循环处理所有情况?

带有预期结果的附加代码的各种可能性的示例:

  • 简单文本:<a href="#">Text<span>extracontent</span></a>
  • 图标:<a href="#"><i class="fa fa-search"></i><span>extracontent</span></a>
  • 包含图像和文本的分区:

    <a href="#">
        <div>
            <div><img src="" alt="" width="24" height="24"></div>
            <div>Text<span>extracontent</span></div>
        </div>
    </a>
    
  • 多文本:

    <a href="#">
        <div><img src="" alt="" width="24" height="24"></div>
        <div>
            <div>Text1<span>extracontent</span></div>
        </div>
        <div>Text2</div>
    </a>
    

1 个答案:

答案 0 :(得分:1)

只要发现不为空的文本节点,就可以递归解析DOM树并追加元素。

编辑:现在也考虑了<i>元素(请参见下面的评论)。

function isTargetTextElement(element) {
  return (element.nodeType === Node.TEXT_NODE && element.textContent.trim().length > 0)
      || element.nodeName === 'I';
}

function appendAfterFirstText(parentElement, elementToAppend) {
  // Browse through all the element's children
  for (const childElement of parentElement.childNodes) {
    // If that node is a non-empty text node, append the element after it and stop
    if (isTargetTextElement(childElement)) {
      parentElement.insertBefore(elementToAppend, childElement.nextSibling);
      return true;
    }
    // Otherwise, do the same starting from that node's children
    if (appendAfterFirstText(childElement, elementToAppend)) {
      return true;
    }
  }
  return false;
}

document.querySelectorAll('a').forEach(a => {
  const elementToAppend = document.createElement('span');
  elementToAppend.textContent = 'extracontent';
  appendAfterFirstText(a, elementToAppend);
});
<a href="#">
  <div>
    <div><img src="" alt="" width="24" height="24"></div>
    <div>Text</div>
  </div>
</a>

<a href="#">
  <div><img src="" alt="" width="24" height="24"></div>
  <div>
    <div>Text1</div>
  </div>
  <div>Text2</div>
</a>

<a href="#">
  <i class="fa fa-search"></i>
</a>