2016-05-09 32 views
8

这是一个example是否可以动态获取固定宽度的文本的最后一行?

<div class="parent"> 
    Contrary to popular belief Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. 
</div> 

这个div是200像素宽,我需要赶上最后一行我可以在浏览器中看到,有一个跨度加以包装。如我的情况下为<span>it over 2000 years old.</span>

这可能与jQuery的/ JavaScript?或者至少得到这个“最后”线的长度。

编辑:我想我找到一个好办法:https://jsfiddle.net/qqkxyq42/2/

+0

你是说,你知道前手的子?如果在逗号分割,对吧? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split。 –

回答

3

This Works。用一句话是字计算宽度

https://jsfiddle.net/stevenkaspar/ht7ostyx/9/

<div 

class="parent" id='text'> 
    Contrary to popular belief Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. 
</div> 

<script> 

function getWidth(pre_space, str, post_space, append_elem){ 
    var pre = (pre_space) ? '&nbsp;' : ''; 
    var post = (post_space) ? '&nbsp;' : ''; 

    var tmp_div = $('<span style="white-space: nowrap;">'+pre+str+post+'</span>'); 
    append_elem.append(tmp_div); 
    var width = tmp_div.width(); 
    tmp_div.remove(); 
    return width; 
} 
function linkEndLine(elem_id){ 
    var elem = document.getElementById(elem_id); 
    var width = $(elem).width(); 
    var text = elem.innerText; 
    var words = text.split(' '); 
    var line_width = 0; 
    var current_line = ''; 
    var lines = []; 
    words.map(function(word, index){ 

    if(line_width == 0){ 
     line_width += getWidth(false, word, false, $(elem)); 
    } 
    else { 
     line_width += getWidth(true, word, false, $(elem)); 
    } 

    if((line_width/width) > 1){ 
     lines.push(current_line); 

     line_width = getWidth(false, word, false, $(elem)); // new line 
     current_line = ''; 
    } 
    current_line += ((current_line != '') ? ' ' : '') + word; 

    if(index == (words.length-1)){ 
     lines.push(current_line); 
    } 
    }) 
    var end_index = lines.length - 1; 
    lines[end_index] = '<a href="#">'+lines[end_index]+'</a>'; 
    elem.innerHTML = lines.join(' '); 
} 
linkEndLine('text'); 

</script> 
4

这可能是多一点的铁杆比你希望,但你可以检查父的高度,并开始由文字删除Word,检查它每次迭代,直到高度改变。然后你会知道最后一行开头的是什么文字或符号。

var words = text.split(' '); // An array of all the words split by spaces, since that's where text breaks by default. 
var lastLine = []; // Put all words that don't change the height here. 
var currentHeight = parentEl.clientHeight; // The starting height. 

while(words[0]){ 
    parentEl.innerText = words.join(' '); 
    if (parentEl.clientHeight < currentHeight) { 
    var span = document.createElement('span'); 
    span.innerText = lastLine.join(' '); 
    parentEl.appendChild(span); 
    break; 
    } 

    lastLine.shift(words.pop); 
} 

我假设你正在做这个的风格在某种程度上文本,目前有一个伪选择称为first-line,它的目标上的选择文本的第一线,但我们还没有看到一个last-linenth-line(#)选择器,这是一个耻辱,因为它似乎是一个非常合理的事情。

+0

不错,但我认为OP需要这样的东西才能达到比这更好的东西。我喜欢,因为你正在回答这个问题,但我不喜欢在我的项目中使用这种类型的东西。 –

3

您可以使用document.caretPositionFromPoint这一点,如果你知道或可以近似在容器中的文本行的高度。下面是一个示例小提琴:https://jsfiddle.net/xtcadpo0/

该函数基本上允许我们抓取任何元素在给定坐标处的文本的偏移位置,然后我们对元素的textContent属性使用简单的字符串切片。我们用这个来获取之前这个点的位置,并得到偏移量。

此解决方案对DOM性能也非常友好,因为我们不插入新元素或改变已存在的元素。

希望有所帮助。

编辑:刚才看到你想要包装的跨度中的最后一行,你可以这样做:https://jsfiddle.net/xtcadpo0/1/

它将该文本节点并替换为一个包裹元素替换。

下面是代码:

function fn(el) { 
    var range; 
    var textNode; 
    var offset; 

    var e = {}; 

    var height = el.clientHeight; 
    var lh = parseFloat(getComputedStyle(el).lineHeight, 10) || 18; 
    var D = height/lh; 
    var secondLastLineStart = (D - 1.5) * lh; 
    var pos = el.getBoundingClientRect(); 
    e.x = pos.right; 
    e.y = secondLastLineStart; 

    if (document.caretPositionFromPoint) { 
    range = document.caretPositionFromPoint(e.x, e.y); 
    textNode = range.offsetNode; 
    offset = range.offset; 
    } else if (document.caretRangeFromPoint) { 
    range = document.caretRangeFromPoint(e.x, e.y); 
    textNode = range.startContainer; 
    offset = range.startOffset; 
    } 
    var repl = textNode.splitText(offset); 
    var newEl = document.createElement('span'); 
    textNode.parentNode.replaceChild(newEl, repl); 
    newEl.appendChild(repl); 
} 

fn(document.getElementById('x')); 
+0

很好的解决方案,您应该将代码嵌入到答案中,而不仅仅是JSfiddle中。 – Loktar

+0

这是一个非常酷的解决方案。你可以将它嵌入到StackSnippet中吗(也可以添加一些关于你的每行代码的评论吗?) – Tuvia

0

为此,您必须使用JavaScript split方法得到的文本所有的作品。然后将每个单词添加到元素并获取元素height。如果元素高度达到元素的第一个高度,那意味着这个单词在最后一行。见我的例子

var words = $(".parent").text().split(" "); 
 
var elementHeight = $(".parent").height(); 
 
var lastLine = ""; 
 

 
$(".parent").text(""); 
 
$.each(words, function(index, value){ 
 
    $(".parent").append(value + " "); 
 
    if ($(".parent").height() == elementHeight) 
 
     lastLine += value + " "; 
 
}); 
 

 
var html = $(".parent").html().replace(lastLine.trim(), "<span>" + lastLine + "</span>"); 
 
$(".parent").html(html);
.parent { 
 
    width: 200px; 
 
} 
 

 
span { 
 
    background: yellow; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div class="parent"> 
 
    Contrary to popular belief Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. 
 
</div>

如果你想要做的使用纯JavaScript这项工作见jsfiddle

相关问题