Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Html 选择所有跨距文本时如何获取元素?_Html_Contenteditable - Fatal编程技术网

Html 选择所有跨距文本时如何获取元素?

Html 选择所有跨距文本时如何获取元素?,html,contenteditable,Html,Contenteditable,在内容可编辑的div中,我希望用一个文本环绕选定的文本,或者在选择其中的所有文本时修改现有文本。我能做第一件,但不能做第二件 在第二种情况下,如果我有ABC并选择了B,则选择将锚点节点显示为A,焦点节点显示为C,而toString返回B。父节点是封闭的段落,而不是文本。我找不到任何方法来区分在ABC中选择B和在ABC中选择B,因为我找不到任何方法来发现在第一种情况下围绕B的元素的存在。肯定有办法做到这一点吧?有人能告诉我怎么做吗 代码如下: var sel = window.getSelecti

在内容可编辑的div中,我希望用一个文本环绕选定的文本,或者在选择其中的所有文本时修改现有文本。我能做第一件,但不能做第二件

在第二种情况下,如果我有ABC并选择了B,则选择将锚点节点显示为A,焦点节点显示为C,而toString返回B。父节点是封闭的段落,而不是文本。我找不到任何方法来区分在ABC中选择B和在ABC中选择B,因为我找不到任何方法来发现在第一种情况下围绕B的元素的存在。肯定有办法做到这一点吧?有人能告诉我怎么做吗

代码如下:

var sel = window.getSelection();
var range = sel.getRangeAt(0);
var selected = range.compareBoundaryPoints(range.START_TO_END, range);
if (selected > 0) {    // some text is selected
  var el = range.commonAncestorContainer;
  //
  // would expect to find el == <span> if selection is B
  // in <p>A<span>B</span>C<p>, but find <p> instead!
  //
  //... code to surround selection with new span or to process
  //    existing span... but there is never an existing span!
}
Range.commonAncestorContainer有一个名为parentElement的属性。它是所选文本的父级

在代码片段中,伦敦和巴黎都用span元素包装

const text=你好,来自伦敦和巴黎

const parser=新的DOMParser; const html=parser.parseFromStringtext,text/html.body.innerHTML const editor=document.querySelector'div[contenteditable]' editor.innerHTML=html 函数getParent{ var selection=window.getSelection; if selection.rangeCount{ 常量范围=selection.getRangeAt0; const parent=range.commonAncestorContainer.parentElement; document.querySelectorresult.innerText=HtmlPanelElement的父实例 如果HtmlPanelElement的父实例{ console.logparent } } } document.querySelectorbutton.onclick=getParent; 获取文本 是HtmlPanelElement的父实例吗


对于上述问题,我想出了一个相当糟糕的解决方法。为了测试选择是否是元素的全部,我克隆了范围,当它是整个范围时,它包含前面的范围和后面的空字符串。所以我要做的就是移除其中的任何一个,然后检查剩下的是否是一个跨度元素。如果是这样的话,我将在原始范围开始后取下一个元素,它将是:


这是可行的,但不是很吸引人。如果有人有一个更整洁的解决方案,我会很高兴。

您想在什么环境下这样做?你有更多的代码吗?在上面添加了一些代码。我正在做的是:使用Firefox,双击内容可编辑div中段落中的一个单词,添加一个有效的span,然后双击同一个单词,尝试修改我刚刚插入的span,并在分配给el之后在浏览器的调试器中放置一个断点。仅当我在插入跨距后立即单击按钮修改跨距时,el的值才是跨距-如果我单击其他位置,然后返回并再次双击该单词,它将无法找到跨距,即使所选文本完全在其中。因为它找不到跨距,我以ABC结尾。这只适用于您选择范围内的文本,而不是整个范围内的内容。例如,如果您选择整个单词London,则共同祖先是,它包围了,parentElement则是的包围。我试图处理这样一种情况,即选择是整个跨度内容。当你在上面选择伦敦时,你实际上是在选择伦敦,而且似乎没有任何简单的方法来区分伦敦和伦敦。你可以考虑通过将文本换行来改变字体颜色。如果文本不是整个跨度的内容,例如ondo in London,则我将其包装,以给出例如London。如果我选择了整个跨度,我最终选择了伦敦,它仍然是蓝色的,因为我在现有跨度之外而不是内部进行包装。在本例中,我只想将封闭范围从蓝色改为红色。@user163639 London是Text的实例,而London是HTMLSpanElement的实例。如果您添加所有场景和示例[操作,预期结果],我将帮助您。如果您这样做,请将其包含在问题中。在您的示例中,如果您选择单词London并单击“获取文本”,则不会发生任何事情,因为整个跨度被选中,其父级为,但如果您从单词中间选择ondo,则表示London。我希望这样,如果你从单词中间选择ondo,它会显示ondo,如果你选择London,它会显示London。正如我在下面所说的,我有一个解决方法,但这是一个完全混乱的问题。因此,一个更整洁的解决方案将不胜感激!
var el = range.commonAncestorContainer;
var copy = range.cloneContents();
while (copy.childNodes.length > 1 && copy.firstChild.nodeValue === "") {
  copy.removeChild(copy.firstChild);
}
while (copy.childNodes.length > 1 && copy.lastChild.nodeValue === "") {
  copy.removeChild(copy.lastChild);
}
if (copy.childNodes.length == 1 && copy.childNodes[0] instanceof HTMLSpanElement) {
  el = range.startContainer.nextSibling;
}