Fügen Sie Auslassungspunkte (…) in das HTML-Tag ein, wenn der Inhalt zu breit ist

148

Ich habe eine Webseite mit einem elastischen Layout, dessen Breite sich ändert, wenn die Größe des Browserfensters geändert wird.

In diesem Layout gibt es Überschriften ( h2) mit variabler Länge (Überschriften aus Blogposts, über die ich keine Kontrolle habe). Derzeit sind sie - wenn sie breiter als das Fenster sind - in zwei Zeilen unterteilt.

Gibt es eine elegante, getestete (browserübergreifende) Lösung - zum Beispiel mit jQuery -, die das innerHTML dieses Überschriften-Tags verkürzt und "..." hinzufügt, wenn der Text zu breit wäre, um in eine Zeile auf dem aktuellen Bildschirm zu passen? Behälterbreite?

BlaM
quelle
1
2014 aktualisierte Antwort: stackoverflow.com/a/22811590/759452
Adrien Be
Ich habe ein Plugin basierend auf diesem Thread erstellt, das die CSS-Eigenschaften Leerzeichen und Zeilenumbruch verwendet, um den Text zu formatieren. github.com/nothrem/jQuerySmartEllipsis
Radek Pech

Antworten:

119

Ich habe eine Lösung in FF3, Safari und IE6 + mit ein- und mehrzeiligem Text

.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);
Alex
quelle
22
Schön, ich habe gesucht, wie man mit Überlauf mit mehreren Zeilen umgeht. Eine Verbesserung: Anstatt drei Punkte anzuhängen, fügen Sie das Auslassungszeichen '…' hinzu.
Simon Lieschke
4
Das funktioniert sehr gut. Sie sollten dies auf der jQuery-Site veröffentlichen.
Edgar
1
Obwohl im IE die Ellipsenfunktion auf ein Div angewendet wird, das nur einen Link hat, verschwindet der Link nach den Ellipsen. Irgendwelche Hinweise dazu?
Chantz
6
Wenn Sie dies in Aktion sehen möchten, können Sie es hier sehen (entschuldigen Sie die verrückte Formatierung des Plugin-Codes). Jsfiddle.net/danesparza/TF6Rb/1
Dan Esparza
22
Um die Leistung zu verbessern, führen Sie eine binäre Suche durch, anstatt jeweils 1 Zeichen in der "while" -Schleife zu entfernen. Wenn 100% des Textes nicht passen, versuchen Sie es mit 50% des Textes. dann 75% des Textes, wenn 50% passen, oder 25%, wenn 50% nicht passen usw.
StanleyH
182

Die folgende Nur-CSS-Lösung zum Abschneiden von Text in einer einzelnen Zeile funktioniert mit Ausnahme von Firefox 6.0 mit allen Browsern, die zum Zeitpunkt des Schreibens unter http://www.caniuse.com aufgeführt sind . Beachten Sie, dass JavaScript nicht erforderlich ist, es sei denn, Sie müssen das Umbrechen von mehrzeiligem Text oder früheren Versionen von Firefox unterstützen.

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

Wenn Sie Unterstützung für frühere Versionen von Firefox benötigen, lesen Sie meine Antwort auf diese andere Frage .

Simon Lieschke
quelle
2
Dies ist um Größenordnungen schneller als der jQuery-Ansatz. Funktioniert gut in IE7 + und Chrome.
JDB erinnert sich noch an Monica
3
Dies funktioniert auch gut alten Browsern. Wir haben es im Jahr 2004 erfolgreich bei Google eingesetzt, wo wir einige wirklich eckige Browser unterstützen oder ordnungsgemäß beeinträchtigen mussten.
ElBel
2
JS Fiddle für diejenigen, die es in einem Browser testen
Deepak Bala
@ DilipRajkumar Sie müssen mehr Details bereitstellen, z. B. ein JSFiddle- Beispiel, das zeigt, dass es in IE 8 nicht funktioniert.
Simon Lieschke
1
@ SharpCoder du nicht. Wo der Text abgeschnitten wird, wird durch die Breite des Elements bestimmt, das ihn enthält, dh er wird abgeschnitten, wenn die Breite des Elements überlaufen würde.
Simon Lieschke
40

