在输入时替换contenteditable框中的内容?

时间:2017-01-26 23:41:23

标签: javascript html

我有一个我想要用户输入的contenteditable div。当用户在onkeyup框内输入时,我激活了一个改变某些字符颜色的函数:

var lTags = fixedCode.innerHTML.replace(/&lt;/gi, "<span style='color:gold;'>&lt;</span>");
var rTags = lTags.replace(/&gt;/gi, "<span style='color:gold'>&gt;</span>");
fixedCode.innerHTML = rTags;

这段代码的作用是每个&lt;标志和每一个&gt;签字并将其变成金色。但是,当我这样做时,我再也无法在单词中输入单词,因为每次按下某个键时该框都会自动刷新。

&#13;
&#13;
function checkIt(code) {
   var fixedCode = document.getElementById(code);
   var lTags = fixedCode.innerHTML.replace(/&lt;/gi, "<span style='color:gold;'>&lt;</span>");
   var rTags = lTags.replace(/&gt;/gi, "<span style='color:gold'>&gt;</span>");
   fixedCode.innerHTML = rTags;
}
&#13;
<div id="box" contenteditable="true" onkeyup="checkIt(this.id);">See for yourself</div>
&#13;
&#13;
&#13;

要亲眼看看,请尝试在框中输入任何HTML标记。 首先,为什么它会更改标记左<的颜色,而不是标记>的右边部分?如何在不删除变色的东西的情况下实际输入框内。我见过类似的问题,但答案是Jquery。 我不想使用JQUERY!

3 个答案:

答案 0 :(得分:4)

目前可以在Chrome浏览器中使用 ...但是找出一种方法可以让插入符号显示,即使文本是透明的,你也可以去。

所以我太懒了 hardcore-JS 而且弹出的一个想法是使用

  • 两个覆盖DIV。
  • 重叠的满意的透明文字(但可见的插入符号)!
  • 底层DIV是展示你更换的彩色内容的那个:

关于这种技术的一个好的方面是你总是保持(在可信的DIV中)要更换的内容的不变版本!
不太好的一面是,在每次击键时,你都会再次解析相同的内容 - 而且随着它变大,可能会成为性能杀手。

function highLite(el) {
  el.previousSibling.innerHTML = el.innerHTML
     .replace(/&lt;/gi, "<span class='bck_angle'>&lt;</span>")
     .replace(/&gt;/gi, "<span class='bck_angle'>&gt;</span>");
}
body{margin:0; font:14px/1 sans-serif;}

.highLite{
  border:1px solid #888;
  position:relative;
}

/* THE ONE WITH COLORS */
.highLite > div:nth-child(1) {
  padding:16px;
  position:absolute;
  top:0; left:0;
  width:100%; height:100%;
}

/* THE OVERLAYING CONTENTEDITABLE WITH TRANSPARENT TEXT */
.highLite > div:nth-child(2) {
  padding:16px;
  position:relative;
  -webkit-text-fill-color: transparent; /* Chrome: make text transparent */
  color:black;                          /* But keep caret black */
}

.bck_angle{color:gold;}
Try to type some angle brackets &lt; &gt;
<div class="highLite">
  <div>Type here</div><div contenteditable oninput="highLite(this);">Type here</div>
</div>

我留给读者的一个简单的JS-TODO - 当我们编辑的DIV收到滚动条时,相应地更新兄弟DIV的滚动位置。

答案 1 :(得分:1)

从不。解析。 HTML。有了。正则表达式。

只需遍历DOM并在必要时拆分节点。

function wrap(textNode, str, cName) {
  var pos = textNode.nodeValue.indexOf(str);
  if (pos < 0) return false;
  var newNode = textNode.splitText(pos);
  var span = document.createElement('span');
  span.className = cName;
  textNode.parentNode.insertBefore(span, newNode);
  newNode.splitText(str.length);
  span.appendChild(newNode);
  return true;
}
function checkIt() {
  for (var i=0; i<this.childNodes.length; ++i) {
    var node = this.childNodes[i];
    if (node.nodeType === Node.TEXT_NODE) {
      if (wrap(node, '<', 'less-than')) ++i;
      if (wrap(node, '>', 'greater-than')) ++i;
    } else if (node.nodeType === Node.ELEMENT_NODE) {
      checkIt.call(node);
    }
  }
}
document.getElementById('box').addEventListener('input', checkIt);
.less-than, .greater-than {
  color: gold;
}
<div id="box" contenteditable="true">See for yourself</div>

答案 2 :(得分:-2)

看看这个小提琴 - 这解释了最好的方式     http://jsfiddle.net/Y8ySy/305/

$("div").prop("contentEditable", true).keypress(function(){
    var chars = $(this).text().split("");
    $("#hidden").val($(this).text());
    this.innerHTML = "";
    $.each(chars, function(){
        $("<span>").text(this).css({
            color: "#"+(Math.random()*16777215|0).toString(16)
        }).appendTo("div");
    });
});

可以轻松转换为简单的java

<强>更新 它不应该难以转向你想要的,但它 事实证明,你总是从Field的开头开始,这不会使它成为可用的