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

后端 未结 24 2788
名媛妹妹
名媛妹妹 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 11:08

    Here's another JavaScript solution. Works very good and very fast.

    https://github.com/dobiatowski/jQuery.FastEllipsis

    Tested on Chrome, FF, IE on Windows and Mac.

    0 讨论(0)
  • 2020-11-22 11:08

    This is similar to Alex's but does it in log time instead of linear, and takes a maxHeight parameter.

    jQuery.fn.ellipsis = function(text, maxHeight) {
      var element = $(this);
      var characters = text.length;
      var step = text.length / 2;
      var newText = text;
      while (step > 0) {
        element.html(newText);
        if (element.outerHeight() <= maxHeight) {
          if (text.length == newText.length) {
            step = 0;
          } else {
            characters += step;
            newText = text.substring(0, characters);
          }
        } else {
          characters -= step;
          newText = newText.substring(0, characters);
        }
        step = parseInt(step / 2);
      }
      if (text.length > newText.length) {
        element.html(newText + "...");
        while (element.outerHeight() > maxHeight && newText.length >= 1) {
          newText = newText.substring(0, newText.length - 1);
          element.html(newText + "...");
        }
      }
    };
    
    0 讨论(0)
  • 2020-11-22 11:08

    I couldn't find a script that worked exactly as I wanted it so did my own for jQuery - quite a few options to set with more on their way :)

    https://github.com/rmorse/AutoEllipsis

    0 讨论(0)
  • 2020-11-22 11:08

    Here is a nice widget/plugin library which has ellipsis built in: http://www.codeitbetter.co.uk/widgets/ellipsis/ All you need to do it reference the library and call the following:

    <script type="text/javascript"> 
       $(document).ready(function () { 
          $(".ellipsis_10").Ellipsis({ 
             numberOfCharacters: 10, 
             showLessText: "less", 
             showMoreText: "more" 
          }); 
       }); 
    </script> 
    <div class="ellipsis_10"> 
       Some text here that's longer than 10 characters. 
    </div>
    
    0 讨论(0)
  • 2020-11-22 11:08
    <html>
    <head>
        <!-- By Warren E. Downs, copyright 2016.  Based loosely on a single/multiline JQuery using example by Alex,
        but optimized to avoid JQuery, to use binary search, to use CSS text-overflow: ellipsis for end,
        and adding marquee option as well.
        Credit: Marquee: http://jsfiddle.net/jonathansampson/xxuxd/
                JQuery version: http://stackoverflow.com/questions/536814/insert-ellipsis-into-html-tag-if-content-too-wide
                (by Alex, http://stackoverflow.com/users/71953/alex)
                (Improved with Binary Search as suggested by StanleyH, http://stackoverflow.com/users/475848/stanleyh)
        -->
        <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
        <meta content="utf-8" http-equiv="encoding">
        <style>
    
            .single {
                overflow:hidden;
                white-space: nowrap;
                width: 10em;
                padding: 10px;
                margin: 0 auto;
                border: solid 1px blue;
            }
    
            .multiline {
                overflow: hidden;
                white-space: wrap;
                width: 10em;
                height: 4.5em;
                padding: 10px;
                margin: 0 auto;
                border: solid 1px blue;
            }
    
            .marquee {
                overflow: hidden;
                width: 40em;
                padding: 10px;
                margin: 0 auto;
                border: solid 1px blue;
            }
    
    </style>
        <script>
            var _marqueeNumber=0;
            // mode=start,end,middle
            function clipText(text, len, mode) {
                if(!mode) { mode="end"; }
                else { mode=mode.toLowerCase(); }
                if(mode == "start") { return "&hellip;"+clipText(text,len,"_start"); }
                if(mode == "_start") { return text.substr(text.length - len); }
                if(mode == "middle") { 
                    return clipText(text, len/2, "end") + clipText(text, len/2, "_start");
                }
                return text.substr(0, len) + "&hellip;";
            }
    
            function generateKeyframes(clsName, start, end) {
                var sec=5;
                var totalLen=parseFloat(start)-parseFloat(end);
                if(start.indexOf('em') > -1)      { sec=Math.round(totalLen/3); }
                else if(start.indexOf('px') > -1) { sec=Math.round(totalLen/42); }
    
                var style = document.createElement('style');
                style.type = 'text/css';
                style.innerHTML = 'body {}';
                document.getElementsByTagName('head')[0].appendChild(style);
                this.stylesheet = document.styleSheets[document.styleSheets.length-1];
                try {
                    this.stylesheet.insertRule('.'+clsName+' {\n'+
                        '    animation: '+clsName+' '+sec+'s linear infinite;\n'+
                        '}\n', this.stylesheet.rules.length);
                    this.stylesheet.insertRule('.'+clsName+':hover {\n'+
                        '    animation-play-state: paused\n'+
                        '}\n', this.stylesheet.rules.length);
                    this.stylesheet.insertRule('@keyframes '+clsName+' {\n'+
                        '    0%   { text-indent: '+start+' }\n'+
                        '    100% { text-indent: '+end+' }\n'+
                        '}', this.stylesheet.rules.length);
                } catch (e) {
                    console.log(e.message);
                }
            }
    
            function addClone(el, multiline, estyle) {
                if(!estyle) { 
                    try { estyle=window.getComputedStyle(el); }
                    catch(e) { return null; }
                }
                var t = el.cloneNode(true);
                var s=t.style;
                //s.display='none';
                s.visibility='hidden'; // WARNING: Infinite loop if this is not hidden (e.g. while testing)
                s.display='inline-block';
                s.background='black';
                s.color='white';
                s.position='absolute';
                s.left=0;
                s.top=0;
                s.overflow='visible';
                s.width=(multiline ? parseFloat(estyle.width) : 'auto');
                s.height=(multiline ? 'auto' : parseFloat(estyle.height));
    
                el.parentNode.insertBefore(t, el.nextSibling);
    
                return t;
            }
            function getTextWidth(el, multiline) {
                var t=addClone(el, multiline);
                if(!t) { return null; }
                var ts=window.getComputedStyle(t);
                var w=ts.width;
                if(multiline) {
                    var es=window.getComputedStyle(el);
                    var lines=Math.round(parseInt(ts.height)/parseInt(es.height))*2+0.5;
                    w=w+'';
                    var unit=''; // Extract unit
                    for(var xa=0; xa<w.length; xa++) {
                        var c=w[xa];
                        if(c <= '0' || c >= '9') { unit=w.substr(xa-1); }
                    }
                    w=parseFloat(w);
                    w*=lines; // Multiply by lines
                    w+=unit; // Append unit again
                }
                t.parentNode.removeChild(t);
                return w;
            }
    
            // cls=class of element to ellipsize
            // mode=start,end,middle,marq (scrolling marquee instead of clip)
            function ellipsis(cls, mode) {
                mode=mode.toLowerCase();
                var elems=document.getElementsByClassName(cls);
                for(xa in elems) {
                    var el=elems[xa];
                    var multiline = el.className ? el.className.indexOf('multiline') > -1 : true;
                    if(mode == "marq") {       
                        var w=getTextWidth(el, multiline);
                        if(!w) { continue; }
                        var mCls="dsmarquee"+(_marqueeNumber++);
                        var es=window.getComputedStyle(el);
                        generateKeyframes(mCls,es.width, '-'+w);
                        el.className+=" "+mCls; 
                        continue; 
                    }
                    if(mode == "end" && !multiline) { el.style.textOverflow="ellipsis"; continue; }
                    var estyle=null;
                    try { estyle=window.getComputedStyle(el); }
                    catch(e) { continue; }
                    if(estyle.overflow == "hidden") {
                        var text = el.innerHTML;
                        var t=addClone(el, multiline, estyle);
    
                        function height() {
                            var ts=window.getComputedStyle(t);
                            var es=window.getComputedStyle(el);
                            return parseFloat(ts.height) - parseFloat(es.height); 
                        }
                        function width() { 
                            var ts=window.getComputedStyle(t);
                            var es=window.getComputedStyle(el);
                            return parseFloat(ts.width) - parseFloat(es.width); 
                        }
    
                        var tooLong = multiline ? height : width;
    
                        var len=text.length;
                        var diff=1;
                        var olen=0;
                        var jump=len/2;
                        while (len > 0) {
                            var diff=tooLong();
                            if(diff > 0) { len-=jump; jump/=2; }
                            else if(diff < 0) { len+=jump; }
                            len=Math.round(len);
                            //alert('len='+len+';olen='+olen+';diff='+diff+';jump='+jump+';t='+JSON.stringify(t.innerHTML));
                            t.innerHTML=clipText(text, len, mode);
                            if(olen == len) { break; }
                            olen=len;
                        }
                        el.innerHTML=t.innerHTML;
                        t.parentNode.removeChild(t);
                    }           
                    //break;
                    t.style.visibility='hidden';
                }
            }
    
            function testHarness() {
                ellipsis('ellipsis1', 'start'); 
                ellipsis('ellipsis2', 'end'); 
                ellipsis('ellipsis3', 'middle'); 
                ellipsis('marquee', 'marq')
            }
        </script>
        </head>
        <body onload="testHarness()">
        <div class="single ellipsis1" style="float:left">some long text that should be clipped left</div>
        <div class="single ellipsis2" style="float:right">right clip long text that should be clipped</div>
        <div class="single ellipsis3" style="float:center">some long text that should be clipped in the middle</div>
    
        <br />
    
        <p class="single marquee">Windows 8 and Windows RT are focused on your life—your friends and family, your apps, and your stuff. With new things like the <a href="http://windows.microsoft.com/en-US/windows-8/start-screen">Start screen</a>, <a href="http://windows.microsoft.com/en-US/windows-8/charms">charms</a>, and a <a href="http://windows.microsoft.com/en-US/windows-8/microsoft-account">Microsoft account</a>, you can spend less time searching and more time doing.</p>
        &nbsp;
    
        <br />
    
        <div class="multiline ellipsis1" style="float:left">Test test test test test test, some more long text, such as asdasdasdasdasd, that should be multiline clipped left(*)</div>
    
        <div class="multiline ellipsis2" style="float:right">right clip multiline long text, such as Test test test test test test, and some more long text that should be multiline clipped right.</div>
    
        <div class="multiline ellipsis3" style="float:center">Test test test test test test, some more long text, such as asdasdasdasdasd, that should be multiline clipped in the middle(*)</div>
    
        <br />
    
        <p class="multiline marquee">Multiline Marquee: Windows 8 and Windows RT are focused on your life—your friends and family, your apps, and your stuff. With new things like the <a href="http://windows.microsoft.com/en-US/windows-8/start-screen">Start screen</a>, <a href="http://windows.microsoft.com/en-US/windows-8/charms">charms</a>, and a <a href="http://windows.microsoft.com/en-US/windows-8/microsoft-account">Microsoft account</a>, you can spend less time searching and more time doing.</p>
        &nbsp;
    
        </body>
    </html>
    
    0 讨论(0)
  • 2020-11-22 11:10

    Just like @acSlater I couldn't find something for what I needed so I rolled my own. Sharing in case anyone else can use:

    Method:
    ellipsisIfNecessary(mystring,maxlength);
    
    Usage:
    trimmedString = ellipsisIfNecessary(mystring,50);
    
    Code and Demo Link: https://gist.github.com/cemerson/10368014
    0 讨论(0)
提交回复
热议问题