【问题标题】:Rich Text Editor Not Behaving Correctly富文本编辑器行为不正确
【发布时间】:2016-12-15 20:46:01
【问题描述】:

我正在尝试在文本字段上创建富文本编辑器。为了做到这一点,我正在使用Summernote。我让编辑器按照我想要的方式进行初始化。我真的很希望 airmode 在悬停而不是点击时表现。不过,有一个奇怪的行为是我真正的问题。

Fiddle 所示,用户可以开始在屏幕上的三个编辑器之一中输入内容。但是,只要您输入一个空格,文本就会转到输入字段上方的行。它不会停留在同一条线上。奇怪的是,输入行上方的文本不允许进行丰富的编辑。我正在初始化这样的文本字段:

  var optionEditors = $('.option-editor');
  for (var i=0; i<optionEditors.length; i++) {
    $(optionEditors[i]).summernote({
      airMode: true,
      popover: {
        air: [
          ['font', ['bold', 'underline', 'clear']]
        ]
      }
    });
  }

我错过了什么?一切看起来都是正确的。只是行为似乎是错误的。谢谢。

【问题讨论】:

    标签: javascript summernote


    【解决方案1】:

    Bootstrap plugins depend on jQuery;如果不先加载,它们将失败:

    插件依赖

    一些插件和 CSS 组件依赖于其他插件。如果您单独包含插件,请确保在文档中检查这些依赖项。另请注意,所有插件都依赖于 jQuery(这意味着 jQuery 必须在插件文件之前包含)。请查阅我们的 bower.json 以了解支持的 jQuery 版本。

    The defer attribute 在您的 jQuery 脚本加载标记中导致它加载 您在 onload 事件中调用 addAllElements

    defer

    此布尔属性设置为向浏览器指示脚本将在文档被解析后执行。由于所有其他主要浏览器尚未实现此功能,因此作者不应假设脚本的执行实际上会被延迟。不应该在没有 src 属性的脚本上使用 defer 属性。从 Gecko 1.9.2 开始,没有 src 属性的脚本会忽略 defer 属性。但是,在 Gecko 1.9.1 中,如果设置了 defer 属性,甚至内联脚本也会被延迟。

    【讨论】:

      【解决方案2】:

      发生这种情况的原因似乎与jQuery无关,它似乎与summernote如何初始化编辑器有关。您正在获取的 optional-editor 属性是 div 元素并且正在初始化,而不是 input 元素。

      接下来发生的事情是summernote然后获取这个div并在内部创建几个其他div元素,其中包含note-editornote-dropzonenote-editing-area等类。最里面的div有一个名为@的类987654330@ 并且在这个 div 里面是你的输入元素。 note-editable div 是summernote 认为的实际富文本编辑器,而不是输入元素。也就是说,您仍然可以单击输入元素并输入您想要的任何内容。

      Summernote 在onkeydown 事件(see the docs here) 上放置了一些事件侦听器,并且由于它是一个富文本编辑器,它似乎正在检查空格字符(其中包括,例如enter,它成为一个新段落),以便它可以在 HTML 中转义它(空格变为&amp;nbsp;)。由于您在note-editable div 中输入,即使您在技术上在input 元素中输入,这个按键将被summernote 捕获,并且似乎将转义的空格字符放置在div 中,而不是在输入。这导致文本被放置在您的输入元素上方。您会注意到,当您的光标位于输入元素上方时,您可以使用 ctrl+A 来突出显示此可编辑 div 中的所有内容,您甚至可以删除您的输入元素。

      我的建议是完全删除输入元素,只使用包含的 div,因为这似乎是最常见的用例场景。您也可以尝试覆盖 onkeydown 事件侦听器并将空格附加到输入内部,但这似乎是一种尝试解决实际上不需要解决的问题的非常迂回的方式。

      编辑:看起来summernote克隆了指定为富文本编辑器的节点,该节点最终会删除所述元素上的任何事件侦听器,包括其子元素,因此您无法覆盖初始化summernote之前文本输入元素的keydown事件。尝试通过 Summernote 的 init 配置为 keyDown 事件提供覆盖回调是可能的,但由于 Summernote 设置的预配置事件处理程序,非常难看并且有怪癖。

      在小提琴中,我只使用了一个文本输入,并给了它 id richTextInput。另外,我删除了onchange="onAnswerChoiceChange(this);",因为这会导致错误。

      要在配置中提供覆盖,请使用:

      $(optionEditors[i]).summernote({
        airMode: true,
        popover: {
          air: [
            ['font', ['bold', 'underline', 'clear']]
          ]
        },
        callbacks: {
          onKeydown: function(e) {
            if (e.keyCode === 32) { // catch "space"
              e.preventDefault();
              $('.note-editable>#richTextInput').val($('.note-editable>#richTextInput').val() + " ");
            }
          }
        }
      });
      

      note-editable类是summernote初始化后创建的容器div。我们需要指定这个,因为summernote会在初始化之前自动复制“rich-text-editor-to-be”的所有内容,然后用display:none隐藏它们,所以仅仅试图用$('#richTextInput')引用输入是行不通的,因为你'将抓取隐藏的输入。

      怪癖:您会注意到,如果您尝试使用此代码,summernote 将尝试自动为 actual 富文本编辑器 div 提供焦点,这是由于Summernote 注册的事件监听器中提供的行为。你可以通过提供这样的超时来解决这个问题:

      setTimeout(function() {
          $('.note-editable>#richTextInput').focus();
      }, 1); 
      

      正如我之前所说,这确实不是一个好的解决方案,虽然它可能会奏效,但我认为更好的方法是完全放弃文本输入,只初始化一个 div 或 textarea ,而没有任何嵌套在库中预计。这样做会更容易,然后相应地设置它们的样式。使用材料设计样式/组件可能无法很好地协同工作,因为材料需要输入或 textarea 元素,而summernote 会将 textarea 转换为 div,但这是一个不同的问题。

      【讨论】:

      • 我尝试这样做但没有任何运气。你有没有机会拿我提供的小提琴给我看你指的是什么?
      • @user687554 我更新了我的答案以向您展示我所指的内容。希望这会有所帮助
      • 你提到的小提琴在哪里?我在任何地方都没有看到指向小提琴的链接。谢谢
      • @user687554 here 与我提到的内容无关。希望这会有所帮助
      • @stevenlberger - 所以,也许我很困惑。但是当我访问您发布的小提琴时,单击文本字段,我可以输入文本。但是,我从来没有看到summernote 富文本编辑器选项出现。我是不是误会了什么?
      【解决方案3】:

      也许解决方案很简单。 &lt;div contenteditable="true"&gt; parent 已创建(也许您不需要 &lt;input&gt;),实际发生 RICH-EDITING。

      1) 空中模式开启:https://jsfiddle.net/hwd5efe0/13/
      2) 空中模式关闭:https://jsfiddle.net/hwd5efe0/18/

      (p.s. 只改了 JS )

      【讨论】:

        【解决方案4】:

        另一种解决方案是使用 CSS 隐藏输入,并使 Summernote 看起来像一个表单控件:

        for (var i=0; i<optionEditors.length; i++) {
            $(optionEditors[i]).summernote({
              airMode: true,
              popover: {
                air: [
                  ['font', ['bold', 'underline', 'clear']]
                ]
              },
              callbacks: {
                onInit: function() {
                       // make the editor like a "form-control"
                       $('.note-editor').addClass('form-control');
                       // Force editor height adding one space 
                       $(this).summernote('code', ' ');
                    }
                }      
            });
        
        }
        

        @查看工作示例https://jsfiddle.net/v8zhvsmo/

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-06-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多