我正在尝试在文本字段上创建一个富文本编辑器。为了做到这一点,我正在使用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']]
]
}
});
}
我错过了什么?一切看起来都很正确。只是这种行为似乎是错误的。谢谢。
答案 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;如果它没有先加载它们会失败:
您的jQuery脚本加载代码中的插件依赖项
某些插件和CSS组件依赖于其他插件。如果单独包含插件,请确保在文档中检查这些依赖项。另请注意,所有插件都依赖于jQuery(这意味着 jQuery必须包含在插件文件之前 )。请咨询我们的bower.json,了解支持哪些版本的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并使用div
,note-editor
,note-dropzone
等类创建其他几个note-editing-area
元素。 -most div有一个名为note-editable
的类,在这个div中是你的输入元素。 note-editable
div是summernote认为是实际的富文本编辑器,而不是输入元素。也就是说,您仍然可以单击输入元素并输入您想要的任何内容。
Summernote将一些事件监听器放在onkeydown
事件(see the docs here)上,因为它是一个富文本编辑器,它似乎正在检查空格键字符(其中包括enter
,它变成了它可以在HTML中转义它(空格变为
)。即使您在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)