Inserire i puntini di sospensione (...) nel tag HTML se il contenuto è troppo ampio


148

Ho una pagina web con un layout elastico che cambia la sua larghezza se la finestra del browser viene ridimensionata.

In questo layout ci sono titoli ( h2) che avranno una lunghezza variabile (in realtà essendo titoli di blogposts sui quali non ho controllo). Attualmente, se sono più larghi della finestra, sono suddivisi in due righe.

Esiste una soluzione elegante, testata (tra browser), ad esempio con jQuery, che accorcia l'HTML interno del tag del titolo e aggiunge "..." se il testo fosse troppo largo per adattarsi a una riga nella schermata corrente / larghezza del contenitore?


1
Risposta aggiornata 2014: stackoverflow.com/a/22811590/759452
Adrien Be

Ho creato plugin basati su questo thread che utilizza le proprietà CSS white-space e word-wrap per formattare il testo. github.com/nothrem/jQuerySmartEllipsis
Radek Pech

Risposte:


119

Ho una soluzione che funziona in FF3, Safari e IE6 + con testo singolo e multilinea

.ellipsis {
    white-space: nowrap;
    overflow: hidden;
}

.ellipsis.multiline {
    white-space: normal;
}

<div class="ellipsis" style="width: 100px; border: 1px solid black;">Lorem ipsum dolor sit amet, consectetur adipisicing elit</div>
<div class="ellipsis multiline" style="width: 100px; height: 40px; border: 1px solid black; margin-bottom: 100px">Lorem ipsum dolor sit amet, consectetur adipisicing elit</div>

<script type="text/javascript" src="/js/jquery.ellipsis.js"></script>
<script type="text/javascript">
$(".ellipsis").ellipsis();
</script>

jquery.ellipsis.js

(function($) {
    $.fn.ellipsis = function()
    {
        return this.each(function()
        {
            var el = $(this);

            if(el.css("overflow") == "hidden")
            {
                var text = el.html();
                var multiline = el.hasClass('multiline');
                var t = $(this.cloneNode(true))
                    .hide()
                    .css('position', 'absolute')
                    .css('overflow', 'visible')
                    .width(multiline ? el.width() : 'auto')
                    .height(multiline ? 'auto' : el.height())
                    ;

                el.after(t);

                function height() { return t.height() > el.height(); };
                function width() { return t.width() > el.width(); };

                var func = multiline ? height : width;

                while (text.length > 0 && func())
                {
                    text = text.substr(0, text.length - 1);
                    t.html(text + "...");
                }

                el.html(t.html());
                t.remove();
            }
        });
    };
})(jQuery);

22
Bene, ho cercato di gestire l'overflow con più linee. Un miglioramento: invece di aggiungere tre punti, aggiungi il carattere con i puntini di sospensione, "...".
Simon Lieschke,

4
Funziona molto bene Dovresti pubblicarlo sul sito jQuery.
Edgar,

1
Sebbene in IE se la funzione dei puntini di sospensione sia applicata su un div che ha solo un collegamento, dopo i puntini di sospensione il collegamento scompare. Qualche suggerimento su questo?
Chantz,

