execCommand标题不起作用

时间:2017-11-09 22:58:26

标签: javascript html html5 rich-text-editor execcommand

正如标题所解释的那样,由于某种原因document.execCommand('heading', false, 'h1')(或任何其他标题大小)不起作用。但是,'bold''link'等其他命令也可以正常工作。

我正在关注caniuse并且似​​乎全面支持,而“0已知问题。”

以下是我正在使用的代码。值得注意的是,我尝试嵌入一个演示甚至创建一个codepen,但由于某些原因,这两个命令都没有。

const formatToolClass = document.getElementsByClassName('format-tool')

const preventDefault = (e) => e.preventDefault()

const applyStyle = function(){
  document.designMode = 'on'
  document.execCommand('heading', false, 'h1') // does not work
  document.execCommand('bold', false, null) // will work
  document.designMode = 'off'
}

for (let i = 0; i < formatToolClass.length; i++){
  formatToolClass[i].addEventListener('mousedown', preventDefault)
  formatToolClass[i].addEventListener('click', applyStyle)
}

知道发生了什么事吗?

P.S。下面是HTML和CSS,以防你想在浏览器中搞砸它。

<!DOCTYPE html>
  <head>
    <title>Is required and cannot be empty.</title>
    <meta charset="UTF-8">\
    <link rel="stylesheet" href="css/write.css">
  </head>
  <body>
    <div id="controls">
      <div class="controls format-tool" id="controls-embolden" data-xcom="bold">Embolden</div>
      <div class="controls format-tool" id="controls-italicize" data-xcom="italic">Italicize</div>
      <div class="controls format-tool" id="controls-heading" data-xcom="heading">Heading</div> <!---->
      <div class="controls format-tool" id="controls-link" data-xcom="createLink">Link</div> <!---->
      <div class="controls format-tool" id="controls-list" data-xcom="insertUnorderedList">List</div>
      <div class="controls format-tool" id="controls-image" data-xcom="insertImage">Image</div> <!---->
      <div class="controls" id="controls-shortcuts">Shortcuts</div>
      <div class="controls" id="controls-save">Save</div>
      <div class="controls" id="controls-publish">Publish</div>
    </div>
    <div id="user-input" contenteditable="true">
      By portraying me in a sexual way to attendees, this would have opened the door to additional harassment, and added yet another hurdle I’d have to overcome in order to be perceived as a competent professional. The fact that nowhere along the way did ReactiveConf organizers recognize how this gift could actually be harmful, to me, demonstrated a complete lack of empathy for women in tech. That’s not an organization I want to associate myself or my employer, Meteor Development Group (MDG), with.

      Not only is the photo itself problematic, but also the fact that ReactiveConf never asked for my consent. I was never informed that ReactiveConf was planning on altering my photo for the event, nor did I see the superhero picture until after day one of the conference had ended. None of the organizers explicitly asked for my permission to display the picture on the big screen. Had I presented my talk on day 1, I would have been completely blindsided as I walked on stage, which is what happened to a colleague of mine who was also unhappy with his picture.

      Speaking at a conference is already a monumental investment of mental, emotional, and physical effort, right up until the plane ride home. The will to continue investing any more energy into an event whose organizers had showed so little consideration for their speakers vanished as soon as I received the gift. After consulting with trusted members of my team, I decided to withdraw and leave the situation immediately.

      By portraying me in a sexual way to attendees, this would have opened the door to additional harassment, and added yet another hurdle I’d have to overcome in order to be perceived as a competent professional. The fact that nowhere along the way did ReactiveConf organizers recognize how this gift could actually be harmful, to me, demonstrated a complete lack of empathy for women in tech. That’s not an organization I want to associate myself or my employer, Meteor Development Group (MDG), with.
    </div>
    <script src="js/write.js"></script>
  </body>
</html>


body {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  margin: 0;
}

#controls {
  width: 100%;
  height: 10%;
  display: flex;
  justify-content: space-around;
box-sizing:border-box;
border:solid red 1px;
}

.controls {
  font-size: 1.5vmin;
  display: flex;
  justify-content: center;
  align-items: flex-end;
box-sizing:border-box;
border:solid orange 1px;
}

