Вы можете кэшировать ширину символов, которые вы уже видели.
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
};
}
Затем вы можете даже запомнить каждый индекс, который вы захватите и начнете с закрытия один за другим при следующем вызове этой функции. Это означает, что вы остаетесь вне дома, за исключением обычно не более чем примерно 50 раз (буквенно-цифровой + пунктуация и т. Д.), А не для каждого символа.
Это, безусловно, будет работать для моноширинных шрифтов, но я думаю, что есть некоторые преимущества для других типов. Вам просто нужно провести исследование обёртки для разных браузеров.
Также обратите внимание, что это предполагает выравнивание по левому краю и т. Д. Это скорее идея, чем реальное кодовое решение.