Insert ellipsis (…) into HTML tag if content too wide

后端 未结 24 2804
名媛妹妹
名媛妹妹 2020-11-22 10:07

I have a webpage with an elastic layout that changes its width if the browser window is resized.

In this layout there are headlines (h2) that will have

相关标签:
24条回答
  • 2020-11-22 10:43

    I built this code using a number of other posts, with the following enhancements:

    1. It uses a binary search to find the text length that is just right.
    2. It handles cases where the ellipsis element(s) are initially hidden by setting up a one-shot show event that re-runs the ellipsis code when the item is first displayed. This is handy for master-detail views or tree-views where some items aren't initially displayed.
    3. It optionally adds a title attribute with the original text for a hoverover effect.
    4. Added display: block to the style, so spans work
    5. It uses the ellipsis character instead of 3 periods.
    6. It auto-runs the script for anything with the .ellipsis class

    CSS:

    .ellipsis {
            white-space: nowrap;
            overflow: hidden;
            display: block;
    }
    
    .ellipsis.multiline {
            white-space: normal;
    }
    

    jquery.ellipsis.js

    (function ($) {
    
        // this is a binary search that operates via a function
        // func should return < 0 if it should search smaller values
        // func should return > 0 if it should search larger values
        // func should return = 0 if the exact value is found
        // Note: this function handles multiple matches and will return the last match
        // this returns -1 if no match is found
        function binarySearch(length, func) {
            var low = 0;
            var high = length - 1;
            var best = -1;
            var mid;
    
            while (low <= high) {
                mid = ~ ~((low + high) / 2); //~~ is a fast way to convert something to an int
                var result = func(mid);
                if (result < 0) {
                    high = mid - 1;
                } else if (result > 0) {
                    low = mid + 1;
                } else {
                    best = mid;
                    low = mid + 1;
                }
            }
    
            return best;
        }
    
        // setup handlers for events for show/hide
        $.each(["show", "toggleClass", "addClass", "removeClass"], function () {
    
            //get the old function, e.g. $.fn.show   or $.fn.hide
            var oldFn = $.fn[this];
            $.fn[this] = function () {
    
                // get the items that are currently hidden
                var hidden = this.find(":hidden").add(this.filter(":hidden"));
    
                // run the original function
                var result = oldFn.apply(this, arguments);
    
                // for all of the hidden elements that are now visible
                hidden.filter(":visible").each(function () {
                    // trigger the show msg
                    $(this).triggerHandler("show");
                });
    
                return result;
            };
        });
    
        // create the ellipsis function
        // when addTooltip = true, add a title attribute with the original text
        $.fn.ellipsis = function (addTooltip) {
    
            return this.each(function () {
                var el = $(this);
    
                if (el.is(":visible")) {
    
                    if (el.css("overflow") === "hidden") {
                        var content = el.html();
                        var multiline = el.hasClass('multiline');
                        var tempElement = $(this.cloneNode(true))
                            .hide()
                            .css('position', 'absolute')
                            .css('overflow', 'visible')
                            .width(multiline ? el.width() : 'auto')
                            .height(multiline ? 'auto' : el.height())
                        ;
    
                        el.after(tempElement);
    
                        var tooTallFunc = function () {
                            return tempElement.height() > el.height();
                        };
    
                        var tooWideFunc = function () {
                            return tempElement.width() > el.width();
                        };
    
                        var tooLongFunc = multiline ? tooTallFunc : tooWideFunc;
    
                        // if the element is too long...
                        if (tooLongFunc()) {
    
                            var tooltipText = null;
                            // if a tooltip was requested...
                            if (addTooltip) {
                                // trim leading/trailing whitespace
                                // and consolidate internal whitespace to a single space
                                tooltipText = $.trim(el.text()).replace(/\s\s+/g, ' ');
                            }
    
                            var originalContent = content;
    
                            var createContentFunc = function (i) {
                                content = originalContent.substr(0, i);
                                tempElement.html(content + "…");
                            };
    
                            var searchFunc = function (i) {
                                createContentFunc(i);
                                if (tooLongFunc()) {
                                    return -1;
                                }
                                return 0;
                            };
    
                            var len = binarySearch(content.length - 1, searchFunc);
    
                            createContentFunc(len);
    
                            el.html(tempElement.html());
    
                            // add the tooltip if appropriate
                            if (tooltipText !== null) {
                                el.attr('title', tooltipText);
                            }
                        }
    
                        tempElement.remove();
                    }
                }
                else {
                    // if this isn't visible, then hook up the show event
                    el.one('show', function () {
                        $(this).ellipsis(addTooltip);
                    });
                }
            });
        };
    
        // ellipsification for items with an ellipsis
        $(document).ready(function () {
            $('.ellipsis').ellipsis(true);
        });
    
    } (jQuery));
    
    0 讨论(0)
  • 2020-11-22 10:44

    There is a simple jQuery solution by Devon Govett:

    https://gist.github.com/digulla/5796047

    To use, just call ellipsis() on a jQuery object. For example:

    $("span").ellipsis();

    0 讨论(0)
  • 2020-11-22 10:45

    There's actually a pretty straightforward way to do this in CSS exploiting the fact that IE extends this with non-standards and FF supports :after

    You can also do this in JS if you wish by inspecting the scrollWidth of the target and comparing it to it's parents width, but imho this is less robust.

    Edit: this is apparently more developed than I thought. CSS3 support may soon exist, and some imperfect extensions are available for you to try.

    • http://www.css3.info/preview/text-overflow/
    • http://ernstdehaan.blogspot.com/2008/10/ellipsis-in-all-modern-browsers.html

    That last one is good reading.

    0 讨论(0)
  • 2020-11-22 10:47

    I made a really cool jQuery plugin for handling all varieties of ellipsis of text is one called ThreeDots @ http://tpgblog.com/threedots

    It's much more flexible than the CSS approaches, and supports much more advanced, customizable behaviors and interactions.

    Enjoy.

    0 讨论(0)
  • 2020-11-22 10:47

    I'd done something similar for a client recently. Here's a version of what I did for them (example tested in all latest browser versions on Win Vista). Not perfect all around the board, but could be tweaked pretty easily.

    Demo: http://enobrev.info/ellipsis/

    Code:

    <html>
        <head>
            <script src="http://www.google.com/jsapi"></script>
            <script>            
                google.load("jquery", "1.2.6");
                google.setOnLoadCallback(function() {
                    $('.longtext').each(function() {
                        if ($(this).attr('scrollWidth') > $(this).width()) {
                            $more = $('<b class="more">&hellip;</b>');
    
                            // add it to the dom first, so it will have dimensions
                            $(this).append($more);
    
                            // now set the position
                            $more.css({
                                top: '-' + $(this).height() + 'px',
                                left: ($(this).attr('offsetWidth') - $more.attr('offsetWidth')) + 'px'
                            });
                        }
                    });
                });
            </script>
    
            <style>
                .longtext {
                    height: 20px;
                    width: 300px;
                    overflow: hidden;
                    white-space: nowrap;
                    border: 1px solid #f00;
                }
    
                .more {
                    z-index: 10;
                    position: relative;
                    display: block;
                    background-color: #fff;
                    width: 18px;
                    padding: 0 2px;
                }
            </style>
        </head>
        <body>
            <p class="longtext">This is some really long text.  This is some really long text.  This is some really long text.  This is some really long text.</p>
        </body>
    </html>
    
    0 讨论(0)
  • 2020-11-22 10:48

    trunk8 jQuery plugin supports multiple lines, and can use any html, not just ellipsis characters, for the truncation suffix: https://github.com/rviscomi/trunk8

    Demo here: http://jrvis.com/trunk8/

    0 讨论(0)
提交回复
热议问题