Ich habe diesen Code mit einer Reihe anderer Beiträge mit den folgenden Verbesserungen erstellt:

  1. Es verwendet eine binäre Suche, um die Textlänge zu finden, die genau richtig ist.
  2. Es behandelt Fälle, in denen die Auslassungselemente zunächst ausgeblendet werden, indem ein einmaliges Show-Ereignis eingerichtet wird, das den Auslassungscode erneut ausführt, wenn das Element zum ersten Mal angezeigt wird. Dies ist praktisch für Hauptdetailansichten oder Baumansichten, in denen einige Elemente anfangs nicht angezeigt werden.
  3. Optional wird ein Titelattribut mit dem Originaltext für einen Hoverover-Effekt hinzugefügt.
  4. Hinzugefügt display: block Stil , damit die Spannweiten funktionieren
  5. Es wird das Auslassungszeichen anstelle von 3 Punkten verwendet.
  6. Das Skript wird für alles mit der .ellipsis-Klasse automatisch ausgeführt

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));
Adam Tegen
quelle
2
Wunderschönen. Bravo für die Umsetzung meines Vorschlags einer binären Suche.
StanleyH
2
Nur eine kurze Anmerkung ... es lohnt sich, .css ('max-width', 'none') zur tempElement-Variable hinzuzufügen ... Auf diese Weise können Sie eine Max-width-Deklaration in Ihrem CSS verwenden, wodurch das Plugin weitaus flexibler wird (Zumindest für die meisten Anwendungsfälle, die ich habe). Gute Arbeit trotzdem. :)
Gordon
3
Dies ist eine viel schnellere Implementierung als die oben akzeptierte Antwort. Wenn Sie mehrere .ellipsis-Elemente haben und mit ihnen etwas Dynamisches tun, ist dieses Element viel leistungsfähiger.
mjvotaw
Können Sie bitte ein Beispiel nennen? Meine Frage ist hier: stackoverflow.com/questions/26344520/…
SearchForKnowledge
Binäre Suche ist vorzuziehen, aber nicht mit sehr kleinen Datensätzen und behindert in diesem Fall die Leistung im Vergleich zu einer geraden linearen Suche wie indexOf () ... anscheinend
user1360809
20

Meine Antwort unterstützt nur einzeiligen Text. Schauen Sie sich den Kommentar von gfullam unten für die mehrzeilige Gabel an, sie sieht ziemlich vielversprechend aus.

Ich habe den Code von der ersten Antwort an einige Male umgeschrieben, und ich denke, dies sollte der schnellste sein.

Es findet zuerst eine "geschätzte" Textlänge und fügt dann ein Zeichen hinzu oder entfernt es, bis die Breite korrekt ist.

Die verwendete Logik ist unten dargestellt:

Geben Sie hier die Bildbeschreibung ein

Nachdem eine "geschätzte" Textlänge gefunden wurde, werden Zeichen hinzugefügt oder entfernt, bis die gewünschte Breite erreicht ist.

Ich bin mir sicher, dass einige Anpassungen erforderlich sind, aber hier ist der Code:

