admin管理员组

文章数量:1314320

How to get position (left, top) of every characters in some node? I know just one method: wrap every character in it's own tag and then we can get it's coordinate. But it's bit slowly

How to get position (left, top) of every characters in some node? I know just one method: wrap every character in it's own tag and then we can get it's coordinate. But it's bit slowly

Share Improve this question asked Nov 30, 2010 at 8:11 anton_byrnaanton_byrna 2,5551 gold badge18 silver badges31 bronze badges 2
  • I fear you don't have much choice except the method you described. To know the position of every character you must know the exact size of each letter and that's pretty much impossible task as each font has different size for each character.. – Shadow Wizzard Commented Nov 30, 2010 at 9:00
  • Possible duplicate: stackoverflow./questions/5143534/… – Anderson Green Commented Jun 3, 2013 at 23:12
Add a ment  | 

2 Answers 2

Reset to default 8

I've found answer on my question — Range interface can present all information that I need (More info — http://www.w3/TR/DOM-Level-2-Traversal-Range/ranges.html).

You could cache the widths of characters that you already have seen.

function findOffset(index) {
  // Set some variables early on
  var sizes          = {},
      text           = "The text you are getting an offset from.",
      lineHeight     = 16,  // You can get this dynamically if you want
      containerWidth = 500, // Same with this one
      leftOffset     = 0,
      topOffset      = 0,
      i              = 0,
      cur;

  // Loop through and count up the sizes of each character until this one
  for (; (i < text.length) && (i <= index); i++) {

    // Set the current character
    cur = text.charAt(i);

    // Check to see if we have a size
    if ( typeof size[cur] == "undefined" ) {
      // If not: Wrap it in a span (You seemed to already know how to do this)
      // then cache the result
      size[cur] = findWidthByTemporarilyWrappingInASpan(text, i);
    }

    // If it's greater than a line can hold, we'll wrap
    if ( (sizes[cur] + leftOffset) > containerWidth ) {

      // Reset the left offset
      leftOffset = 0;

      // Increment the top offset
      topOffset += lineHeight;
    }
    // Otherwise, increment from the left
    else {
      leftOffset += sizes[cur];
    }
  }

  // return an object with the coordinates
  return {
    leftOffset: leftOffset,
    topOffset : topOffset
  };
}

Then you can even memoize each index that you go grab and start from a close by one the next time you call this function. This means you stay off the dom except for usually not too much more than ~50 (alphanumeric + punctuation, etc) times, rather than for each character.

This would certainly work for monospaced fonts, but I think there is some merit to it for other types. You'd just have to do the wrapping research for different browsers.

Also, note that this assumes left-justification, etc. It's more of an idea than an actual code solution.

本文标签: javascriptHow to get position of every characterStack Overflow