未捕获的IndexSizeError:无法在'Selection'上执行'getRangeAt':0不是有效的索引 [英] Uncaught IndexSizeError: Failed to execute 'getRangeAt' on 'Selection': 0 is not a valid index

查看:1233
本文介绍了未捕获的IndexSizeError:无法在'Selection'上执行'getRangeAt':0不是有效的索引的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里有什么问题?

  if(window.getSelection())
EditField = window.getSelection( ).getRangeAt(0);

抛出错误:


Uncaught IndexSizeError:无法在'Selection'上执行'getRangeAt':0不是有效索引。



解决方案

问题似乎是WebKit特有的;我无法在IE或Firefox中重现它。正如OP已经提到的,Google Chrome上的错误是:


未捕获的IndexSizeError:无法在'Selection'上执行'getRangeAt':0是不是有效的索引


Safari有同样的问题,但消息不同:


INDEX_SIZE_ERR:DOM例外1:索引或大小为负数,或大于允许值。


通常在简单的WYSIWYG编辑器中发生。示例:



< pre class =snippet-code-html lang-html prettyprint-override> < form name =frm> < div contenteditable =truestyle =border:1px solid grey; height:8em; width:100%;>我的编辑内的文字。 < / DIV>单击此按钮可在文本编辑器中插入一些文本:< button type =buttononclick =doInsert('TEST');> Insert< / button> < /形式> <脚本> function doInsert(text){var sel = window.getSelection&& window.getSelection(); if(sel){var range = sel.getRangeAt(0); //错误此处var node = document.createTextNode(text); range.deleteContents(); range.insertNode(节点); }< / script>



页面加载后,点击按钮;您将在JavaScript控制台(Chrome)或错误控制台(Safari)中看到错误消息。但是,如果在单击按钮之前单击编辑器部分内的任何位置,则错误将



<强>这个问题很容易预防;在调用 getRangeAt 之前总是检查 rangeCount

  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 =truestyle =border:1px solid grey; height:8em; width:100%;>单击以将插入符号放置在此编辑器部分的任何位置。 < / DIV>接下来,从此列表中选择一个项目:< select id =insertablesmultiple =multiple> <选项> FOO< /选项> <选项>巴≤; /选项> <选项>巴兹< /选项> < /选择> < br />最后,单击此按钮将列表项插入文本编辑器:< button type =buttononclick =doInsert(frm.insertables.value);> Insert< / button>< ; /形式><脚本> function doInsert(text){var sel = window.getSelection&& window.getSelection(); if(sel){var range = sel.getRangeAt(0); //错误此处var node = document.createTextNode(text); range.deleteContents(); range.insertNode(节点); }< / script>  



再次,我可以阻止检查 rangeCount 时出错。但问题仍然是我的按钮没有插入最后一个已知插入位置的所选列表项,正如它应该做的那样。方法焦点没有帮助;它会将插入符号位置重置为编辑器中的左上角位置。



解决方案是连续保存当前选择范围(为此,陷阱事件 SelectionChange ):

  var savedRange = null; 

document.addEventListener(selectionchange,HandleSelectionChange,false);

函数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);
}
}

小提琴:http://jsfiddle.net/stXDu/


What is problem here?

if ( window.getSelection() ) 
  EditField = window.getSelection().getRangeAt(0);

throws error:

Uncaught IndexSizeError: Failed to execute 'getRangeAt' on 'Selection': 0 is not a valid index.

解决方案

The problem seems to be WebKit-specific; I could not reproduce it in IE or Firefox. As OP already mentioned, the error on Google Chrome is:

Uncaught IndexSizeError: Failed to execute 'getRangeAt' on 'Selection': 0 is not a valid index

Safari has the same issue, but the message is different:

INDEX_SIZE_ERR: DOM Exception 1: Index or size was negative, or greater than the allowed value.

Typically happens in simple WYSIWYG editors. Example:

<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>

Once the page has loaded, click the button; you will see the error message in the JavaScript console (Chrome) or error console (Safari). But if you click anywhere inside the editor section before clicking the button, the error will not occur.

This problem is easy to prevent; always check rangeCount before calling getRangeAt:

function doInsert(text) {
    var sel = window.getSelection && window.getSelection();
    if (sel && sel.rangeCount > 0) {
        var range = sel.getRangeAt(0);
        ...

Of course, you can avoid the situation by giving the editor focus (with method focus) upon page load.

However, there are rare events that cause your editor to lose its selection range later on. So far, I have only been able to reproduce this with a multi-select list control:

<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>

Again, I can prevent the error by checking rangeCount. But the problem remains that my button does not insert the selected list item at the last known caret position, as it was supposed to do. Method focus does not help; it will reset the caret position to the top left position in the editor.

A solution is to continuously save the current selection range (for this purpose, trap event 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);
    }
}

And restore it when the button is clicked:

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/

这篇关于未捕获的IndexSizeError:无法在'Selection'上执行'getRangeAt':0不是有效的索引的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