我需要使用jQuery基于用户选择拆分HTML元素.在以下示例中,方括号表示选择:
Lor[em
应该成为
Lor [ em
为此,我创建一个范围,找到包含选择边界的TextNodes并使用splitText(index)拆分它们.接下来,我检查是否还必须拆分父元素.如果是,我克隆并清空它们,将原始元素的第二部分移动到克隆中并将它们插入原始元素后如下:
var tail = textNode.splitText( offset );
var $parent = $(textNode).parent();
if ($parent.is("span")) {
var $tail = $parent.clone();
$tail.contents().remove();
$tail = $tail.append(tail).insertAfter($parent);
if ($parent.parent().is("a")) {
$tail = $parent.parent().clone();
$tail.contents().remove();
$tail = $tail.append($tail).insertAfter($parent.parent());
}
return $tail[0];
}
else if ($parent.is("a")) {
var $tail = $parent.clone();
$tail.contents().remove();
$tail = $tail.append(tail).insertAfter($parent);
return $tail[0];
}
return tail;
但问题是,tail只包含TextNode的第二部分.以下< span />没有移动,所以HTML就像这样混乱(选择正在丢失,但并不重要):
Lor em
我也试过$(tail).nextAll()但它似乎返回一个空集.有没有人知道我怎么能做到这一点?如果有任何不清楚的地方,请询问更多细节.
编辑:像建议我创建了以下http://jsfiddle.net/7PdLd/4/.
最佳答案
这似乎有效:
原文链接:https://www.f2er.com/html/426063.htmlfunction start () {
var range = window.getSelection().getRangeAt(0);
split(
range.startContainer,range.startOffset,range.commonAncestorContainer,false
);
split(
range.endContainer,range.endOffset,true
);
}
function split(node,offset,ancestor,backwards) {
var clone;
if(backwards) {
clone = node;
node = node.splitText(offset);
}else{
clone = node.splitText(offset);
}
if(node == ancestor) return;
var parent;
while((parent = node.parentNode) && parent != ancestor) {
var parentClone = parent.cloneNode(false);
appendUntil(parentClone,parent,node,!backwards);
parentClone.insertBefore(clone,backwards ? null : parentClone.firstChild);
node = parent;
clone = parentClone;
}
insertAdjacent(ancestor,clone,backwards);
}
function appendUntil(target,until,fromEnd) {
var from,to,sibling;
if(fromEnd) {
from = until.nextSibling;
to = null;
} else {
from = parent.firstChild;
to = until;
}
while(from && from != to) {
sibling = from.nextSibling;
target.appendChild(from);
from = sibling;
}
}
function insertAdjacent(parent,newEl,refEl,before) {
parent.insertBefore(newEl,before ? refEl : refEl.nextSibling);
}