我有contenteditable div,需要能够将文本打包/解包到其他标签,如<code>
等等。
包装它们不是问题,而是解开所选文本,就像有<b>hello </b><code>world</code>
并且我只需要打开中间的字母(orl)时,似乎没有简单的方法来检测所选文本位于<code>
标记内或否。因此,虽然document.execCommand("bold")
完全使用<b>
和<i>
标记完成此包装/展开作业,但除了b,i,u之外,还有其他方法可以做同样的事吗吗?
答案 0 :(得分:0)
修改contenteditable div并非易事。你问的是可能的,但是这个话题太大了,并且在这里没有一些例子可以回答。
然而,之前有许多现成的库(例如CKEditor)。它们非常复杂,但也非常灵活。开箱即用,它们可能比你需要的要多得多,但是它们可以进行配置,以便您不需要的功能可以被禁用,并且它们有一个API,允许您在需要时从外部控制它们。
答案 1 :(得分:0)
因此,经过较长时间寻找解决方案并找不到任何东西,我决定尝试自己编写,所以如果有人发现这件作品有用,我会很高兴的。 我不知道它在IE或Safari上是如何执行的,并且肯定它不是最有效的方法,但是对于大多数浏览器它应该完成这项工作。
<!doctype html>
<html>
<head>
<title>Wrap</title>
<meta charset="utf-8">
</head>
<body>
<script>
function traverseParentCE(el){
var parent = el.parentElement;
if(!parent || (el && el.contentEditable=="true")) return el;
while(parent && parent.contentEditable!="true"){
parent = parent.parentElement;
}
return parent;
}
function finishWrap(el, innHtml, marker, wrapper){
el.innerHTML = innHtml.replace("<"+marker+">","").replace("</"+marker+">","");
var node = el.getElementsByTagName(wrapper)[0];
var range = document.createRange();
range.setStart(node, 0);
range.setEnd(node, 1);
var sel = document.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
function wrap(tag){
var marker = "marker";
var wrapper = "inncnt";
var ae = document.activeElement;
if(ae.contentEditable!="true") return;
var sel = document.getSelection();
var range = sel.getRangeAt(0);
var el = document.createElement(marker);
el.appendChild(range.cloneContents());
range.deleteContents();
range.insertNode(el);
var innHtml = el.innerHTML;
var count = 0;
while(true){ // I know right, this kind of replacing is horrible, but RegExp somehow didn't work for me
var pos = innHtml.indexOf("<"+tag+">");
if(pos==-1) break;
innHtml = innHtml.replace("<"+tag+">","").replace("</"+tag+">","");
count++;
}
innHtml.replace("<"+wrapper+">","").replace("</"+wrapper+">","");
el.innerHTML = "<"+wrapper+">" + innHtml + "</"+wrapper+">";
var container = traverseParentCE(range.commonAncestorContainer);
innHtml = container.innerHTML;
if(count>0){
return finishWrap(container, innHtml, marker, wrapper);
}
var pos = innHtml.indexOf("<"+marker+">");
var contentBefore = innHtml.substr(0, pos);
var lastStarting = contentBefore.indexOf("<"+tag+">");
var lastEnding = contentBefore.indexOf("</"+tag+">");
var wrap = false;
if(lastStarting == -1) wrap = true;
else if(lastStarting < lastEnding) wrap = true;
if(wrap) innHtml = innHtml.replace(marker, tag).replace(marker, tag);
else innHtml = innHtml.replace(marker, "/"+tag).replace("/"+marker,tag);
var doublet = "<"+tag+"></"+tag+">";
while(true){
var pos = innHtml.indexOf(doublet);
if(pos==-1) break;
innHtml = innHtml.replace(doublet, "");
}
return finishWrap(container, innHtml, marker, wrapper);
}
</script>
<button onmousedown="wrap('b'); return false;" onmouseup="return false;" onclick="return false;">B</button>
<button onmousedown="wrap('i'); return false;" onmouseup="return false;" onclick="return false;">I</button>
<button onmousedown="wrap('code'); return false;" onmouseup="return false;" onclick="return false;">Code</button>
<div style="width: 800px; height: 300px; background-color: yellow" contenteditable="true" id="out">
Hello <b>World</b>! This <code>is some</code> sentence.
</div>
</body>
</html>