如何在文本容器中找到最后一个可见的单词位置?

时间:2013-10-14 09:05:21

标签: javascript jquery html

是否有可能找到一个小div中显示的文本的最后一个可见单词的位置(溢出:隐藏)?

例如:

<div style="height: 50px; width: 50px; overflow: hidden;">
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor 
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et 
accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata
sanctus est Lorem ipsum dolor sit amet.
</div>

如何计算div容器中最后一个可见Word的位置? I like to fill the whole div133!

6 个答案:

答案 0 :(得分:4)

JSFiddle:http://jsfiddle.net/SmokeyPHP/NQLcc/1/

HTML:

<div id="txt">
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor 
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et 
accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata
sanctus est Lorem ipsum dolor sit amet.
</div>

CSS:

#txt {
    width: 75px;
    height: 75px;
    border: 1px solid #F00;
    overflow: hidden;
}

JS:

var cntnr = $("#txt");
cntnr.html('<span>'+cntnr.html().replace(/ /g,'</span> <span>')+'</span>')
var words = Array.prototype.slice.call(cntnr.find("span"),0).reverse();
var lastw = null;
for(var i=0,c=words.length;i<c;i++)
{
    var w = $(words[i]);
    var wbot = w.height() + w.offset().top;
    var wleft = w.offset().left;
    var wright = wleft+w.width();
    if(wbot <= cntnr.height() && wleft <= cntnr.width() && wright <= cntnr.width())
    {
        lastw = w.text();
        break;
    }
}
cntnr.html(cntnr.text());
alert(lastw);

JS可能会缩短,但我在写作时已经离开了。同时思考......本质上,你将所有单词包裹在一个跨度中,然后向后循环跨越跨度,看看它们的边界是否落入容器内,并且一旦我们找到一个跨越容器边界的跨度,在将文本返回到纯文本(删除临时跨度)后,中断循环并返回该单词。

答案 1 :(得分:2)

是的,可以使用Javascript检测正在显示的最后一个单词。

不幸的是我没有时间编写可以执行此操作的代码,但是,我将解释算法。

如果您有一个50x50的框,并且想要检测最后一个可见单词是什么,请执行以下操作:

  1. 创建一个div宽屏,其宽度为50像素,但不限制高度。对于此演示,我们将此div称为clonedDiv。
  2. 获取原始div中的字符串,并在clonedDiv中插入它的第一个单词。
  3. 检查clonedDiv的高度。
  4. 应用此逻辑:如果&lt; = 50px,则添加下一个单词,然后重试。如果它高于50px高,那么这就是导致溢出发生的词。你的答案将是上一个词。
  5. 请注意,上述算法使用强力方法查找单词。该算法基本上一次添加一个字,直到找到导致溢出的字。您可以通过使用二进制搜索算法的变体来改进这一点,这将改进算法从O(n)到O(log(n))。

答案 2 :(得分:1)

Working DEMO

here借了一个答案并稍微调整一下。

function countVisibleCharacters(element) {
    var text = element.firstChild.nodeValue;
    var r = 0;

    element.removeChild(element.firstChild);

    for(var i = 0; i < text.length; i++) {
        var newNode = document.createElement('span');
        newNode.appendChild(document.createTextNode(text.charAt(i)));
        element.appendChild(newNode);

        if(newNode.offsetLeft < element.offsetWidth) {
            r++;
        }
    }

    return r;
}

var c = countVisibleCharacters(document.getElementsByTagName('div')[0]);

var str = document.getElementById('myDiv');
str = str.textContent;
str = str.substring(0, c);
str = str.substr(str.trim().lastIndexOf(" ")+1);
alert(str);

答案 3 :(得分:1)

一种可能的解决方案:

var $div = $('div'),
    size = [$div.width(), $div.height()],
    words = $.trim($div.text()).split(/\s+/),
    word;

for (var i = 0, len = words.length; i < len; i++) {
    var $clone = $div.clone().text(words.join(' ')).insertAfter($div);
    $clone.contents().wrap('<span />');
    var $child = $clone.children('span');

    if ($child.width() <= size[0] && $child.height() <= size[1]) {
        word = words.pop();
        $clone.remove();
        break;
    }
    words.pop();
    $clone.remove();
}

console.log(word);

DEMO: http://jsfiddle.net/bcn78/

答案 4 :(得分:1)

除了@SmokeyPhp回答:

首先,这是一个很好的答案,对我有很大帮助,但那里的情况有些错误。

其次,我正在使用jqlite库而不是jQuery,因此答案在该领域也非常有用(他使用的所有方法都是jqlite库的一部分)。

除了检测跨度或div中的最后一个可见单词外,我的功能还用&#34; ...&#34;替换文本的其余部分。

我发布了我正在使用的代码,基本上是代码@SmokeyPhp发布的,但修复了需要的地方,我希望其他人也能从中受益:

function dotdotdot(containersToDotdotdot) {
    function dotdotdotContainers(containers) {
        for (var i = 0; i < containers.length; i++) {
            var cntnr = $jq(containers[i]);
            cntnr.html('<span>' + cntnr.html().replace(/ /g,'</span> <span>') + '</span>');
            var words = Array.prototype.slice.call(cntnr.find("span"), 0).reverse();
            var lastw = null;

            for (var j = 0; j < words.length; j++) {
                var w = $jq(words[j]);
                var wbot = w.height() + w.offset().top;
                var wleft = w.offset().left;
                var wright = wleft + w.width();

                if (wbot <= (cntnr.offset().top + cntnr.height()) && wleft >= (cntnr.offset().left) && wright <= (cntnr.offset().left + cntnr.width())) {
                    lastw = words.length - j - 1;
                    break;
                }
            }

            cntnr.html(lastw === null || lastw === (words.length - 1) ? cntnr.text() : (cntnr.text().split(' ').slice(0, lastw).join(' ') + '...'));
        }
    }

    if (containersToDotdotdot instanceof Array) {
        for (var i = 0; i < containersToDotdotdot.length; i++) {
            dotdotdotContainers($jq(containersToDotdotdot[i]));
        }
    } else {
        dotdotdotContainers($jq(containersToDotdotdot));
    }
}

正如您所看到的,我的dotdotdot函数可以获取dotdotdot的类/ ID数组,或者单个类/ id。

$ jq是jQuery&#39; s $。

的jqlite替代品

感谢@SmokeyPhp,我找了很长时间来寻找一个不需要jQuery到dotdotdot文本的方法,而且你的方法太棒了。

答案 5 :(得分:0)

我完成了你的工作如下......

function Searchinput()
{
var str = "This is a test "; // Content of the div
var lastWord = str.substr(str.trim().lastIndexOf(" ")+1);
  alert(lastWord)
}

http://jsbin.com/UWUTar/1/edit