#user-input {
  width: 80%;
  height: 90%;
  max-width: 1440px;
  padding: 1.25%;
  overflow-y: visible;
  overflow-x: hidden;
  font-family: arial;
  font-size: 3vmin;
  color: #000;
box-sizing:border-box;
border:solid black 1px;
}

1 个答案:

答案 0 :(得分:2)

你做出了错误的假设。 caniuse网站声明execCommand支持没有问题,这是正确的,但这并不意味着支持所有命令。事实上,caniuse page在Notes部分有一个注释:

  

要确定支持哪些命令,请参阅Document.queryCommandSupported()

如果您选中“标题”,则会在Chrome中看到它不受支持:

console.log(document.queryCommandSupported("heading"))

IE也不支持。 Firefox声明它支持它,但它可能或可能不是你期望的方式:不是将标题样式仅应用于所选文本,而是将其应用于整个块(就像“formatBlock”一样有意义标题是块级元素,而不是粗体/斜体的内联元素。

如果这对您有用,则有一种使用“formatBlock”的解决方法,因为它受Chrome,Firefox和IE支持:

console.log(document.queryCommandSupported("formatBlock"))

在这种情况下,您要做的是将formatBlock设置为您想要的标题(看起来像h1)并且它将起作用:

const formatToolClass = document.getElementsByClassName('format-tool')

const preventDefault = (e) => e.preventDefault()

const applyStyle = function() {
  document.designMode = 'on'
  document.execCommand('formatBlock', false, 'h1')
  document.designMode = 'off'
}

for (let i = 0; i < formatToolClass.length; i++) {
  formatToolClass[i].addEventListener('mousedown', preventDefault)
  formatToolClass[i].addEventListener('click', applyStyle)
}
body {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  margin: 0;
}

#controls {
  width: 100%;
  height: 10%;
  display: flex;
  justify-content: space-around;
  box-sizing: border-box;
  border: solid red 1px;
}

.controls {
  font-size: 1.5vmin;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  box-sizing: border-box;
  border: solid orange 1px;
}

#user-input {
  width: 80%;
  height: 90%;
  max-width: 1440px;
  padding: 1.25%;
  overflow-y: visible;
  overflow-x: hidden;
  font-family: arial;
  font-size: 3vmin;
  color: #000;
  box-sizing: border-box;
  border: solid black 1px;
}
<div id="controls">
  <div class="controls format-tool" id="controls-embolden" data-xcom="bold">Embolden</div>
  <div class="controls format-tool" id="controls-italicize" data-xcom="italic">Italicize</div>
  <div class="controls format-tool" id="controls-heading" data-xcom="heading">Heading</div>
  <!---->
  <div class="controls format-tool" id="controls-link" data-xcom="createLink">Link</div>
  <!---->
  <div class="controls format-tool" id="controls-list" data-xcom="insertUnorderedList">List</div>
  <div class="controls format-tool" id="controls-image" data-xcom="insertImage">Image</div>
  <!---->
  <div class="controls" id="controls-shortcuts">Shortcuts</div>
  <div class="controls" id="controls-save">Save</div>
  <div class="controls" id="controls-publish">Publish</div>
</div>
<div id="user-input" contenteditable="true">
  By portraying me in a sexual way to attendees, this would have opened the door to additional harassment, and added yet another hurdle I’d have to overcome in order to be perceived as a competent professional. The fact that nowhere along the way did ReactiveConf
  organizers recognize how this gift could actually be harmful, to me, demonstrated a complete lack of empathy for women in tech. That’s not an organization I want to associate myself or my employer, Meteor Development Group (MDG), with. Not only is the
  photo itself problematic, but also the fact that ReactiveConf never asked for my consent. I was never informed that ReactiveConf was planning on altering my photo for the event, nor did I see the superhero picture until after day one of the conference
  had ended. None of the organizers explicitly asked for my permission to display the picture on the big screen. Had I presented my talk on day 1, I would have been completely blindsided as I walked on stage, which is what happened to a colleague of mine
  who was also unhappy with his picture. Speaking at a conference is already a monumental investment of mental, emotional, and physical effort, right up until the plane ride home. The will to continue investing any more energy into an event whose organizers
  had showed so little consideration for their speakers vanished as soon as I received the gift. After consulting with trusted members of my team, I decided to withdraw and leave the situation immediately. By portraying me in a sexual way to attendees,
  this would have opened the door to additional harassment, and added yet another hurdle I’d have to overcome in order to be perceived as a competent professional. The fact that nowhere along the way did ReactiveConf organizers recognize how this gift
  could actually be harmful, to me, demonstrated a complete lack of empathy for women in tech. That’s not an organization I want to associate myself or my employer, Meteor Development Group (MDG), with.
