Contenteditable中的HTML元素?

时间:2017-01-02 22:01:25

标签: javascript html

我有一个contenteditable标记,我希望我的用户能够在其中输入代码。但是,当我输入contenteditable标记时,我的代码显示为文本而不是实际元素。有没有办法让用户在一个可疑的框中创建一个完整的,有效的HTML元素?我知道客户端可以使用javascript插入代码,但是对于无法访问javascript的用户呢?用户怎样才能在一个可疑的盒子里面获得按钮等代码?



<p contenteditable="true">Try typing code in here as user, code will only be text...</p>
&#13;
&#13;
&#13;

如果没有JQUERY,有没有javascript方法可以实现这一目标?

修改

我花了很长时间在Google上搜索答案,但没有提出任何问题。我在这一点上得到的最佳解决方案是@ Dekel对CKEditor的评论。如果有另一种解决方案,我想听听。如果没有,我会坚持使用CKEditor。我没有太多时间,所以我需要快速解决方案。

更多编辑= D

我最近通过查看@ Brandon的.replace答案(仅适用于客户端编码,而不是用户编码)并修改它以使用用户编码来开发我自己的问题答案。

3 个答案:

答案 0 :(得分:3)

这不是很好,但如果您只想添加HTML,可以使它工作。否则,内联编辑器可能效果最佳。

var el = document.querySelector('p')
el.addEventListener('blur', function() {
  var map = {amp: '&', lt: '<', gt: '>', quot: '"', '#039': "'"}
  var html = this.innerHTML.replace(/&([^;]+);/g, (m, c) => map[c]);
  this.innerHTML = html;
});
<p contenteditable="true">Try typing <b>code</b> in here as user, code will only be text...</p>

答案 1 :(得分:1)

您无法插入代码,但可以使用JS插入DOMElements。不需要jQuery。

var element=document.createElement("button");
element.innerHTML="Hello";
document.getElementById("yourContentEditable").append(element);

这个想法是有一个按钮来提示代码并插入它。像这样:

(这是非常丑陋和错误,但它只是我刚刚写的一个例子)

&#13;
&#13;
var editorSelection=null;

function openCodePopup() {
  //Store cursor position before editor loses focus
  editorSelection=getEditorSelection();
  
  //Open the popup
  document.querySelector("#codePopup").style.display="block";
  var ta=document.querySelector("#userCode");
  ta.value="";
  ta.focus();
}

function closeCodePopup() {
  document.querySelector("#codePopup").style.display="none";
}

function insertCode() {
  var code=document.querySelector("#userCode").value;
  closeCodePopup();
  if(code=="") return;
  insertIntoEditor(html2dom(code));
}

function getEditorSelection() {
  //TODO make crossbrowser
  //TODO (VERY IMPORTANT) validate if selection is whitin the editor
  var sel=window.getSelection();
  if(sel.rangeCount) return sel.getRangeAt(0);
  return null;
}

function insertIntoEditor(dom) {
  if(editorSelection) {
    editorSelection.deleteContents();
    editorSelection.insertNode(dom);
  } else {
    //Insert at the end
    document.querySelector("#editor").append(dom);
  }
}

function html2dom(code) {
  //A lazy way to convert html to DOMElements, you can use jQuery or any other 
  var foo=document.createElement('div'); //or you could use an inline element
  foo.contentEditable=false;
  foo.innerHTML=code;
  return foo;
}
&#13;
#editor {
  height: 180px;
  overflow: auto;
  border: 1px solid #ccc;
}
#toolbar {
  position: relative;
}
#codePopup {
  position: absolute;
  left: 10px;
  top: 15px;
  background-color: #fff;
  border: 1px solid #ccc;
  padding: 5px;
  display: none;
}
#userCode {
  display: block;
  width: 200px;
  height: 100px;
}
&#13;
<div id="toolbar">
  <button onclick="openCodePopup()">&lt;/&gt;</button>
  <div id="codePopup">
    <textarea id="userCode" placeholder="Type code here"></textarea>
    <button onclick="insertCode()">Ok</button>
    <button onclick="closeCodePopup()">Cancel</button>
  </div>
</div>
<div contenteditable="true" id="editor"></div>
&#13;
&#13;
&#13;

使用相同的想法,您可以创建其他选项来转换元素(例如,text-&gt; link等)。

答案 2 :(得分:1)

这个答案类似于@Brandon的想法,但更为简单。

https://jsfiddle.net/azopqLe4/

<iframe width="100%" height="300" src="//jsfiddle.net/azopqLe4/embedded/js,html,result/dark/" allowfullscreen="allowfullscreen" frameborder="0"></iframe>

function convertit() {
	var convet = document.getElementById("convet");
  var text = convet.innerHTML;
  var newtext;

  newtext = text.replace(/&lt;/g, "<").replace(/&gt;/g, ">");
  
  convet.innerHTML = newtext;
}
//this version runs onrightclick =D
<p contenteditable="true" oncontextmenu="convertit();" id="convet">
Type some code here, then right-click... =D
</p>
在第二个代码段中,我输入<b>Test</b>,右键单击它,它变为测试!我的答案通过简单的数组替换方法来解决,尽管一直保持右键单击是令人沮丧和浪费时间的。要防止实际的上下文菜单弹出,只需添加.preventDefault()。

相关问题