Export (0) Print
Expand All
This topic has not yet been rated - Rate this topic

Positioning and Editing

As of December 2011, this topic has been archived. As a result, it is no longer actively maintained. For more information, see Archived Content. For information, recommendations, and guidance regarding the current version of Internet Explorer, see Internet Explorer Developer Center.

Michael Wallent
Microsoft Corporation

April 3, 2000

Contents

CSS Positioning
Automatic Positioning
Editing
Summary

Internally at Microsoft, we have e-mail aliases where people can ask questions about how to use DHTML. This month's column and samples focus on some of the questions that tend to arise about positioning and editing.

CSS Positioning

CSS Positioning has been around since 1997, but questions continue to come up. Probably the most common question is, "How can I tell the actual position of an object?" This question is not as easy to answer as you might hope. The sure-fire way to get the position of any element, positioned or not, is to look at the element.offsetLeft/offsetTop properties, which give the position of the element with respect to its offsetParent (the offsetParent is the parent of an element that gives it its coordinate space). This becomes interesting when you start to nest positioned and non-positioned objects. Even if the offsetParent moves, the values you will get from any of its children's offsetLeft/offsetTop values will be the same. In effect, the offsetParent provides positioning encapsulation for all of its children.

Check out this positioning sample. You should maximize your window to see everything that's going on.

First, note that as you move your mouse around, you see a lot of information flashing by in the status bar:

  • Mouse Wnd: the position of the mouse with respect to the window
  • Mouse Prnt: the position of the mouse with respect to the local container
  • Scroll: how much the window is scrolled (if any)
  • Over: the tag name and ID of the element the mouse is over
  • Offset Prnt: the offsetParent of the element that the mouse is over (if any)
  • Prnt Pos: the offsetLeft/offsetTop position of the element the mouse is over, in local coordinates
  • Window Pos: the position of the element in window coordinates

If you move your mouse over the bottom set of elements—over the blue rectangle called Middle—you can see that the offsetParent is DIV Outer. Since the DIV with ID Outer has relative positioning set, it creates its own coordinate space. In fact, any elements that are either relatively or absolutely positioned create their own coordinate space.

If you then move your mouse over the green rectangle Inner, you will see a different effect. The parent of the Inner DIV is Middle. However, since Middle isn't positioned, it doesn't create a coordinate space. In this case, the offsetParent is the Outer DIV, since it's the first parent in the chain that creates its own coordinate space.

Now that we have the information on the offsetParent and the position of the object, one technique to calculate the window-relative position of an object is to walk up the offsetParent chain, accumulating all of the offsetLeft/offsetTop values. This method will work and is reliable. However, it can be slow in a deep hierarchy.

Instead of walking up the offsetParent chain, you can use a different location method. In the above sample, you get three types of coordinate information with every mouse move event: mouse position with respect to the screen, window relative position, and local coordinates. A relative delta can be calculated that allows the transformation of a local coordinate to a window coordinate.

Here's the relevant code:

  we = window.event.srcElement;

  if ((we.offsetParent) && (we.offsetParent.tagName != "BODY")) {
    windowDX = window.event.clientX - window.event.x;
    windowDY = window.event.clientY - window.event.y;
  } else {
    windowDX = 0;
    windowDY = 0;
  }

  posX = we.offsetLeft + windowDX + document.body.scrollLeft;
  posY = we.offsetTop + windowDY + document.body.scrollTop;

To do the calculation right, you want to add the window offset value only if the element you are over actually has an offsetParent other than the <BODY> element. For elements contained directly in the <BODY> element, there is no need to calculate the offset. Also, you must consider scrolling. Any amount the window is scrolled will throw this calculation off. The scrollLeft/Top values are added in as appropriate to compensate for the amount the window is scrolled.

Automatic Positioning

The positioning sample also highlights a feature called "Automatic Positioning."

If an element is absolutely positioned, it takes up no flow space. Usually, this also means that you must give it a top/left position. However, if you do not specify a top/left position, the element will be positioned in its normally calculated flow position, but takes up no flow space. This is a very useful way to create a "float" style effect, with slightly more control. The first example in the sample above shows the Blue <DIV> with absolute positioning, but no specification for top and left. Note how the Green <DIV> immediately following it is positioned at the exact location, and there is overlap between the Blue and Green <DIV>s.

Automatic positioning bridges the gap between the inflow positioning model and the absolute positioning model. With automatic positioning, you can let the browser figure out where your elements should go, but you have more control of flow and layout.

Editing

Check out this cool editing sample that uses format tools in a drop-down box. In this sample, you can change the format of the text—but when you select text, its format value is reflected in the combo box.

Here's the relevant code:

otherDoc.body.onselect = showSelectionFont;

function showSelectionFont() {
  var f;
  f = otherDoc.queryCommandValue("FontName");
  if (!f)
    f = "null";

  f = f.toLowerCase();

  c = FontSelection.all[f];

  if ((c) && (!c.selected)) {
    c.selected = true;
  }
}

The "otherDoc" property is a pointer to the document in the IFrame that's in edit mode. I've hooked the onselect event so that every time the selection changes in the document, the showSelectionFont() method is called. It uses the queryCommandValue() method to determine the FontName property. This will return the value of the FontName property for the current selected text. If no text is selected, it will return the default.

Once I have that font name, I don't want to have to walk the options list in the select, searching for names; that's too slow. Instead, I can cheat. I give all the options an ID that matches their font name. This way, I can just use the Internet Explorer indexing method in the "all" collection to quickly look up elements by ID. Once I have the right option, I just change the selected value to true—and voila, I have an updating font drop-down box.

Summary

That's it for the grab bag DHTML Dude column this month. As you can probably tell, these two featurelets are not very related, but are both very powerful. If you are using CSS Positioning, understanding how coordinate systems work and how to transform from local to window to screen coordinates is very useful.

On the other end of the spectrum, the editing support included with Internet Explorer is often overlooked, but very powerful. Using the editing functionality, in combination with the other rich object model support for Internet Explorer, lets you create rich applications that will put your C++ programmer friends to shame.

 

DHTML Dude

Michael Wallent is Microsoft's product unit manager for Microsoft Internet Explorer.


 
Did you find this helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2014 Microsoft. All rights reserved.