Ace 在 Firefox 的焦点上选择编辑器中的所有文本
Ace selects all text in editor on focus in Firefox
我在 Bootstrap 3 模式中嵌入了一个 Ace 编辑器。在显示模式之前,我在编辑器中这样设置值:
var editor = ace.edit(aceEditorId);
editor.session.setValue(val, -1); // set value at document start
editor.session.selection.clearSelection();
我还有一个 "shown" 模态事件处理程序来调整编辑器的大小:
$(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();
});
我还应该看哪里?还有其他人看到过类似的行为吗?
更新:
我注意到 ace.js
中有一个 onSelect
函数在无限循环中被调用。它在第 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)
returns 的调用为真,因此再次引发了选择事件。
这很可能是由于渲染器中的缓存大小过时所致。
您需要在模态显示后调用 editor.resize()
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
是一个文本区域 DOM 元素。 isAllSelected(text)
检查是否所有文本都使用此代码 selected:
return text.selectionStart === 0 && text.selectionEnd === text.value.length;
如您所见,returns 即使对于空文本区域也是如此,这会导致调用 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());
}
};
我在 Bootstrap 3 模式中嵌入了一个 Ace 编辑器。在显示模式之前,我在编辑器中这样设置值:
var editor = ace.edit(aceEditorId);
editor.session.setValue(val, -1); // set value at document start
editor.session.selection.clearSelection();
我还有一个 "shown" 模态事件处理程序来调整编辑器的大小:
$(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();
});
我还应该看哪里?还有其他人看到过类似的行为吗?
更新:
我注意到 ace.js
中有一个 onSelect
函数在无限循环中被调用。它在第 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)
returns 的调用为真,因此再次引发了选择事件。
这很可能是由于渲染器中的缓存大小过时所致。
您需要在模态显示后调用 editor.resize()
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
是一个文本区域 DOM 元素。 isAllSelected(text)
检查是否所有文本都使用此代码 selected:
return text.selectionStart === 0 && text.selectionEnd === text.value.length;
如您所见,returns 即使对于空文本区域也是如此,这会导致调用 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());
}
};