(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);
Mikey G.
quelle
3
Ihre Lösung ist vielleicht nicht die beste, aber sie ist sehr gut erklärt. Und ich mag diese Art von Approximationslogik. +1 :)
Flater
2
Ich habe dies gegabelt, um Unterstützung für Textbereiche und mehrzeilige (vertikale) Ellipsenkürzungen hinzuzufügen : jsfiddle.net/gfullam/j29z7381 (Ich mag die Approximationslogik
übrigens
19

Nur für den Fall, dass Sie 2013 hier landen - hier ist ein reiner CSS-Ansatz, den ich hier gefunden habe: http://css-tricks.com/snippets/css/truncate-string-with-ellipsis/

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

Es funktioniert gut.

Joseph Juhnke
quelle
1
FWIW text-overflowfunktioniert nicht mit textareaElementen (Stand 2015). Wenn Sie Unterstützung benötigen textarea, können Sie dies erreichen, indem Sie die akzeptierte Antwort ändern oder diese Abzweigung verwenden .
Gfullam
18

Ich habe ein wirklich cooles jQuery-Plugin für den Umgang mit allen Arten von Textauslassungen namens ThreeDots @ http://tpgblog.com/threedots erstellt

Es ist viel flexibler als die CSS-Ansätze und unterstützt viel fortgeschrittenere, anpassbare Verhaltensweisen und Interaktionen.

Genießen.

Jeremy Horn
quelle
8

Ein flexibleres jQuery-Plugin, mit dem Sie ein Element nach den Auslassungspunkten (z. B. eine Schaltfläche "Mehr lesen") beibehalten und onWindowResize aktualisieren können. Es funktioniert auch um Text mit Markup:

http://dotdotdot.frebsite.nl

Matt
quelle
Ich habe dieses Plugin gerade getestet, aber ich konnte es nicht zum Laufen bringen. Trunk8 war eine bessere Wahl für mich.
Guilherme Garnier
8

Das jQuery-Plugin für trunk8 unterstützt mehrere Zeilen und kann für das Kürzungssuffix ein beliebiges HTML verwenden, nicht nur Auslassungszeichen: https://github.com/rviscomi/trunk8

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

Eliot Sykes
quelle
Ja, aber das ist jetzt uralt. sieht aus wie es nicht unterstützt wird?
user2513846
1
Es sieht so aus, als ob es aktiv unterstützt wird - zum Zeitpunkt des Schreibens (März 2016) zeigen die Themen und PRs die jüngsten Aktivitäten, an denen der Projektersteller beteiligt ist.
Eliot Sykes
5

Es gibt tatsächlich eine ziemlich einfache Möglichkeit, dies in CSS zu tun, indem die Tatsache ausgenutzt wird, dass der IE dies mit Nicht-Standards und FF-Unterstützung erweitert:after

Sie können dies auch in JS tun wenn Sie möchten, indem Sie die scrollWidth des Ziels überprüfen und mit der Breite der Eltern vergleichen. Imho ist dies jedoch weniger robust.

Edit: das ist anscheinend weiter entwickelt als ich dachte. Möglicherweise wird bald CSS3-Unterstützung vorhanden sein, und Sie können einige unvollständige Erweiterungen ausprobieren.

Das letzte ist eine gute Lektüre.

Annakata
quelle
Eigentlich bevorzuge ich die JS-Lösung - weil sie nur "..." hinzufügt, wenn der Text breiter als der verfügbare Platz ist.
BlaM
3

Ich hatte kürzlich etwas Ähnliches für einen Kunden getan. Hier ist eine Version von dem, was ich für sie getan habe (Beispiel getestet in allen neuesten Browserversionen unter Win Vista). Nicht rundum perfekt, könnte aber ziemlich einfach angepasst werden.

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>
enobrev
quelle
3

Nun, eine einfache Lösung, die das "..." nicht ganz hinzufügt, aber verhindert, dass das <h2> in zwei Zeilen zerfällt, besteht darin, dieses Bit CSS hinzuzufügen:

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 */
}

Ich habe noch etwas darüber nachgedacht und mir diese Lösung ausgedacht. Sie müssen den Textinhalt Ihres h2-Tags mit einem anderen Tag (z. B. einer Spanne) umschließen (oder alternativ die h2s mit etwas umbrechen, das die angegebene Höhe hat) und dann Sie können diese Art von Javascript verwenden, um die nicht benötigten Wörter herauszufiltern:

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;
                }
            }
        }
    }
Ramuns Usovs
quelle
Eigentlich habe ich darüber nachgedacht, dies als Grundlage für eine mögliche Lösung zu verwenden, aber ich habe keine Ahnung, ob es auf dieser Grundlage möglich wäre, herauszufinden, ob der gesamte Text jetzt angezeigt wird oder ob ich ihn kürzen und hinzufügen muss. " ... ". Nur abzuschneiden würde komisch aussehen.
BlaM
3

Hier ist eine weitere JavaScript-Lösung. Funktioniert sehr gut und sehr schnell.

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

Getestet auf Chrome, FF, IE unter Windows und Mac.

Adam Lukaszczyk
quelle
Dies ist zwar weniger automatisch, aber ich fand, dass es eine genauere Lösung ist als die Antwort von Adam Tegen . Für dieses Skript muss die maximale Anzahl von Textzeilen angegeben werden, anstatt zu raten.
Donut
3

Es gibt eine Lösung für mehrzeiligen Text mit reinem CSS. Es heißtline-clamp , funktioniert aber nur in Webkit-Browsern. Es gibt jedoch eine Möglichkeit, dies in allen modernen Browsern nachzuahmen (alles neuer als IE8). Außerdem funktioniert es nur auf festem Hintergrund, da Sie ein Hintergrundbild benötigen, um die letzten Wörter der letzten Zeile auszublenden. So geht's:

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

Hier ist das 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 ist ein Bild mit der gleichen Farbe Ihres Hintergrunds, das ungefähr 100 Pixel breit ist und die gleiche Höhe wie Ihre Linienhöhe hat.

Es ist nicht sehr hübsch, da Ihr Text möglicherweise in der Mitte eines Buchstabens abgeschnitten wird, aber in einigen Fällen kann es nützlich sein.

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

Jules Colle
quelle
Das ist schön, aber Sie müssen sicher sein, dass Ihr Text lang genug ist, da dieses CSS "..." hinzufügt, auch wenn der Text kurz genug ist, um in den verfügbaren Platz zu passen. Übrigens: Die gleiche Antwort wurde von Apopii vor ungefähr einem Monat gegeben;)
BlaM
@BlaM So ziemlich das gleiche in der Tat. Aber ich denke, der Gradiententrick ist ordentlich und dieser Code in CSS anstelle von SASS, also denke ich, dass es sich lohnt, eine separate Antwort zu sein.
Jules Colle
3

