views:

308

answers:

2

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.

+1  A: 

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
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
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
+1  A: 

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
I'm quite happy that this was accepted, but even I have to admit it's more advice than answer.
David Andres
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
@thedp: Is the IE example not working? It's designed to select all text within the first DIV element.
David Andres
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
@thedp: Thanks, I corrected the code to declare variable "start."
David Andres
One final question, I'm all set to go :)How can I select from the first div to the last?Thanks again.
thedp
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
Thank you. I will try to do so as well, and post if I find it.
thedp