富文本编辑器表现不正常

时间:2016-08-09 17:21:40

标签: javascript summernote

我正在尝试在文本字段上创建一个富文本编辑器。为了做到这一点,我正在使用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']]
        ]
      }
    });
  }

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

4 个答案:

答案 0 :(得分:1)

另一个解决方案是使用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', ' ');
            }
        }      
    });

}

@see work example https://jsfiddle.net/v8zhvsmo/

答案 1 :(得分:0)

Bootstrap plugins depend on jQuery;如果它没有先加载它们会失败:

  
    

插件依赖项

         

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

  
您的jQuery脚本加载代码中的

The defer attribute导致其在中addAllElements事件中调用onload后加载

  
    
      

<强> defer

    
         

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

  

答案 2 :(得分:0)

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

接下来会发生什么是summernote,然后使用此div并使用divnote-editornote-dropzone等类创建其他几个note-editing-area元素。 -most div有一个名为note-editable的类,在这个div中是你的输入元素。 note-editable div是summernote认为是实际的富文本编辑器,而不是输入元素。也就是说,您仍然可以单击输入元素并输入您想要的任何内容。

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

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

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

在小提琴中,我只使用了一个文本输入,并为其指定了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-be-be”的所有内容,然后用display:none隐藏它们,所以只需尝试用$('#richTextInput')引用输入不行,因为你会抓住隐藏的输入。

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

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

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

答案 3 :(得分:0)

也许解决方案很简单。创建<div contenteditable="true">父级(也许您不需要<input>),实际上发生了RICH-EDITING。

1)airmode ON:https://jsfiddle.net/hwd5efe0/13/
2)airmode OFF:https://jsfiddle.net/hwd5efe0/18/

(p.s。只改变了JS)