2017-07-31 22 views
3

确实我有CONTENTEDITABLE股利和需要能够来包装/解包文本到其他标签,如<code>等。 结束语他们不是问题,而展开选定的文本,当有<b>hello </b><code>world</code>一样,我需要则只打开字母中间(ORL),似乎没有要简单的方法检测是否选定的文本里面<code>标签或没有。因此,尽管document.execCommand("bold")完美地做到这一点的包装/展开工作与<b><i>标签,有没有办法做同样与除B之外的标签,I,U?切换就像将execCommand任何粗体标签用b

回答

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> 
0

修改contenteditable divs不是一件简单的事情。你问的是可能的,但是这个话题太大了,不能在这里举几个例子来回答。

但是现在有很多现成的库已经做到了这一点(例如CKEditor),它们非常复杂,但也非常灵活,开箱即可,它们可能比你需要的多得多,但它们可以是配置,以便拥有你不需要可禁用,他们有一个API,允许你从外面控制他们,如果需要的话。