看看这个<div>
- 元素:
<div id="text">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque pena­tibus et magnis dis parturient montes, nascetur ridiculus mus.</div>
和这个css:
div#text {
font-family: Arial;
font-size: 16px;
width: 200px;
}
当渲染这个div时,它被分成许多行,可能看起来像这个块:
Lorem ipsum dolor sit amet,
consectetuer adipiscing elit。
Aenean commodo ligula
eget dolor。 Aenean massa。
Cum sociis natoque pena-
tibus et magnis dis
产妇montes,nascetur
嘲笑
有没有办法使用Javascript提取这个div内容的第6行?这意味着,我想要一个函数,我传递值3
,然后它返回»tibus et magnis dis«。这可能吗?如果是这样,怎么办呢?
“penatibus”这个词中的软连字符(­
)使得这个词被分成两部分。
以类似的方式,考虑css-property hyphen
:
div#text {
hyphens: auto;
}
这会使渲染机连接文本,而无需插入破折号或­
- 实体。
请记住,文本中没有换行符或<br>
或任何其他标记将文本拆分为多行。它只是渲染机器的自动换行算法和css-styles以及texttring本身,它们负责将哪些单词写入哪一行。
这也是此问题与this不同的原因。
这个问题也与this one不同,因为那里发布的解决方案忽略了连字符的影响。
还要想到连字(就像f后跟i一样,许多字体被新的字形替换,fi,比正常f稍微短一点,接着是正常情况。这可能会影响自动换行和但是当你将文本的每个字符放入一个<span>
元素中以便能够读取所有这些元素的位置时,你就不会看到f和我被其较短的连字fi所取代,所以在所有情况下,此方法都不会返回正确的结果。
答案 0 :(得分:2)
I guess you could trick a bit, and copy the width of the existing element, and then add word per word to see if the height of the new element changes, then increase the line.
I wrote a basic version of this. This only takes into account the width of the div element, none of the other styles (like font-size, letter-spacing, ... for that, you could copy the css styles from the element you wish to get the line nr from)
function copyStyle(source, target) {
var computedStyle = window.getComputedStyle(source, null),
prop, obj = computedStyle, i, len, style = '';
for (i = 0, len = computedStyle.length; i < len; i++) {
prop = computedStyle[i];
style += prop + ': ' + obj[prop] + ';';
}
target.style = style;
}
function extractHyphens(array) {
var word, i, len, shyElement = document.createElement('span');
shyElement.innerHTML = '­';
for (i = 0, len = array.length; i < len; i++) {
word = array[i];
if (word.indexOf(shyElement.innerHTML) >= 0) {
word = word.split(shyElement.innerHTML);
array.slice(i, 1, word);
}
}
}
function getLine(element, lineNr, callback, measuredWidth) {
var hiddenElement,
sourceElement = document.getElementById(element),
textarea = document.getElementById('textarea'),
lastHeight,
outline = '',
curline = -1,
words, word;
if (typeof measuredWidth === 'undefined' ||
measuredWidth !== sourceElement.offsetWidth) {
measuredWidth = sourceElement.offsetWidth;
setTimeout(function() {
getLine(element, lineNr, callback, measuredWidth);
}, 100);
} else {
hiddenElement = document.createElement('div');
words = sourceElement.innerHTML;
words = words.split(' ');
extractHyphens(words);
copyStyle(sourceElement, hiddenElement);
hiddenElement.style.visibility = 'hidden';
// we don't want anything affecting the height of the "hidden" element
hiddenElement.style.height = 'auto';
delete hiddenElement.style['minHeight'];
delete hiddenElement.style['maxHeight'];
document.body.appendChild(hiddenElement);
lastHeight = hiddenElement.offsetHeight;
for (var i = 0, len = words.length; i < len; i++) {
word = words[i];
hiddenElement.innerHTML += word;
if (lastHeight !== hiddenElement.offsetHeight) {
curline++;
}
if (lineNr === curline) {
outline += word + ' ';
}
hiddenElement.innerHTML += ' ';
lastHeight = hiddenElement.offsetHeight;
if (curline > lineNr) {
break;
}
}
document.body.removeChild(hiddenElement);
setTimeout(function() {
callback(element, outline);
}, 0);
}
}
function showResult(element, result) {
alert(element + ': ' + result);
}
window.onload = function() {
getLine('test', 1, showResult);
getLine('test2', 6, showResult);
};
#test2 {
width: 50px;
font-size: 7px;
padding: 3px;
}
div {
padding: 5px;
}
<div id="test">lorem ipsum dolor sit amet, consectetuer adipiscing elit, aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque­»penatibus« et magnis dis parturient montes, ascetur ridiculus mus.</div>
<div id="test2">lorem ipsum dolor sit amet, consectetuer adipiscing elit, aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, ascetur ridiculus mus.</div>