优化jQuery插件以根据容器大小截断文本

时间:2016-07-30 23:50:15

标签: javascript jquery optimization

我不是javascript或者jQuery最热衷的东西,但我对它们了如指掌。我整理了一个快速插件,我可以放入我的任何网站,动态地截断容器的文本,而不实际删除文本。

因此,如果我有一个600x600像素的容器,我希望文本很好地适应那里,当需要切断时,在最后一个单词之后添加....

我找不到真正做到这一点的任何内容,所以我创建了以下插件。

它有效,它的效果非常好,唯一的问题是它很慢。只是因为如果经过每一行文字。

有没有办法优化这一点而不会失去功能?

// To work the parent div to class .jFit must have it's height defined.
// Stylized spans may cause problems.

$(function() {
    $('.jFit').each(function() {
        $(this).jFit();
    });
});

var resizeTimer;
$(window).on('resize', function(e) {
    clearTimeout(resizeTimer);
    resizeTimer = setTimeout(function() {
        $('.jFit').each(function() {
            $(this).jFit(true);
        });
    }, 150);
});


jQuery.fn.jFit = function(resize = false) {
    var parentHeight = $(this).parent().height(),
        maxHeight = parentHeight,
        height = 0,
        char = 0,
        i = 1,
        str = '',
        last = 0;

    $(this).siblings().each(function() {
        maxHeight -= $(this).outerHeight();
        maxHeight -= parseInt($(this).css('margin-top'));
        maxHeight -= parseInt($(this).css('margin-bottom'));
    });

    if (resize) {
        $(this).find('.jFit-ellipsis').remove();
        var span = $(this).find('.jFit-hide'),
            contents = span.html();
        span.remove();
        $(this).append(contents);
    }

    while ((str = $(this).line(i))['text'] != "") {
        height += str['lineHeight'];
        if (maxHeight > height) {
            char += str['text'].length;
            last = str['text'].length - $.trim(str['text']).lastIndexOf(' ');
            i++;
        } else {
            break;
        }
    }

    if ($.trim(str['text']).lastIndexOf(' ')<0) {
        char -= str['text'].length;
        str['text'] = $(this).line(i-1 | 0)['text'];

        if (str['text'].match('<br\s*\/?>$')) {
            char -= str['text'].length;
            char += str['text'].lastIndexOf('<');
        }
        last = 0;
    }

    if (str['text'].match('/(.|,|;|:)$/')) {
        last += 1;
    }

    if (str['text']!='') {
        $(this).html($(this).html().substring(0,char-(last))+'<span class="jFit-ellipsis">...</span><span class="jFit-hide" style="display: none;">'+$(this).html().substring(char-(last)));
        $(this).append('</span>');
    }
}

jQuery.fn.line = function(line) {
    var dummy = this.clone().css({
        top: -9999,
        left: -9999,
        position: 'absolute',
        width: this.width()
    }).appendTo(this.parent());
    var text = dummy.html().match(/(<.*?span[^>]*>|<br.*?>|[\w\.\,]+[\s\.\,])/g);

    var words = text.length,
        lastTopOffset = 0,
        lineNumber = 0,
        lineHeight = 0,
        ret = '',
        found = false;

    for (var i = 0; i < words; ++i) {
        dummy.html(
            text.slice(0,i).join('') +
            text[i].replace(/(\S)/, '$1<span id="jFit-lh" style="line-height:inherit;"/>') +
            text.slice(i+1).join('')
        );

        var topOffset = jQuery('#jFit-lh', dummy).offset().top;
        lineHeight = $('#jFit-lh').height();
        if (topOffset !== lastTopOffset) {
            lineNumber += 1;
        }
        lastTopOffset = topOffset;

        if (lineNumber === line) {
            found = true;
            ret += text[i];
        } else {
            if (found) {
                break;
            }
        }
    }

    dummy.remove();
    return {text:ret,lineHeight:lineHeight};
}

0 个答案:

没有答案