6
Se vuoi vederlo in azione, puoi vederlo qui (scusami per la formattazione errata
Dan Esparza,

22
Per migliorare le prestazioni, esegui una ricerca binaria invece di rimuovere 1 carattere alla volta nel ciclo "while". Se il 100% del testo non si adatta, prova il 50% del testo; quindi il 75% del testo se il 50% si adatta, o il 25% se il 50% non si adatta, ecc.
StanleyH

182

La seguente soluzione CSS unica per troncare il testo su una sola riga funziona con tutti i browser elencati su http://www.caniuse.com al momento della scrittura, ad eccezione di Firefox 6.0. Si noti che JavaScript è totalmente inutile a meno che non sia necessario supportare il wrapping di testo multilinea o versioni precedenti di Firefox.

.ellipsis {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    -o-text-overflow: ellipsis;
}

Se hai bisogno di supporto per le versioni precedenti di Firefox, controlla la mia risposta su questa altra domanda .


2
Questo è ordini di grandezza più rapidi dell'approccio jQuery. Funziona bene su IE7 + e Chrome.
JDB ricorda ancora Monica il

3
Funziona bene anche con i browser antichi. Lo usavamo con successo su Google nel 2004, dove ci veniva richiesto di supportare o degradare con grazia su alcuni browser davvero angolari.
ElBel,

2
JS Fiddle per coloro che vogliono campionarlo su un browser - jsfiddle.net/r39Ad
Deepak Bala

@DilipRajkumar dovrai fornire maggiori dettagli, ad esempio un esempio di JSFiddle che dimostra che non funziona in IE 8.
Simon Lieschke

1
@SharpCoder non lo fai. Il punto in cui il testo viene troncato è dettato dalla larghezza dell'elemento che lo contiene, ovvero si tronca quando traboccarebbe la larghezza dell'elemento.
Simon Lieschke,

40

Ho creato questo codice usando una serie di altri post, con i seguenti miglioramenti:

  1. Usa una ricerca binaria per trovare la lunghezza del testo giusta.
  2. Gestisce i casi in cui gli elementi dei puntini di sospensione sono inizialmente nascosti impostando un evento di show one-shot che esegue nuovamente il codice dei puntini di sospensione quando l'elemento viene visualizzato per la prima volta. Questo è utile per le viste di dettaglio principale o le viste ad albero in cui alcuni elementi non sono inizialmente visualizzati.
  3. Aggiunge facoltativamente un attributo title con il testo originale per un effetto hoverover.
  4. Aggiunto display: blockallo stile, quindi le campate funzionano
  5. Usa il carattere con i puntini di sospensione anziché 3 punti.
  6. Esegue automaticamente lo script per qualsiasi cosa con la classe .ellipsis

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));

2
Bellissimo. Bravo per aver implementato il mio suggerimento di una ricerca binaria.
StanleyH

2
Solo una breve nota ... vale la pena aggiungere .css ('max-width', 'none') alla tempElement var ... In questo modo puoi usare una dichiarazione di max-width nel tuo css, rendendo il plugin molto più flessibile (almeno per la maggior parte dei casi d'uso che ho). Bel lavoro comunque. :)
gordyr,

3
Questa è un'implementazione molto più rapida della risposta accettata sopra. Se hai più elementi .ellipsis e stai facendo qualcosa di dinamico con loro, questo si comporta molto meglio.
mjvotaw,

Potete per favore fornire un esempio? La mia domanda è qui: stackoverflow.com/questions/26344520/…
SearchForKnowledge

La ricerca binaria è preferibile ma non con set di dati molto piccoli e in questo caso ostacola le prestazioni rispetto a una ricerca lineare diretta come indexOf () ... apparentemente
user1360809

20

La mia risposta supporta solo testo a riga singola. Guarda il commento di gfullam qui sotto per la forcella multi-linea, sembra abbastanza promettente.

Ho riscritto il codice dalla prima risposta alcune volte e penso che questo dovrebbe essere il più veloce.

Prima trova una lunghezza del testo "stimata", quindi aggiunge o rimuove un carattere fino a quando la larghezza non è corretta.

La logica che utilizza è mostrata di seguito:

inserisci qui la descrizione dell'immagine

Dopo aver trovato una lunghezza "stimata" del testo, i caratteri vengono aggiunti o rimossi fino a raggiungere la larghezza desiderata.

Sono sicuro che ha bisogno di qualche modifica, ma ecco il codice:

(function ($) {
    $.fn.ellipsis = function () {
        return this.each(function () {
            var el = $(this);

            if (el.css("overflow") == "hidden") {
                var text = el.html().trim();
                var t = $(this.cloneNode(true))
                                        .hide()
                                        .css('position', 'absolute')
                                        .css('overflow', 'visible')
                                        .width('auto')
                                        .height(el.height())
                                        ;
                el.after(t);

                function width() { return t.width() > el.width(); };

                if (width()) {

                    var myElipse = "....";

                    t.html(text);

                    var suggestedCharLength = (text.length * el.width() / t.width()) - myElipse.length;

                    t.html(text.substr(0, suggestedCharLength) + myElipse);

                    var x = 1;
                    if (width()) {
                        while (width()) {
                            t.html(text.substr(0, suggestedCharLength - x) + myElipse);
                            x++;
                        }
                    }
                    else {
                        while (!width()) {
                            t.html(text.substr(0, suggestedCharLength + x) + myElipse);
                            x++;
                        }
                        x--;
                        t.html(text.substr(0, suggestedCharLength + x) + myElipse);
                    }

                    el.html(t.html());
                    t.remove();
                }
            }
        });
    };
})(jQuery);

3
La tua soluzione potrebbe non essere la migliore, ma è molto ben spiegata. E mi piace questo tipo di logica di approssimazione. +1 :)
Flater,

