这是什么问题?
if ( window.getSelection() )
EditField = window.getSelection().getRangeAt(0);
引发错误:
最佳答案
这个问题似乎是WebKit特有的。我无法在IE或Firefox中复制它。如OP所述,Google Chrome上的错误是:
Safari存在相同的问题,但消息有所不同:
通常发生在简单的WYSIWYG编辑器中。例子:
<form name="frm">
<div contenteditable="true" style="border:1px solid grey;height:8em;width:100%;">
Text inside my editor.
</div>
Click this button to insert some text into the text editor:
<button type="button" onclick="doInsert('TEST');">Insert</button>
</form>
<script>
function doInsert(text) {
var sel = window.getSelection && window.getSelection();
if (sel) {
var range = sel.getRangeAt(0); // error here
var node = document.createTextNode(text);
range.deleteContents();
range.insertNode(node);
}
}
</script>
页面加载后,单击按钮;您将在JavaScript控制台(Chrome)或错误控制台(Safari)中看到错误消息。但是,如果在单击按钮之前单击编辑器部分内的任何位置,则不会发生该错误。
这个问题很容易预防;始终在调用
rangeCount
之前检查getRangeAt
:function doInsert(text) {
var sel = window.getSelection && window.getSelection();
if (sel && sel.rangeCount > 0) {
var range = sel.getRangeAt(0);
...
当然,可以通过在页面加载时给予编辑器焦点(使用
focus
方法)来避免这种情况。但是,有些罕见的事件会导致您的编辑器稍后失去选择范围。到目前为止,我只能使用多选列表控件来重现此内容:
<form name="frm">
<div contenteditable="true" style="border:1px solid grey;height:8em;width:100%;">
Click to position the caret anywhere inside this editor section.
</div>
Next, select an item from this list:
<select id="insertables" multiple="multiple">
<option>foo</option>
<option>bar</option>
<option>baz</option>
</select>
<br />Finally, click this button to insert the list item into the text editor:
<button type="button" onclick="doInsert(frm.insertables.value);">Insert</button>
</form>
<script>
function doInsert(text) {
var sel = window.getSelection && window.getSelection();
if (sel) {
var range = sel.getRangeAt(0); // error here
var node = document.createTextNode(text);
range.deleteContents();
range.insertNode(node);
}
}
</script>
同样,我可以通过检查
rangeCount
来防止错误。但是问题仍然出在,我的按钮没有像预期那样在最后的已知插入号位置插入所选列表项。方法focus
没有帮助;它将插入符号的位置重置为编辑器中的左上角位置。一种解决方案是连续保存当前选择范围(为此,捕获事件
SelectionChange
):var savedRange = null;
document.addEventListener("selectionchange", HandleSelectionChange, false);
function HandleSelectionChange() {
var sel = window.getSelection && window.getSelection();
if (sel && sel.rangeCount > 0) {
savedRange = sel.getRangeAt(0);
}
}
并在单击按钮时将其还原:
function doInsert(text) {
var sel = window.getSelection && window.getSelection();
if (sel && sel.rangeCount == 0 && savedRange != null) {
sel.addRange(savedRange);
}
if (sel && sel.rangeCount > 0) {
var range = sel.getRangeAt(0);
var node = document.createTextNode(text);
range.deleteContents();
range.insertNode(node);
}
}
fiddle :http://jsfiddle.net/stXDu/