0

The following code gives me a really weird error in Firefox:

Error: uncaught exception: [Exception... "Index or size is negative or greater than the allowed amount" code: "1" nsresult: "0x80530001 (NS_ERROR_DOM_INDEX_SIZE_ERR)" location: "file:///G:/test.html Line: 13"]

<html>
<head>
    <title>test</title>

   <script>
function xxx() {

   var myList = document.getElementsByTagName("div");

   var range = document.createRange();
   var start = myList[0];
   var end = myList[0];
   range.setStart(start, 1); // Edit: this is (presumably) line 13
   range.setEnd(end, 3); 

   window.getSelection().addRange(range);
}
   </script>
</head>

<body onload="xxx();">

   <div>abcddasdsadasda</div>
   <div>2312321</div>

</body>
</html>

What am I doing wrong?

Thank you.

thedp
  • 8,350
  • 16
  • 53
  • 95
  • I get a JavaScript error in IE 7 at the document.createRange() line. Doesn't look like DOM ranges are supported in IE, at least not through that function. – David Andres Sep 15 '09 at 12:19
  • I can't get Firefox to throw this error. It doesn't do anything at all, but there's no error. What version of FF are you using? – Pete OHanlon Sep 15 '09 at 12:25
  • It's not an error in FireFox. window.getSelection does not work in IE. – David Andres Sep 15 '09 at 12:29

2 Answers2

2

You need to expand function xxx to support IE, which it currently doesn't. The document.createRange and window.getSelection functions do not appear to work within this environment.

How about:

function xxx()
{
  var myList = document.getElementsByTagName("div");    

  if(window.getSelection)
  {
    var range = document.createRange();

    var start = myList[0];
    var end = myList[0];

    range.setStart(start, 0);
    range.setEnd(end, 1);
    window.getSelection().addRange(range);      
  }
  else
  if(document.selection)
  {
    document.selection.empty();
    var txt = document.body.createTextRange();
    txt.moveToElementText(myList[0]);
    txt.setEndPoint("EndToEnd", txt);
    var start;
    txt.moveStart('character', start);

    if (length + start > myList[0].innerHTML.length) 
    {
      length = myList[0].innerHTML.length - start;
    }

    txt.moveEnd('character', -(myList[0].innerHTML.length - start - length));
    txt.select();
  } 
} 

The code will select the entire DIV element's text. You'll need to fiddle with the endpoints to get this to select only a portion of this range.

David Andres
  • 31,351
  • 7
  • 46
  • 36
  • I'm quite happy that this was accepted, but even I have to admit it's more advice than answer. – David Andres Sep 15 '09 at 14:38
  • With your advice I now know how I can solve my issues. But could you please fix the IE example, I'm having some problems understanding it. Thanks. – thedp Sep 15 '09 at 18:49
  • @thedp: Is the IE example not working? It's designed to select all text within the first DIV element. – David Andres Sep 15 '09 at 18:51
  • My bad. It works great... But one thing I don't understand. Where is the "start" variable is coming from in the IE statement, it seems to be undefined? – thedp Sep 15 '09 at 19:05
  • @thedp: Thanks, I corrected the code to declare variable "start." – David Andres Sep 15 '09 at 19:18
  • One final question, I'm all set to go :) How can I select from the first div to the last? Thanks again. – thedp Sep 15 '09 at 19:29
  • 1
    Have to be honest, I haven't had any luck selecting multiple elements. I'll hack away at it, but can't make any promises at this point! – David Andres Sep 16 '09 at 00:33
  • Thank you. I will try to do so as well, and post if I find it. – thedp Sep 16 '09 at 08:21
1

First, I highly recommend Firebug for debugging Javascript on FireFox. It pointed me to the setEnd line immediately.

Now to the getting you to the answer. The second parameter of setStart and setEnd is the node depth to select into. Since you only have two div tags without any child nodes you only have depths 0 and 1. For myList[0] your depth 0 is the div tag itself and depth 1 is the text node within the div.

Since I'm not sure what you attempting to select here would be the corrected code for selecting all text within both div tags.

   var end = myList[1];
   range.setStart(start, 0);
   range.setEnd(end, 1);
Scott Bevington
  • 1,201
  • 10
  • 12
  • I wanted to select the text "bcd" in the first div element... From the following article I understood it can be done: http://www.quirksmode.org/dom/range_intro.html – thedp Sep 15 '09 at 12:31
  • This doc explains that not only is the second parameter the number of child nodes but for nodes of type Text, Comment, or CDATASection the offset is the number of characters. https://developer.mozilla.org/en/DOM/range.setEnd – Mr Rogers Mar 23 '10 at 16:37