发生这种情况的原因似乎与jQuery无关,它似乎与summernote如何初始化编辑器有关。您正在获取的 optional-editor 属性是 div 元素并且正在初始化,而不是 input 元素。
接下来发生的事情是summernote然后获取这个div并在内部创建几个其他div元素,其中包含note-editor、note-dropzone、note-editing-area等类。最里面的div有一个名为@的类987654330@ 并且在这个 div 里面是你的输入元素。 note-editable div 是summernote 认为的实际富文本编辑器,而不是输入元素。也就是说,您仍然可以单击输入元素并输入您想要的任何内容。
Summernote 在onkeydown 事件(see the docs here) 上放置了一些事件侦听器,并且由于它是一个富文本编辑器,它似乎正在检查空格字符(其中包括,例如enter,它成为一个新段落),以便它可以在 HTML 中转义它(空格变为 )。由于您在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,但这是一个不同的问题。