2
L'ho modificato per aggiungere supporto per textareas e troncamento ellittico multilinea (verticale): jsfiddle.net/gfullam/j29z7381 (Mi piace la logica di approssimazione BTW)
gfullam

19

Nel caso in cui finirete tutti qui nel 2013, ecco un approccio css puro che ho trovato qui: http://css-tricks.com/snippets/css/truncate-string-with-ellipsis/

.truncate {
  width: 250px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

Funziona bene.


1
FWIW, text-overflownon funziona con gli textareaelementi (a partire dal 2015). Se hai bisogno di supporto textarea, puoi ottenerlo modificando la risposta accettata o usando questo fork di essa .
gfullam,

18

Ho creato un plug-in jQuery davvero interessante per gestire tutte le varietà di ellissi di testo che si chiama ThreeDots @ http://tpgblog.com/threedots

È molto più flessibile degli approcci CSS e supporta comportamenti e interazioni molto più avanzati e personalizzabili.

Godere.


8

Un plug-in jQuery più flessibile che consente di mantenere un elemento dopo i puntini di sospensione (ad esempio un pulsante "leggi altro") e di aggiornare suWindowResize. Funziona anche attorno al testo con markup:

http://dotdotdot.frebsite.nl


Ho appena testato questo plugin, ma non sono riuscito a farlo funzionare. Trunk8 è stata una scelta migliore per me.
Guilherme Garnier,


5

In realtà c'è un modo abbastanza semplice per farlo in CSS sfruttando il fatto che IE lo estende con non standard e supporti FF:after

Puoi anche farlo in JS, se lo desideri, ispezionando scrollWidth del target e confrontandolo con la larghezza dei genitori, ma questo è meno robusto.

Modifica: questo è apparentemente più sviluppato di quanto pensassi. Il supporto CSS3 potrebbe presto esistere e alcune estensioni imperfette sono disponibili per te da provare.

Quest'ultima è una buona lettura.


In realtà preferisco la soluzione JS, perché aggiunge "..." solo se il testo è più ampio dello spazio disponibile.
BlaM,

3

Di recente avevo fatto qualcosa di simile per un cliente. Ecco una versione di quello che ho fatto per loro (esempio testato in tutte le ultime versioni del browser su Win Vista). Non perfetto su tutta la linea, ma potrebbe essere modificato abbastanza facilmente.

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

Codice:

<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>

3

Bene, una soluzione semplice, che non aggiunge del tutto il "...", ma impedisce a <h2> di dividersi in due righe sarebbe quella di aggiungere questo bit di css:

h2 {
    height:some_height_in_px; /* this is the height of the line */
    overflow:hidden; /* so that the second (or third, fourth, etc.)
                        line is not visible */
}

Ci ho pensato un po 'di più, e ho trovato questa soluzione, devi avvolgere i contenuti testuali del tuo tag h2 con un altro tag (ad esempio uno span) (o in alternativa avvolgere gli h2 con qualcosa che abbia l'altezza data) e quindi puoi usare questo tipo di javascript per filtrare le parole non necessarie:

var elems = document.getElementById('conainter_of_h2s').
                     getElementsByTagName('h2');

    for ( var i = 0, l = elems.length; i < l; i++) {
        var span = elems.item(i).getElementsByTagName('span')[0];
        if ( span.offsetHeight > elems.item(i).offsetHeight ) {
            var text_arr = span.innerHTML.split(' ');
            for ( var j = text_arr.length - 1; j>0 ; j--) {
                delete text_arr[j];
                span.innerHTML = text_arr.join(' ') + '...';
                if ( span.offsetHeight <= 
                                        elems.item(i).offsetHeight ){
                    break;
                }
            }
        }
    }

