我有一个嵌入Bootstrap 3模式的Ace编辑器。在显示模态之前,我在编辑器中设置了这样的值:
var editor = ace.edit(aceEditorId);
editor.session.setValue(val, -1); // set value at document start
editor.session.selection.clearSelection();
我还有一个“显示”事件处理程序,用于调整编辑器的模式:
$(editSnippetSelector).on("shown.bs.modal", function () {
var editorId = getSnippetEditorId();
var snippetEditor = ace.edit(editorId);
snippetEditor.resize();
当我专注于Firefox中的编辑器时,所有编辑器文本都会被选中。我无法通过单击移动光标或删除选择。我只能通过按退格键或其他键(例如字母或输入键)来删除文本。
这不会发生在Chrome或IE中。
作为一项实验,我也添加了这段代码无济于事:
codeEditor.on("focus", function () {
codeEditor.getSession().setValue(codeEditor.getSession().getValue());
codeEditor.clearSelection();
});
我还应该在哪儿看?还有其他人看到过类似的行为吗?
更新
我注意到onSelect
中的ace.js
函数在无限循环中被调用。它在2061行:https://github.com/ajaxorg/ace-builds/blob/master/src-noconflict/ace.js#L2061
以下是该函数的代码:
var onSelect = function(e) {
if (copied) {
copied = false;
} else if (isAllSelected(text)) {
host.selectAll();
resetSelection();
} else if (inputHandler) {
resetSelection(host.selection.isEmpty());
}
};
浏览Firefox调试器中的代码表明对isAllSelected(text)
的调用返回true,因此再次引发选择事件。
答案 0 :(得分:6)
ace.js
有一个onSelect
处理程序,在Firefox中以无限循环方式调用。
以下是该功能的原始代码:
var onSelect = function(e) {
if (copied) {
copied = false;
} else if (isAllSelected(text)) {
host.selectAll();
resetSelection();
} else if (inputHandler) {
resetSelection(host.selection.isEmpty());
}
};
text
是textarea DOM元素。 isAllSelected(text)
检查是否使用此代码选择了所有文本:
return text.selectionStart === 0 && text.selectionEnd === text.value.length;
正如您所看到的,即使对于空文本区域也会返回true,然后会调用host.selectAll()
以某种方式向下传播并再次触发select事件。
我添加了一个空文本区域的检查,它修复了问题。代码现在是这样的:
var onSelect = function(e) {
if (copied) {
copied = false;
} else if (text.value && isAllSelected(text)) {
host.selectAll();
resetSelection();
} else if (inputHandler) {
resetSelection(host.selection.isEmpty());
}
};
答案 1 :(得分:1)
这很可能是由渲染器中过时的缓存大小引起的。
您需要在显示模态后调用editor.resize()