将插入符位置内容的 HTML 标签拆分为多个标签

问题描述 投票:0回答:2

我在插入符号位置拆分标签内容时遇到一些问题。我可以获得分割索引以及分割后插入符号位置的标签内容。我面临的问题如下所示。

<html>
 <div contenteditable="true">
  <strong><em> Suppose this is the content inside tag </em></strong>
 </div>
</html>

我已将光标设置在“内容”和“内部”一词之间。如果我现在按下一个按钮,它应该执行如下操作:

<html>
 <div contenteditable="true">
  <strong>
   <em> Suppose this is the content </em>
  </strong>
  """the cursor will be here""" 
  <strong>
   <em>inside tag </em>
  </strong>
 </div>
</html>
javascript html typescript dom
2个回答
1
投票

首先获取选区,找到光标位置,将其定位在可编辑的

div
中,然后在该位置拆分
innerHTML

接下来,从

target
元素开始(被单击的最里面的元素,不一定与添加单击处理程序的元素相同),使用
do {} while ()
循环和
parentNode
属性来创建一个嵌套标签数组。

将嵌套标签数组转换为字符串,首先是结束标签,然后是开放标签。该数组迭代两次,一次按照初始顺序,然后在颠倒顺序后进行第二次。

有了“之前”的 HTML,标签关闭然后打开字符串,以及“之后”的 HTML,然后将它们组合起来,最后更新可编辑的

div

document.querySelector("div").addEventListener("click", function({target, currentTarget}) {
  if (target !== currentTarget) {
    let sel = window.getSelection(),
      elem = target, // target is clicked element
      ao = sel.anchorOffset, // get cursor postion in target
      an = sel.anchorNode,
      txt = an.textContent,
      ctxt = currentTarget.innerHTML, // currentTarget is event listener element
      cao = ctxt.indexOf(txt) + ao, // get cursor position in currentTarget
      bef = ctxt.substring(0, cao),
      aft = ctxt.substring(cao, ctxt.length),
      tags = [];

    // get all nested tags
    do {
      tags.push(elem.tagName);
      elem = (undefined === elem) ?
        target.parentNode : elem.parentNode;
    } while (elem !== currentTarget);

    // build new HTML with close and open tags inserted at cursor
    let ntxt = bef; // start with HTML before cursor
    // convert tag array to string of close tags
    ntxt += tags.reduce((prev, tag) => prev + '</' + tag + ">", "");

    // reverse tag array
    ntxt += tags.reverse() 
      // then convert to open tags
      .reduce((prev, tag) => prev + '<' + tag + ">", "");

    // end with HTML after cursor
    ntxt += aft;
    
    currentTarget.innerHTML = ntxt;    
    sel.collapse(sel.focusNode, 2); // frankly, I don't know why "2" works here :S
    
    // resulting (encoded) HTML contents of div
    console.log(currentTarget.innerHTML);
  }
});
<div contenteditable="true">
  <strong><em> Suppose this <span>is the</span> content inside tag </em></strong>
</div>


0
投票

您的代码工作完美,只有当 div 包含换行符 (
) 并且插入符号位于换行符的开头时才会失败。如何修改才能处理这种情况?

document.querySelector("div").addEventListener("click", function({target, currentTarget}) {
  if (target !== currentTarget) {
    let sel = window.getSelection(),
      elem = target, // target is clicked element
      ao = sel.anchorOffset, // get cursor postion in target
      an = sel.anchorNode,
      txt = an.textContent,
      ctxt = currentTarget.innerHTML, // currentTarget is event listener element
      cao = ctxt.indexOf(txt) + ao, // get cursor position in currentTarget
      bef = ctxt.substring(0, cao),
      aft = ctxt.substring(cao, ctxt.length),
      tags = [];

    // get all nested tags
    do {
      tags.push(elem.tagName);
      elem = (undefined === elem) ?
        target.parentNode : elem.parentNode;
    } while (elem !== currentTarget);

    // build new HTML with close and open tags inserted at cursor
    let ntxt = bef; // start with HTML before cursor
    // convert tag array to string of close tags
    ntxt += tags.reduce((prev, tag) => prev + '</' + tag + ">", "");

    // reverse tag array
    ntxt += tags.reverse() 
      // then convert to open tags
      .reduce((prev, tag) => prev + '<' + tag + ">", "");

    // end with HTML after cursor
    ntxt += aft;
    
    currentTarget.innerHTML = ntxt;    
    sel.collapse(sel.focusNode, 2); // frankly, I don't know why "2" works here :S
    
    // resulting (encoded) HTML contents of div
    console.log(currentTarget.innerHTML);
  }
});
<div contenteditable="true">
  <strong><em> Suppose this <span>is the</span> content<br><br><br><br> inside tag </em></strong>
</div>

© www.soinside.com 2019 - 2024. All rights reserved.