美文网首页
[译]HTML进阶之HTML5 Content Editable

[译]HTML进阶之HTML5 Content Editable

作者: 趁你还年轻233 | 来源:发表于2017-11-06 11:05 被阅读270次

    原文:https://developer.mozilla.org/zh-CN/docs/Web/Guide/HTML/Content_Editable

    概述

    在HTML中,任何元素都可以编辑。通过使用一些JavaScript事件处理程序,您可以将您的网页转换成一个完整而快速的富文本编辑器。本文提供了有关此功能的一些信息。

    在HTML5中,任何元素都是可编辑的. 这项特性在很久以前就已经被提出,不过直到现在才被WHATWG (当前HTML标准)组织标准化. 通过一些javascript事件处理函数,你可以把自己的网页转换成完整快速的富文本编辑器.

    它是如何工作的?

    只要将HTML元素的contenteditable属性值设置 true, 就可以激活编辑模式,那么该元素范围中的内容都是可编辑的.

    例子
    1. 这是一个简单的例子,创建一个<div>元素,用户可以编辑其内容。
    <div contenteditable="true">
          This text can be edited by the user.
    </div>
    
    1. 另一个使用LocalStorage技术配合的content editable例子演示

    可执行命令

    当一个HTML标签的contenteditable属性设置为true时,document.execCommand() 方法就生效了。这可以让你运行命令去操作可编辑区域的内容。大多数命令会影响选择的文档,例如,应用一个文本样式(粗体,斜体等等),或者当插入新标签时(例如添加一个链接),或者影响了一整行(例如文本缩进)。当使用contentEditable时,调用execCommand()方法将影响到当前的激活的可编辑元素。

    标签生成的差异

    一直以来,在不同的浏览器使用contenteditable效果不是很好,因为不同浏览器生成标签的规则不一样。例如,即使是像“输入即输出”来在一个可编辑标签内创建一个新行,在主流浏览器中都会有很多大不同。(Firefox插入
    标签,IE/Opera插入<p>,Chrome和Safari插入<div>

    幸运的是,在现代浏览器中,插入标签是一致的。例如在Firefox 55中,将之前的
    标签,改为<div>标签,与Chrome以及现代的Opera, Edge, and Safari一致。

    在上面的例子中可以试一下。

    提醒:老版本的IE,一直是在用<p>,没有更新成div。

    如果你想使用段落分离器,上面提及的浏览器均支持document.execCommand,提供了一个"DefaultPragraphSeparator"接口,允许我们来改变默认插入的标签,例如,想用<p>来分段:
    document.execCommand("DefaultParagraphSeparator", false, "p");

    安全性

    由于安全原因,Firefox不允许使用剪贴板的copy ,paste等等默认功能。你可以通过使用在firefox浏览器地址栏中输入about:config,从而去启用他们。
    user_pref("capability.policy.policynames", "allowclipboard");
    user_pref("capability.policy.allowclipboard.sites", "https://www.mozilla.org");
    user_pref("capability.policy.allowclipboard.Clipboard.cutcopy", "allAccess");
    user_pref("capability.policy.allowclipboard.Clipboard.paste", "allAccess");

    例子:一个简单但是完整的富文本编辑器

    <!doctype html>
    <html>
    <head>
    <title>Rich Text Editor</title>
    <script type="text/javascript">
    var oDoc, sDefTxt;
    
    function initDoc() {
      oDoc = document.getElementById("textBox");
      sDefTxt = oDoc.innerHTML;
      if (document.compForm.switchMode.checked) { setDocMode(true); }
    }
    
    function formatDoc(sCmd, sValue) {
      if (validateMode()) { document.execCommand(sCmd, false, sValue); oDoc.focus(); }
    }
    
    function validateMode() {
      if (!document.compForm.switchMode.checked) { return true ; }
      alert("Uncheck \"Show HTML\".");
      oDoc.focus();
      return false;
    }
    
    function setDocMode(bToSource) {
      var oContent;
      if (bToSource) {
        oContent = document.createTextNode(oDoc.innerHTML);
        oDoc.innerHTML = "";
        var oPre = document.createElement("pre");
        oDoc.contentEditable = false;
        oPre.id = "sourceText";
        oPre.contentEditable = true;
        oPre.appendChild(oContent);
        oDoc.appendChild(oPre);
        document.execCommand("defaultParagraphSeparator", false, "div");
      } else {
        if (document.all) {
          oDoc.innerHTML = oDoc.innerText;
        } else {
          oContent = document.createRange();
          oContent.selectNodeContents(oDoc.firstChild);
          oDoc.innerHTML = oContent.toString();
        }
        oDoc.contentEditable = true;
      }
      oDoc.focus();
    }
    
    function printDoc() {
      if (!validateMode()) { return; }
      var oPrntWin = window.open("","_blank","width=450,height=470,left=400,top=100,menubar=yes,toolbar=no,location=no,scrollbars=yes");
      oPrntWin.document.open();
      oPrntWin.document.write("<!doctype html><html><head><title>Print<\/title><\/head><body onload=\"print();\">" + oDoc.innerHTML + "<\/body><\/html>");
      oPrntWin.document.close();
    }
    </script>
    <style type="text/css">
    .intLink { cursor: pointer; }
    img.intLink { border: 0; }
    #toolBar1 select { font-size:10px; }
    #textBox {
      width: 540px;
      height: 200px;
      border: 1px #000000 solid;
      padding: 12px;
      overflow: scroll;
    }
    #textBox #sourceText {
      padding: 0;
      margin: 0;
      min-width: 498px;
      min-height: 200px;
    }
    #editMode label { cursor: pointer; }
    </style>
    </head>
    <body onload="initDoc();">
    <form name="compForm" method="post" action="sample.php" onsubmit="if(validateMode()){this.myDoc.value=oDoc.innerHTML;return true;}return false;">
    <input type="hidden" name="myDoc">
    <div id="toolBar1">
    <select onchange="formatDoc('formatblock',this[this.selectedIndex].value);this.selectedIndex=0;">
    <option selected>- formatting -</option>
    <option value="h1">Title 1 &lt;h1&gt;</option>
    <option value="h2">Title 2 &lt;h2&gt;</option>
    <option value="h3">Title 3 &lt;h3&gt;</option>
    <option value="h4">Title 4 &lt;h4&gt;</option>
    <option value="h5">Title 5 &lt;h5&gt;</option>
    <option value="h6">Subtitle &lt;h6&gt;</option>
    <option value="p">Paragraph &lt;p&gt;</option>
    <option value="pre">Preformatted &lt;pre&gt;</option>
    </select>
    <select onchange="formatDoc('fontname',this[this.selectedIndex].value);this.selectedIndex=0;">
    <option class="heading" selected>- font -</option>
    <option>Arial</option>
    <option>Arial Black</option>
    <option>Courier New</option>
    <option>Times New Roman</option>
    </select>
    <select onchange="formatDoc('fontsize',this[this.selectedIndex].value);this.selectedIndex=0;">
    <option class="heading" selected>- size -</option>
    <option value="1">Very small</option>
    <option value="2">A bit small</option>
    <option value="3">Normal</option>
    <option value="4">Medium-large</option>
    <option value="5">Big</option>
    <option value="6">Very big</option>
    <option value="7">Maximum</option>
    </select>
    <select onchange="formatDoc('forecolor',this[this.selectedIndex].value);this.selectedIndex=0;">
    <option class="heading" selected>- color -</option>
    <option value="red">Red</option>
    <option value="blue">Blue</option>
    <option value="green">Green</option>
    <option value="black">Black</option>
    </select>
    <select onchange="formatDoc('backcolor',this[this.selectedIndex].value);this.selectedIndex=0;">
    <option class="heading" selected>- background -</option>
    <option value="red">Red</option>
    <option value="green">Green</option>
    <option value="black">Black</option>
    </select>
    </div>
    <div id="toolBar2">
    <img class="intLink" title="Clean" onclick="if(validateMode()&&confirm('Are you sure?')){oDoc.innerHTML=sDefTxt};" src="data:image/gif;base64,R0lGODlhFgAWAIQbAD04KTRLYzFRjlldZl9vj1dusY14WYODhpWIbbSVFY6O7IOXw5qbms+wUbCztca0ccS4kdDQjdTLtMrL1O3YitHa7OPcsd/f4PfvrvDv8Pv5xv///////////////////yH5BAEKAB8ALAAAAAAWABYAAAV84CeOZGmeaKqubMteyzK547QoBcFWTm/jgsHq4rhMLoxFIehQQSAWR+Z4IAyaJ0kEgtFoLIzLwRE4oCQWrxoTOTAIhMCZ0tVgMBQKZHAYyFEWEV14eQ8IflhnEHmFDQkAiSkQCI2PDC4QBg+OAJc0ewadNCOgo6anqKkoIQA7" />
    <img class="intLink" title="Print" onclick="printDoc();" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9oEBxcZFmGboiwAAAAIdEVYdENvbW1lbnQA9syWvwAAAuFJREFUOMvtlUtsjFEUx//n3nn0YdpBh1abRpt4LFqtqkc3jRKkNEIsiIRIBBEhJJpKlIVo4m1RRMKKjQiRMJRUqUdKPT71qpIpiRKPaqdF55tv5vvusZjQTjOlseUkd3Xu/3dPzusC/22wtu2wRn+jG5So/OCDh8ycMJDflehMlkJkVK7KUYN+ufzA/RttH76zaVocDptRxzQtNi3mRWuPc+6cKtlXZ/sddP2uu9uXlmYXZ6Qm8v4Tz8lhF1H+zDQXt7S8oLMXtbF4e8QaFHjj3kbP2MzkktHpiTjp9VH6iHiA+whtAsX5brpwueMGdONdf/2A4M7ukDs1JW662+XkqTkeUoqjKtOjm2h53YFL15pSJ04Zc94wdtibr26fXlC2mzRvBccEbz2kiRFD414tKMlEZbVGT33+qCoHgha81SWYsew0r1uzfNylmtpx80pngQQ91LwVk2JGvGnfvZG6YcYRAT16GFtW5kKKfo1EQLtfh5Q2etT0BIWF+aitq4fDbk+ImYo1OxvGF03waFJQvBCkvDffRyEtxQiFFYgAZTHS0zwAGD7fG5TNnYNTp8/FzvGwJOfmgG7GOx0SAKKgQgDMgKBI0NJGMEImpGDk5+WACEwEd0ywblhGUZ4Hw5OdUekRBLT7DTgdEgxACsIznx8zpmWh7k4rkpJcuHDxCul6MDsmmBXDlWCH2+XozSgBnzsNCEE4euYV4pwCpsWYPW0UHDYBKSWu1NYjENDReqtKjwn2+zvtTc1vMSTB/mvev/WEYSlASsLimcOhOBJxw+N3aP/SjefNL5GePZmpu4kG7OPr1+tOfPyUu3BecWYKcwQcDFmwFKAUo90fhKDInBCAmvqnyMgqUEagQwCoHBDc1rjv9pIlD8IbVkz6qYViIBQGTJPx4k0XpIgEZoRN1Da0cij4VfR0ta3WvBXH/rjdCufv6R2zPgPH/e4pxSBCpeatqPrjNiso203/5s/zA171Mv8+w1LOAAAAAElFTkSuQmCC">
    <img class="intLink" title="Undo" onclick="formatDoc('undo');" src="data:image/gif;base64,R0lGODlhFgAWAOMKADljwliE33mOrpGjuYKl8aezxqPD+7/I19DV3NHa7P///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARR8MlJq7046807TkaYeJJBnES4EeUJvIGapWYAC0CsocQ7SDlWJkAkCA6ToMYWIARGQF3mRQVIEjkkSVLIbSfEwhdRIH4fh/DZMICe3/C4nBQBADs=" />
    <img class="intLink" title="Redo" onclick="formatDoc('redo');" src="data:image/gif;base64,R0lGODlhFgAWAMIHAB1ChDljwl9vj1iE34Kl8aPD+7/I1////yH5BAEKAAcALAAAAAAWABYAAANKeLrc/jDKSesyphi7SiEgsVXZEATDICqBVJjpqWZt9NaEDNbQK1wCQsxlYnxMAImhyDoFAElJasRRvAZVRqqQXUy7Cgx4TC6bswkAOw==" />
    <img class="intLink" title="Remove formatting" onclick="formatDoc('removeFormat')" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAd0SU1FB9oECQMCKPI8CIIAAAAIdEVYdENvbW1lbnQA9syWvwAAAuhJREFUOMtjYBgFxAB501ZWBvVaL2nHnlmk6mXCJbF69zU+Hz/9fB5O1lx+bg45qhl8/fYr5it3XrP/YWTUvvvk3VeqGXz70TvbJy8+Wv39+2/Hz19/mGwjZzuTYjALuoBv9jImaXHeyD3H7kU8fPj2ICML8z92dlbtMzdeiG3fco7J08foH1kurkm3E9iw54YvKwuTuom+LPt/BgbWf3//sf37/1/c02cCG1lB8f//f95DZx74MTMzshhoSm6szrQ/a6Ir/Z2RkfEjBxuLYFpDiDi6Af///2ckaHBp7+7wmavP5n76+P2ClrLIYl8H9W36auJCbCxM4szMTJac7Kza////R3H1w2cfWAgafPbqs5g7D95++/P1B4+ECK8tAwMDw/1H7159+/7r7ZcvPz4fOHbzEwMDwx8GBgaGnNatfHZx8zqrJ+4VJBh5CQEGOySEua/v3n7hXmqI8WUGBgYGL3vVG7fuPK3i5GD9/fja7ZsMDAzMG/Ze52mZeSj4yu1XEq/ff7W5dvfVAS1lsXc4Db7z8C3r8p7Qjf///2dnZGxlqJuyr3rPqQd/Hhyu7oSpYWScylDQsd3kzvnH738wMDzj5GBN1VIWW4c3KDon7VOvm7S3paB9u5qsU5/x5KUnlY+eexQbkLNsErK61+++VnAJcfkyMTIwffj0QwZbJDKjcETs1Y8evyd48toz8y/ffzv//vPP4veffxpX77z6l5JewHPu8MqTDAwMDLzyrjb/mZm0JcT5Lj+89+Ybm6zz95oMh7s4XbygN3Sluq4Mj5K8iKMgP4f0////fv77//8nLy+7MCcXmyYDAwODS9jM9tcvPypd35pne3ljdjvj26+H2dhYpuENikgfvQeXNmSl3tqepxXsqhXPyc666s+fv1fMdKR3TK72zpix8nTc7bdfhfkEeVbC9KhbK/9iYWHiErbu6MWbY/7//8/4//9/pgOnH6jGVazvFDRtq2VgiBIZrUTIBgCk+ivHvuEKwAAAAABJRU5ErkJggg==">
    <img class="intLink" title="Bold" onclick="formatDoc('bold');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAInhI+pa+H9mJy0LhdgtrxzDG5WGFVk6aXqyk6Y9kXvKKNuLbb6zgMFADs=" />
    <img class="intLink" title="Italic" onclick="formatDoc('italic');" src="data:image/gif;base64,R0lGODlhFgAWAKEDAAAAAF9vj5WIbf///yH5BAEAAAMALAAAAAAWABYAAAIjnI+py+0Po5x0gXvruEKHrF2BB1YiCWgbMFIYpsbyTNd2UwAAOw==" />
    <img class="intLink" title="Underline" onclick="formatDoc('underline');" src="data:image/gif;base64,R0lGODlhFgAWAKECAAAAAF9vj////////yH5BAEAAAIALAAAAAAWABYAAAIrlI+py+0Po5zUgAsEzvEeL4Ea15EiJJ5PSqJmuwKBEKgxVuXWtun+DwxCCgA7" />
    <img class="intLink" title="Left align" onclick="formatDoc('justifyleft');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAIghI+py+0Po5y02ouz3jL4D4JMGELkGYxo+qzl4nKyXAAAOw==" />
    <img class="intLink" title="Center align" onclick="formatDoc('justifycenter');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAIfhI+py+0Po5y02ouz3jL4D4JOGI7kaZ5Bqn4sycVbAQA7" />
    <img class="intLink" title="Right align" onclick="formatDoc('justifyright');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAIghI+py+0Po5y02ouz3jL4D4JQGDLkGYxouqzl43JyVgAAOw==" />
    <img class="intLink" title="Numbered list" onclick="formatDoc('insertorderedlist');" src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAADljwliE35GjuaezxtHa7P///////yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKSespwjoRFvggCBUBoTFBeq6QIAysQnRHaEOzyaZ07Lu9lUBnC0UGQU1K52s6n5oEADs=" />
    <img class="intLink" title="Dotted list" onclick="formatDoc('insertunorderedlist');" src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAAB1ChF9vj1iE33mOrqezxv///////yH5BAEAAAcALAAAAAAWABYAAAMyeLrc/jDKSesppNhGRlBAKIZRERBbqm6YtnbfMY7lud64UwiuKnigGQliQuWOyKQykgAAOw==" />
    <img class="intLink" title="Quote" onclick="formatDoc('formatblock','blockquote');" src="data:image/gif;base64,R0lGODlhFgAWAIQXAC1NqjFRjkBgmT9nqUJnsk9xrFJ7u2R9qmKBt1iGzHmOrm6Sz4OXw3Odz4Cl2ZSnw6KxyqO306K63bG70bTB0rDI3bvI4P///////////////////////////////////yH5BAEKAB8ALAAAAAAWABYAAAVP4CeOZGmeaKqubEs2CekkErvEI1zZuOgYFlakECEZFi0GgTGKEBATFmJAVXweVOoKEQgABB9IQDCmrLpjETrQQlhHjINrTq/b7/i8fp8PAQA7" />
    <img class="intLink" title="Delete indentation" onclick="formatDoc('outdent');" src="data:image/gif;base64,R0lGODlhFgAWAMIHAAAAADljwliE35GjuaezxtDV3NHa7P///yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKCQG9F2i7u8agQgyK1z2EIBil+TWqEMxhMczsYVJ3e4ahk+sFnAgtxSQDqWw6n5cEADs=" />
    <img class="intLink" title="Add indentation" onclick="formatDoc('indent');" src="data:image/gif;base64,R0lGODlhFgAWAOMIAAAAADljwl9vj1iE35GjuaezxtDV3NHa7P///////////////////////////////yH5BAEAAAgALAAAAAAWABYAAAQ7EMlJq704650B/x8gemMpgugwHJNZXodKsO5oqUOgo5KhBwWESyMQsCRDHu9VOyk5TM9zSpFSr9gsJwIAOw==" />
    <img class="intLink" title="Hyperlink" onclick="var sLnk=prompt('Write the URL here','http:\/\/');if(sLnk&&sLnk!=''&&sLnk!='http://'){formatDoc('createlink',sLnk)}" src="data:image/gif;base64,R0lGODlhFgAWAOMKAB1ChDRLY19vj3mOrpGjuaezxrCztb/I19Ha7Pv8/f///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARY8MlJq7046827/2BYIQVhHg9pEgVGIklyDEUBy/RlE4FQF4dCj2AQXAiJQDCWQCAEBwIioEMQBgSAFhDAGghGi9XgHAhMNoSZgJkJei33UESv2+/4vD4TAQA7" />
    <img class="intLink" title="Cut" onclick="formatDoc('cut');" src="data:image/gif;base64,R0lGODlhFgAWAIQSAB1ChBFNsRJTySJYwjljwkxwl19vj1dusYODhl6MnHmOrpqbmpGjuaezxrCztcDCxL/I18rL1P///////////////////////////////////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAVu4CeOZGmeaKqubDs6TNnEbGNApNG0kbGMi5trwcA9GArXh+FAfBAw5UexUDAQESkRsfhJPwaH4YsEGAAJGisRGAQY7UCC9ZAXBB+74LGCRxIEHwAHdWooDgGJcwpxDisQBQRjIgkDCVlfmZqbmiEAOw==" />
    <img class="intLink" title="Copy" onclick="formatDoc('copy');" src="data:image/gif;base64,R0lGODlhFgAWAIQcAB1ChBFNsTRLYyJYwjljwl9vj1iE31iGzF6MnHWX9HOdz5GjuYCl2YKl8ZOt4qezxqK63aK/9KPD+7DI3b/I17LM/MrL1MLY9NHa7OPs++bx/Pv8/f///////////////yH5BAEAAB8ALAAAAAAWABYAAAWG4CeOZGmeaKqubOum1SQ/kPVOW749BeVSus2CgrCxHptLBbOQxCSNCCaF1GUqwQbBd0JGJAyGJJiobE+LnCaDcXAaEoxhQACgNw0FQx9kP+wmaRgYFBQNeAoGihCAJQsCkJAKOhgXEw8BLQYciooHf5o7EA+kC40qBKkAAAGrpy+wsbKzIiEAOw==" />
    <img class="intLink" title="Paste" onclick="formatDoc('paste');" src="data:image/gif;base64,R0lGODlhFgAWAIQUAD04KTRLY2tXQF9vj414WZWIbXmOrpqbmpGjudClFaezxsa0cb/I1+3YitHa7PrkIPHvbuPs+/fvrvv8/f///////////////////////////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAWN4CeOZGmeaKqubGsusPvBSyFJjVDs6nJLB0khR4AkBCmfsCGBQAoCwjF5gwquVykSFbwZE+AwIBV0GhFog2EwIDchjwRiQo9E2Fx4XD5R+B0DDAEnBXBhBhN2DgwDAQFjJYVhCQYRfgoIDGiQJAWTCQMRiwwMfgicnVcAAAMOaK+bLAOrtLUyt7i5uiUhADs=" />
    </div>
    <div id="textBox" contenteditable="true"><p>Lorem ipsum</p></div>
    <p id="editMode"><input type="checkbox" name="switchMode" id="switchBox" onchange="setDocMode(this.checked);" /> <label for="switchBox">Show HTML</label></p>
    <p><input type="submit" value="Send" /></p>
    </form>
    </body>
    </html>
    Note: if you want to see how to standardize the creation and the insertion
    

    笔记:如果你想了解更多有关富文本编辑器的内容,可以查看 more complete rich-text editor example.

    也可以看看

    • HTMLElement.contentEditable
    • contenteditable全局属性
    • Midas(脚本化的文本编辑组件)
    • caret-color 设置文本插入符号的颜色

    相关文章

      网友评论

          本文标题:[译]HTML进阶之HTML5 Content Editable

          本文链接:https://www.haomeiwen.com/subject/yzokmxtx.html