In realtà ho pensato di utilizzare questo come base per una possibile soluzione, ma non ho idea se - in base a questo - sarebbe possibile scoprire, se l'intero testo è ora visualizzato o se devo accorciarlo e aggiungere " ... ". Basta tagliarlo sembrerebbe strano.
BlaM,


3

C'è una soluzione per il testo multilinea con CSS puro. È chiamatoline-clamp , ma funziona solo nei browser webkit. C'è comunque un modo per imitare questo in tutti i browser moderni (tutto più recente di IE8.) Inoltre, funzionerà solo su sfondi solidi perché è necessaria un'immagine di sfondo per nascondere le ultime parole dell'ultima riga. Ecco come va:

Dato questo HTML:

<p class="example" id="example-1">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>

Ecco il CSS:

p {
    position:relative;
    line-height:1.4em;
    height:4.2em;      /* 3 times the line-height to show 3 lines */
}
p::after {
    content:"...";
    font-weight:bold;
    position:absolute;
    bottom:0;
    right:0;
    padding:0 20px 1px 45px;
    background:url(ellipsis_bg.png) repeat-y;
}

ellipsis_bg.png essendo un'immagine dello stesso colore del tuo sfondo, che sarebbe larga circa 100px e avrebbe la stessa altezza della tua altezza della linea.

Non è molto carino, poiché il testo potrebbe essere tagliato nel mezzo di una lettera, ma può essere utile in alcuni casi.

Riferimento: http://www.css-101.org/articles/line-clamp/line-clamp_for_non_webkit-based_browsers.php


È carino, ma devi essere sicuro che il tuo testo sia abbastanza lungo, perché questo CSS aggiungerà "..." anche se il testo è abbastanza corto da adattarsi allo spazio disponibile. A proposito: la stessa risposta è stata fornita da Apopii circa un mese fa;)
BlaM

@BlaM Praticamente lo stesso in effetti. Ma penso che il trucco del gradiente sia pulito e questo codice in CSS invece di SASS, quindi penso che sia degno di essere una risposta separata.
Jules Colle,

3

Ellissi multilinea CSS pura per contenuti di testo:

.container{
    position: relative;  /* Essential */
    background-color: #bbb;  /* Essential */
    padding: 20px; /* Arbritrary */
}
.text {
    overflow: hidden;  /* Essential */
    /*text-overflow: ellipsis; Not needed */
    line-height: 16px;  /* Essential */
    max-height: 48px; /* Multiples of line-height */
}
.ellipsis {
    position: absolute;/* Relies on relative container */
    bottom: 20px; /* Matches container padding */
    right: 20px; /* Matches container padding */
    height: 16px; /* Matches line height */
    width: 30px; /* Arbritrary */
    background-color: inherit; /* Essential...or specify a color */
    padding-left: 8px; /* Arbritrary */
}
<div class="container">
    <div class="text">
        Lorem ipsum dolor sit amet, consectetur eu in adipiscing elit. Aliquam consectetur venenatis blandit. Praesent vehicula, libero non pretium vulputate, lacus arcu facilisis lectus, sed feugiat tellus nulla eu dolor. Nulla porta bibendum lectus quis euismod. Aliquam volutpat ultricies porttitor. Cras risus nisi, accumsan vel cursus ut, sollicitudin vitae dolor. Fusce scelerisque eleifend lectus in bibendum. Suspendisse lacinia egestas felis a volutpat. Aliquam volutpat ultricies porttitor. Cras risus nisi, accumsan vel cursus ut, sollicitudin vitae dolor. Fusce scelerisque eleifend lectus in bibendum. Suspendisse lacinia egestas felis a volutpat.
    </div>
    <div class="ellipsis">...</div>
</div>

Controlla lo snippet per un esempio dal vivo.


2

Questo è simile a quello di Alex ma lo fa in tempo di log anziché lineare, e accetta un parametro maxHeight.

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 + "...");
    }
  }
};


1

Ho riscritto la funzione di Alex da utilizzare nella libreria MooTools. L'ho cambiato un po 'per saltare le parole piuttosto che aggiungere i puntini di sospensione nel mezzo di una parola.

