最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to get position of every character - Stack Overflow

programmeradmin0浏览0评论

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.

发布评论

评论列表(0)

  1. 暂无评论