views:

45

answers:

1

Hi,

I am trying to find a way to remember/store a JScript textrange and then apply it back to a text and convert it into a selection.

An example: in an iframe which is in "designmode" and contains the text "This is text inside the frame", the user hilights/selects "is text".

I can read that selection by using all the available range methods. No problem so far. Now clicking a button creates creates another iframe containing the same text as the first one and the first iframe gets removed. In that second iframe I want to select the same text the user selected in the first frame. Now the problems start: the range object from iframe 1 cannot be used for iframe 2. Somehow the range object seems to be tied to its source element. Setting the range has either no effect or weird errors. How can I re-select whatever WAS selected?

René

Is there a way to

+1  A: 

Yes, there is a way. textRange provides many methods/properties, for example to determine the position.

So if you say, that's not a real copy, but identical, you can fetch the positions of frame1 and create upon them a new selection in frame2.

I was playing around with it a little bit, here's the result:

    <html>
<head>
<title>title</title>
<script type="text/jscript">
<!--

function cloneSelection()
{
  if(!document.all || window.opera)
  {
    alert('this is an jscript-example for MSIE5+');
    return;
  }
  var editors=window.frames;  
      editors[0].focus();    

  //create 2 ranges in the first iframe 
  var r1=editors[0].document.selection.createRange();
  var r2=editors[0].document.selection.createRange();

  //checkout if a control is selected
  if(editors[0].document.selection.type==='Control')
  {    
    var obj=r1.item(0);
    var objs=editors[0].document.body.getElementsByTagName(obj.tagName);

    //iterate over the elements to get the index of the element
    for(var i=0;i<objs.length;++i)
    {
      if(objs[i]===obj)
      {
        //create a controlRange, add the found control and select it
        var controls=editors[1].document.body.createControlRange();
            controls.add(editors[1].document.body.getElementsByTagName(obj.tagName)[i]);
            controls.select()
        return;
      }
    }
    //control-branch done
  }

  //no control was selected, so we work with textRanges  
  //collapse the 2nd range created above 
  r2.collapse(false); 

  //store the positions of the 2 ranges
  var x1=r1.offsetLeft;
  var y1=r1.offsetTop;
  var x2=r2.offsetLeft;
  var y2=r2.offsetTop;

  //create ranges in the 2nd iframe and move them to the stored positions
  var r2=editors[1].document.body.createTextRange();
      r2.moveToPoint(x1,y1);
  var r3=editors[1].document.body.createTextRange();
      r3.moveToPoint(x2,y2);

  //set the move the end of the first range to start of the 2nd range
  r2.setEndPoint('EndToStart',r3);

  //select the first range
  r2.select(); 

}

//fill the iframes and make them editable
window.onload=function()
{
  var editors=window.frames;
  for(var i=0;i<frames.length;++i)
  {
    with(frames[i].document)
    {
      open();
      write('This is text is an image '+
            '<br/><img src="http://sstatic.net/ads/img/careers-ad-header-so.png"&gt;&lt;br/&gt;'+
            'this is inside this frame');
      designMode='On';
      close();
    }
  }
}
//-->
</script>
<style type="text/css">
<!--
iframe{width:400px;height:200px;}
-->
</style>
</head>
<body>
  <center>
    <iframe src="about:blank"></iframe>
    <input type="button" value="cloneSelection()" onclick="cloneSelection()">
    <iframe src="about:blank"></iframe>
  </center>
</body>
</html>

test with jsFiddle

Notice that this demo so far is build for MSIE only(you wrote you like to do it with JScript^^) .

But it should also be possible to implement it for other browsers.

Dr.Molle
That's marvelous! Makes me wonder how little I know about JScript! I'll check if that solves it for IE. If yes, I'll make it work for Firefox. Thanks a lot!!
Krumelur
But please explain: to select something in IE, you specify absolute coordinate in pixels and IE knows what to select from those coordinates? Why is it then necessary to treat objects separately? Isn't everything an object (a link, a textnode, a table, an image)?
Krumelur
Those objects (e.g. images, form-elements) represent another type of range in IE, "controlRange". This type of range has properties different from a textRange. This type of range for example does'nt have the properties of a textRange to determine position or move start/end of the range. Those ranges represent more than a textRange the DOM-Element-Object/s . http://msdn.microsoft.com/en-us/library/ms537447%28VS.85%29.aspx
Dr.Molle