Element.implement({
ellipsis: function() {
    if(this.getStyle("overflow") == "hidden") {
        var text = this.get('html');
        var multiline = this.hasClass('multiline');
        var t = this.clone()
            .setStyle('display', 'none')
            .setStyle('position', 'absolute')
            .setStyle('overflow', 'visible')
            .setStyle('width', multiline ? this.getSize().x : 'auto')
            .setStyle('height', multiline ? 'auto' : this.getSize().y)
            .inject(this, 'after');

        function height() { return t.measure(t.getSize).y > this.getSize().y; };
        function width() { return t.measure(t.getSize().x > this.getSize().x; };

        var func = multiline ? height.bind(this) : width.bind(this);

        while (text.length > 0 && func()) {
            text = text.substr(0, text.lastIndexOf(' '));
            t.set('html', text + "...");
        }

        this.set('html', t.get('html'));
        t.dispose();
    }
}
});


1

Sono rimasto un po 'sorpreso dal comportamento dei CSS.

var cssEllipsis = 
{   "width": "100%","display": "inline-block", 
"vertical-align": "middle", "white-space": "nowrap", 
"overflow": "hidden", "text-overflow": "ellipsis" 
};

A meno che non abbia fornito la larghezza al controllo a cui avevo bisogno di legare i puntini di sospensione non ha supposto la mia causa. La larghezza è una proprietà indispensabile da aggiungere ??? Per favore, metti i tuoi pensieri.


1

FARE L'ELLIPSIS SOLO CON CSS

<html>
<head>
<style type="text/css">
#ellipsisdiv {
    width:200px;
    white-space: nowrap;  
    overflow: hidden;  
    text-overflow: ellipsis;  
}  
</style>
</head>
<body>
<div id="ellipsisdiv">
This content is more than 200px and see how the the ellipsis comes at the end when the content width exceeds the div width.
</div>
</body>
</html>

* Questo codice funziona sulla maggior parte dei browser attuali. Se riscontri problemi con Opera e IE (che probabilmente non lo farai), aggiungi questi nello stile:

-o-text-overflow: ellipsis;  
-ms-text-overflow: ellipsis;

* Questa funzione fa parte di CSS3. La sua sintassi completa è:

text-overflow: clip|ellipsis|string;

1

Ecco una bella libreria di widget / plugin che ha puntini di sospensione integrati: http://www.codeitbetter.co.uk/widgets/ellipsis/ Tutto ciò che serve per fare riferimento alla libreria e chiamare il seguente:

<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>

1

puoi farlo molto più facilmente solo con css, ad esempio: modalità sass

.truncatedText {
   font-size: 0.875em;
   line-height: 1.2em;
   height: 2.4em; // 2 lines * line-height
   &:after {
      content: " ...";
   }
}

e hai i puntini di sospensione;)


0

Proprio come @acSlater non sono riuscito a trovare qualcosa per ciò di cui avevo bisogno, quindi ho fatto il mio. Condivisione nel caso in cui qualcun altro possa utilizzare:

Metodo:
ellipsisIfNecessary(mystring,maxlength);
Uso:
trimmedString = ellipsisIfNecessary(mystring,50);
Codice e collegamento demo: https://gist.github.com/cemerson/10368014

Due annotazioni: a) Questo codice non controlla la dimensione effettiva di un elemento HTML. È necessario specificare una determinata lunghezza, che può essere la funzionalità richiesta, ma in realtà è banale da fare. b) Devi solo aggiungere "..." alla fine della stringa. C'è un segno di ellissi "..." che potresti / dovresti usare.
BlaM,

Hey @BlaM - il codice controlla effettivamente la lunghezza rispetto al parametro maxlength. Almeno funziona per me. Detto questo, questo è solo il mio modesto unico per la mia situazione particolare. Sentiti libero di usare una delle soluzioni sopra se questa non funziona bene per la tua situazione.
Christopher D. Emerson,

Sì, funziona con una "lunghezza", ma non con una "larghezza" (dimensione pixel).
BlaM,

Idea interessante: sentiti libero di creare una versione aggiornata con supporto. Non ne ho bisogno ora, ma potrebbe essere utile in futuro.
Christopher D. Emerson,

0
<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 lifeyour 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 lifeyour 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>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.