Reine CSS Mehrzeilige Ellipse für Textinhalte:

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

Bitte überprüfen Sie das Snippet für ein Live-Beispiel.

Jason Williams
quelle
2

Dies ist ähnlich wie bei Alex, erfolgt jedoch in logarithmischer Zeit anstatt linear und verwendet einen 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 + "...");
    }
  }
};
Dave Aaron Smith
quelle
2

Es gibt eine einfache jQuery-Lösung von Devon Govett :

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

Rufen Sie zur Verwendung einfach ellipsis () für ein jQuery-Objekt auf. Beispielsweise:

$ ("span"). ellipsis ();

BlaM
quelle
Ich wollte gerade den gleichen Link posten. :)
Gumbo
Der Link in diesem Beitrag ist tot.
Justin Tanner
Ich habe einen Fallback-Link hinzugefügt
BlaM
1

Ich habe Alex 'Funktion für die MooTools-Bibliothek umgeschrieben. Ich habe es ein wenig in Wortsprung geändert, anstatt die Auslassungspunkte in der Mitte eines Wortes hinzuzufügen.

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();
    }
}
});
Ich liebe Italien
quelle
1

Ich konnte kein Skript finden, das genau so funktionierte, wie ich es wollte, und mein eigenes für jQuery - einige Optionen, um mehr auf dem Weg zu machen :)

https://github.com/rmorse/AutoEllipsis

rmorse
quelle
1

Ich war allerdings etwas überrascht vom Verhalten des CSS.

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

Es sei denn, ich habe die Breite für die Kontrolle angegeben, an die ich die Auslassungspunkte binden musste, hat meine Sache nicht unterstützt. Ist die Breite ein Muss, um hinzugefügt zu werden? Bitte setzen Sie Ihre Gedanken.

Premanshu
quelle
1

TUN SIE DIE ELLIPSIS NUR MIT 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>

* Dieser Code funktioniert in den meisten aktuellen Browsern. Wenn Sie Probleme mit Opera und IE haben (was Sie wahrscheinlich nicht tun werden), fügen Sie diese im folgenden Stil hinzu:

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

* Diese Funktion ist Teil von CSS3. Die vollständige Syntax lautet:

text-overflow: clip|ellipsis|string;
Robin Rizvi
quelle
1

Hier ist eine nette Widget- / Plugin-Bibliothek mit integrierten Auslassungspunkten: http://www.codeitbetter.co.uk/widgets/ellipsis/ Alles, was Sie dazu tun müssen, ist, auf die Bibliothek zu verweisen und Folgendes aufzurufen:

<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>
Tim
quelle
1

Sie können dies viel einfacher nur mit CSS tun, zum Beispiel: Sass-Modus

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

und du hast Auslassungspunkte;)

Apopii Dumitru
quelle
0

Genau wie bei @acSlater konnte ich nichts für das finden, was ich brauchte, also rollte ich mein eigenes. Teilen für den Fall, dass jemand anderes Folgendes verwenden kann:

Methode:
ellipsisIfNecessary(mystring,maxlength);
Verwendung:
trimmedString = ellipsisIfNecessary(mystring,50);
Code- und Demo-Link: https://gist.github.com/cemerson/10368014
Christopher D. Emerson
quelle
Zwei Anmerkungen: a) Dieser Code überprüft nicht die tatsächliche Größe eines HTML-Elements. Sie müssen eine bestimmte Länge angeben - dies kann die erforderliche Funktionalität sein, ist jedoch eigentlich trivial. b) Sie fügen einfach "..." am Ende der Zeichenfolge hinzu. Es gibt ein Auslassungszeichen "...", das Sie verwenden könnten / sollten.
BlaM
Hey @BlaM - der Code vergleicht tatsächlich die Länge mit dem Parameter maxlength. Es funktioniert zumindest für mich. Das heißt - dies ist nur mein bescheidenes Einzelstück für meine besondere Situation. Sie können gerne eine der oben genannten Lösungen verwenden, wenn diese für Ihre Situation nicht geeignet ist.
Christopher D. Emerson
Ja, es funktioniert mit einer "Länge", aber nicht mit einer "Breite" (Pixelgröße).
BlaM
Interessante Idee - zögern Sie nicht, eine aktualisierte Version mit Unterstützung dafür zu erstellen. Ich brauche das jetzt nicht, könnte aber in Zukunft nützlich sein.
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>
Warren Downs
quelle