</div>

现在,如果您只想要选择的文本是H1,那么您可以做一个技巧:使用“insertHTML”在所选文本周围添加标记<h1></h1>(它可以在Edge上运行,但不适用于Internet Explorer)。像这样:

const formatToolClass = document.getElementsByClassName('format-tool')

const preventDefault = (e) => e.preventDefault()

const applyStyle = function() {
  document.designMode = 'on'
  document.execCommand('insertHTML', false, '<h1>' + window.getSelection().toString() + '</h1>')
  document.designMode = 'off'
}

for (let i = 0; i < formatToolClass.length; i++) {
  formatToolClass[i].addEventListener('mousedown', preventDefault)
  formatToolClass[i].addEventListener('click', applyStyle)
}
body {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  margin: 0;
}

#controls {
  width: 100%;
  height: 10%;
  display: flex;
  justify-content: space-around;
  box-sizing: border-box;
  border: solid red 1px;
}

.controls {
  font-size: 1.5vmin;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  box-sizing: border-box;
  border: solid orange 1px;
}

#user-input {
  width: 80%;
  height: 90%;
  max-width: 1440px;
  padding: 1.25%;
  overflow-y: visible;
  overflow-x: hidden;
  font-family: arial;
  font-size: 3vmin;
  color: #000;
  box-sizing: border-box;
  border: solid black 1px;
}
<div id="controls">
  <div class="controls format-tool" id="controls-embolden" data-xcom="bold">Embolden</div>
  <div class="controls format-tool" id="controls-italicize" data-xcom="italic">Italicize</div>
  <div class="controls format-tool" id="controls-heading" data-xcom="heading">Heading</div>
  <!---->
  <div class="controls format-tool" id="controls-link" data-xcom="createLink">Link</div>
  <!---->
  <div class="controls format-tool" id="controls-list" data-xcom="insertUnorderedList">List</div>
  <div class="controls format-tool" id="controls-image" data-xcom="insertImage">Image</div>
  <!---->
  <div class="controls" id="controls-shortcuts">Shortcuts</div>
  <div class="controls" id="controls-save">Save</div>
  <div class="controls" id="controls-publish">Publish</div>
</div>
<div id="user-input" contenteditable="true">
  By portraying me in a sexual way to attendees, this would have opened the door to additional harassment, and added yet another hurdle I’d have to overcome in order to be perceived as a competent professional. The fact that nowhere along the way did ReactiveConf
  organizers recognize how this gift could actually be harmful, to me, demonstrated a complete lack of empathy for women in tech. That’s not an organization I want to associate myself or my employer, Meteor Development Group (MDG), with. Not only is the
  photo itself problematic, but also the fact that ReactiveConf never asked for my consent. I was never informed that ReactiveConf was planning on altering my photo for the event, nor did I see the superhero picture until after day one of the conference
  had ended. None of the organizers explicitly asked for my permission to display the picture on the big screen. Had I presented my talk on day 1, I would have been completely blindsided as I walked on stage, which is what happened to a colleague of mine
  who was also unhappy with his picture. Speaking at a conference is already a monumental investment of mental, emotional, and physical effort, right up until the plane ride home. The will to continue investing any more energy into an event whose organizers
  had showed so little consideration for their speakers vanished as soon as I received the gift. After consulting with trusted members of my team, I decided to withdraw and leave the situation immediately. By portraying me in a sexual way to attendees,
  this would have opened the door to additional harassment, and added yet another hurdle I’d have to overcome in order to be perceived as a competent professional. The fact that nowhere along the way did ReactiveConf organizers recognize how this gift
  could actually be harmful, to me, demonstrated a complete lack of empathy for women in tech. That’s not an organization I want to associate myself or my employer, Meteor Development Group (MDG), with.
</div>