Textüberlauf: Auslassungspunkte in Firefox 4? (und FF5)

104

Die text-overflow:ellipsis;CSS-Eigenschaft muss eines der wenigen Dinge sein, die Microsoft für das Web richtig gemacht hat.

Alle anderen Browser unterstützen es jetzt ... außer Firefox.

Die Firefox-Entwickler haben seit 2005 darüber gestritten, aber trotz der offensichtlichen Nachfrage können sie sich nicht dazu bringen, es tatsächlich zu implementieren (selbst eine experimentelle -moz-Implementierung wäre ausreichend).

Vor einigen Jahren hat jemand einen Weg gefunden, Firefox 3 zu hacken, damit es eine Ellipse unterstützt . Der Hack verwendet die -moz-bindingFunktion, um sie mit XUL zu implementieren. Eine ganze Reihe von Websites verwenden diesen Hack.

Die schlechten Nachrichten? Firefox 4 entfernt die -moz-bindingFunktion , was bedeutet, dass dieser Hack nicht mehr funktioniert.

Sobald Firefox 4 veröffentlicht wird (wie ich höre, später in diesem Monat), werden wir wieder auf das Problem zurückkommen, dass es diese Funktion nicht unterstützen kann.

Meine Frage lautet also: Gibt es einen anderen Weg, dies zu umgehen? (Ich versuche zu vermeiden, wenn möglich auf eine Javascript-Lösung zurückzugreifen.)

[BEARBEITEN]
Viele Up-Votes, daher bin ich natürlich nicht der einzige, der es wissen möchte, aber ich habe bisher eine Antwort, die im Grunde "Javascript verwenden" lautet. Ich hoffe immer noch auf eine Lösung, die entweder überhaupt kein JS benötigt oder im schlimmsten Fall nur als Ersatz verwendet, wenn die CSS-Funktion nicht funktioniert. Also werde ich ein Kopfgeld auf die Frage setzen, auf die Chance, dass jemand irgendwo eine Antwort gefunden hat.

[BEARBEITEN]
Ein Update: Firefox ist in den Schnellentwicklungsmodus übergegangen, aber obwohl FF5 jetzt veröffentlicht wird, wird diese Funktion immer noch nicht unterstützt. Und jetzt, da die Mehrheit der Benutzer ein Upgrade von FF3.6 durchgeführt hat, ist der Hack keine Lösung mehr. Die gute Nachricht ist, dass es möglicherweise zu Firefox 6 hinzugefügt wird, das mit dem neuen Release-Zeitplan in nur wenigen Monaten veröffentlicht werden sollte. Wenn das der Fall ist, kann ich es wohl abwarten, aber es ist eine Schande, dass sie es nicht früher hätten sortieren können.

[FINAL EDIT]
Ich sehe, dass die Auslassungsfunktion endlich zu Firefox '"Aurora Channel" (dh Entwicklungsversion) hinzugefügt wurde. Dies bedeutet, dass es jetzt als Teil von Firefox 7 veröffentlicht werden sollte, das Ende 2011 erscheinen soll. Was für eine Erleichterung.

Versionshinweise finden Sie hier: https://developer.mozilla.org/en-US/Firefox/Releases/7

Spudley
quelle
19
fwiw, andere großartige Dinge, die Microsoft für das Web getan hat: AJAX, innerHTML, das Kopieren von JavaScript mit einer ausreichenden Genauigkeit, so dass es tatsächlich dieselbe Sprache in verschiedenen Browsern war, auch wenn die APIs nicht genau gleich waren, IE6
sdleihssirhc
8
@sdleihssirhc: Der IE5.5 -> IE6-Übergang war in der Tat eine Revolution. Du bist einer der wenigen Menschen, die ich gesehen habe, die das öffentlich anerkennen;).
Mingos
3
@mingos Ja, ich bin ziemlich aufgeschlossen und prophetisch und so scharf und intelligent.
sdleihssirhc
6
@mingos & @sdleihssirhc: Punkt gut gemacht, und ich stimme zu - IE6 war zu seiner Zeit gut. Meine Probleme mit IE6 sind nicht, wie gut es zu der Zeit war, sondern wie es 10 Jahre Stagnation im Web verursachte. Dies ist jedoch nicht der richtige Ort, um eine Debatte über das Gute oder Böse des IE zu führen. :-) Dafür gibt es noch viele andere Orte. In der Zwischenzeit bin ich immer noch frustriert von den Firefox-Entwicklern, weil sie über die Auslassungspunkte hartnäckig sind.
Spudley
4
Leider gibt es derzeit keine CSS-Lösung. Die von mir verwendete Fallback-Lösung modernizr hat auch für diese Eigenschaft keinen Test. Sie können überprüfen, ob der UserAgent Firefox ist und das Javascript anstelle des CSS
Nunopolonia

Antworten:

27

Spudley, Sie könnten dasselbe erreichen, indem Sie mit jQuery ein kleines JavaScript schreiben:

var limit = 50;
var ellipsis = "...";
if( $('#limitedWidthTextBox').val().length > limit) {
   // -4 to include the ellipsis size and also since it is an index
   var trimmedText = $('#limitedWidthTextBox').val().substring(0, limit - 4); 
   trimmedText += ellipsis;
   $('#limitedWidthTextBox').val(trimmedText);
}

Ich verstehe, dass es eine Möglichkeit geben sollte, dass alle Browser dies nativ unterstützen (ohne JavaScript), aber genau das haben wir an dieser Stelle.

BEARBEITEN Sie können es auch übersichtlicher gestalten, indem Sie eine cssKlasse an alle Felder mit fester Breite anhängen fixWidth und dann Folgendes tun:

$(document).ready(function() {
   $('.fixWidth').each(function() {
      var limit = 50;
      var ellipsis = "...";
      var text = $(this).val();
      if (text.length > limit) {
         // -4 to include the ellipsis size and also since it is an index
         var trimmedText = text.substring(0, limit - 4); 
         trimmedText += ellipsis;
         $(this).val(trimmedText);
      }
   });
});//EOF
Peakit
quelle
2
Ich habe Ihnen +1 gegeben, aber ich zögere, eine Javascript-Lösung zu akzeptieren, es sei denn, es ist nichts anderes möglich. Ich werde etwas länger warten, um zu sehen, ob ich andere Antworten bekomme. Wenn JS die einzige Option ist, wäre es gut, eine zu haben, die gut funktioniert, text-overflow:ellipsis;damit ich die CSS-Option weiterhin in anderen Browsern verwenden kann.
Spudley
In Ermangelung einer anderen funktionierenden Lösung muss ich diese nur ungern akzeptieren. Ich werde es so ändern, dass es nur in Firefox ausgeführt wird, damit ich die CSS-Funktion in anderen Browsern verwenden kann. Wir hoffen, dass die Mozilla-Leute Auslassungspunkte für FF5 implementieren können. Danke für die Hilfe.
Spudley
Sollte nicht length()sein length? Es ist eine Eigenschaft.
Alex
Es ist schwierig, eine Zeichenlänge auszuwählen, die ständig funktioniert, insbesondere wenn Sie Schriftarten mit variabler Breite verwenden oder die Textgröße im Browser vergrößert oder verkleinert haben.
spb
21

EDIT 30.09.2011

FF7 ist raus, dieser Fehler ist behoben und es funktioniert!


EDIT 29.08.2011

Dieses Problem wird als behoben markiert und ist in FF 7 verfügbar. Wird derzeit am 27.09.2011 veröffentlicht.

Markieren Sie Ihre Kalender und machen Sie sich bereit, alle von Ihnen eingerichteten Hacks zu entfernen.

ALT

Ich habe noch eine Antwort: Warte .

Das FF-Entwicklerteam ist bemüht, dieses Problem zu lösen.

Sie haben vorläufige Korrektur für Firefox 6 eingestellt.

Firefox 6 !! Wann kommt das raus?!?

Einfach da, imaginäre, überreaktive Person. Firefox ist auf der Überholspur. FF6 wird sechs Wochen nach Firefox 5 veröffentlicht. Firefox 5 wird am 21. Juni 2011 veröffentlicht.

Damit ist das Problem irgendwann Anfang August 2011 behoben ... hoffentlich.

Sie können sich nach dem Fehler über den Link in der Frage des Originalplakats für die Mailingliste anmelden.

Oder Sie können hier klicken ; was auch immer am einfachsten ist.

Strahl
quelle
Diese hacks.mozilla.org/2011/07/aurora7 impliziert, dass es in Firefox 7 sein wird, nicht in 6. Aber Ihr Hauptpunkt ( Warten ) ist in beiden Fällen gültig.
MatrixFrog
"Warten" scheint die einzig realistische Antwort zu sein, aber es ist eine schwierige Antwort, wenn Ihr Chef sie fordert. :( Zum Glück scheint das Warten endlich zu Ende zu gehen (obwohl das Problem so lange bestehen bleibt, wie es Leute gibt, die alte Versionen von Firefox verwenden)
Spudley
5
Nein, es ist für Firefox 7 geplant : developer.mozilla.org/en/CSS/…
Christian
6

Ich muss sagen, dass ich ein wenig enttäuscht bin, dass der einzige browserspezifische Hack in meiner Anwendung die Unterstützung von FF4 sein wird. Die obige Javascript-Lösung berücksichtigt keine Schriftarten mit variabler Breite. Hier ist ein ausführlicheres Skript, das dies berücksichtigt. Das große Problem bei dieser Lösung besteht darin, dass die Breite des Felds nicht bekannt ist, wenn das Element, das den Text enthält, beim Ausführen des Codes ausgeblendet wird. Dies war ein Deal Breaker für mich, also habe ich aufgehört, daran zu arbeiten / es zu testen ... aber ich dachte, ich würde es hier posten, falls es für jemanden von Nutzen ist. Stellen Sie sicher, dass Sie es gut testen, da meine Tests weniger als erschöpfend waren. Ich wollte eine Browserprüfung hinzufügen, um nur den Code für FF4 auszuführen und alle anderen Browser ihre vorhandene Lösung verwenden zu lassen.

Dies sollte hier zum Spielen verfügbar sein: http://jsfiddle.net/kn9Qg/130/

HTML:

<div id="test">hello World</div>

CSS:

#test {
    margin-top: 20px;
    width: 68px;
    overflow: hidden;
    white-space: nowrap;
    border: 1px solid green;
}

Javascript (verwendet jQuery)

function ellipsify($c){
    // <div $c>                 content container (passed)
    //    <div $b>              bounds
    //       <div $o>           outer
    //          <span $i>       inner
    //       </div>
    //       <span $d></span>   dots
    //    </div>
    // </div>

    var $i = $('<span>' + $c.html() + '</span>');
    var $d = $('<span>...</span>');
    var $o = $('<div></div>');
    var $b = $('<div></div>');

    $b.css( {
        'white-space' : "nowrap",
        'display' : "block",
        'overflow': "hidden"
    }).attr('title', $c.html());

    $o.css({
        'overflow' : "hidden",
        'width' : "100%",
        'float' : "left"
    });

    $c.html('').append($b.append( $o.append($i)).append($d));

    function getWidth($w){
        return parseInt( $w.css('width').replace('px', '') );
    }

    if (getWidth($o) < getWidth($i))
    {
        while (getWidth($i) > (getWidth($b) - getWidth($d)) )
        {
             var content = $i.html();
             $i.html(content.substr(0, content.length - 1));
        }

        $o.css('width', (getWidth($b) - getWidth($d)) + 'px');
    }
    else
    {
        var content = $i.html();
        $c.empty().html(content);
    }
}

Es würde heißen wie:

$(function(){
    ellipsify($('#test'));
});
wwwhack
quelle
6

Ich bin in der letzten Woche auch auf diesen Gremlin gestoßen .

Da die akzeptierte Lösung keine Schriftarten mit variabler Breite berücksichtigt und die Lösung von wwwhack eine While-Schleife hat, werde ich meine $ .02 einwerfen.

Durch Kreuzmultiplikation konnte ich die Bearbeitungszeit meines Problems drastisch reduzieren. Grundsätzlich haben wir eine Formel, die so aussieht:

Geben Sie hier die Bildbeschreibung ein

Die Variable x ist in diesem Fall das, was wir lösen müssen. Bei der Rückgabe als Ganzzahl wird die neue Länge angegeben, die der überlaufende Text haben soll. Ich habe die MaxLength mit 80% multipliziert, um den Ellipsen genügend Platz zum Anzeigen zu geben.

Hier ist ein vollständiges HTML-Beispiel:

<html>
    <head>
        <!-- CSS setting the width of the DIV elements for the table columns.  Assume that these widths could change.  -->
        <style type="text/css">
            .div1 { overflow: hidden; white-space: nowrap; width: 80px; }
            .div2 { overflow: hidden; white-space: nowrap; width: 150px; }
            .div3 { overflow: hidden; white-space: nowrap; width: 70px; }
        </style>
        <!-- Make a call to Google jQuery to run the javascript below.  
             NOTE:  jQuery is NOT necessary for the ellipses javascript to work; including jQuery to make this example work -->
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
        <script type="text/javascript">
            $(document).ready(function() {  
                //Loop through each DIV element
                $('div').each(function(index) {
                    var myDiv = this;  //The original Div element which will have a nodeType of 1 (e.g. ELEMENT_NODE)
                    var divText = myDiv; //Variable used to obtain the text from the DIV element above  

                    //Get the nodeType of 3 (e.g. TEXT_NODE) from the DIV element.  For this example, it will always be the firstChild  
                    divText = divText.firstChild;  

                    //Create another variable to hold the display text  
                    var sDisplayText = divText.nodeValue;  

                    //Determine if the DIV element is longer than it's supposed to be.
                    if (myDiv.scrollWidth > myDiv.offsetWidth) {  
                        //Percentage Factor is just a way of determining how much text should be removed to append the ellipses  
                        //With variable width fonts, there's no magic number, but 80%, should give you enough room
                        var percentageFactor = .8;  

                        //This is where the magic happens.
                        var sliceFactor = ((myDiv.offsetWidth * percentageFactor) * sDisplayText.length) / myDiv.scrollWidth;
                        sliceFactor = parseInt(sliceFactor);  //Get the value as an Integer
                        sDisplayText = sDisplayText.slice(0, sliceFactor) + "..."; //Append the ellipses
                        divText.nodeValue = sDisplayText; //Set the nodeValue of the Display Text
                    }
                });
            });
        </script>
    </head>
    <body>
        <table border="0">
            <tr>    
                <td><div class="div1">Short Value</div></td>    
                <td><div class="div2">The quick brown fox jumps over the lazy dog; lots and lots of times</div></td>    
                <td><div class="div3">Prince</div></td> 
            </tr>
            <tr>    
                <td><div class="div1">Longer Value</div></td>   
                <td><div class="div2">For score and seven year ago</div></td>   
                <td><div class="div3">Brown, James</div></td>   
            </tr>
            <tr>    
                <td><div class="div1">Even Long Td and Div Value</div></td> 
                <td><div class="div2">Once upon a time</div></td>   
                <td><div class="div3">Schwarzenegger, Arnold</div></td> 
            </tr>
        </table>
    </body>
</html>

Ich verstehe, dass dies nur ein JS-Fix ist, aber bis Mozilla den Fehler behebt, bin ich einfach nicht klug genug, um eine CSS-Lösung zu finden.

Dieses Beispiel funktioniert am besten für mich, da der JS jedes Mal aufgerufen wird, wenn ein Raster in unserer Anwendung geladen wird. Die Spaltenbreite für jedes Raster variiert und wir haben keine Kontrolle darüber, welchen Computertyp unsere Firefox-Benutzer unsere App anzeigen (was wir natürlich nicht haben sollten :)).

Strahl
quelle
Danke für die Antwort; Ich werde es versuchen und ich bin sicher, dass es für andere nützlich sein wird, die das gleiche Problem lösen möchten. +1
Spudley
Hmm, Sie scheinen Ihren Texteditor falsch konfiguriert zu haben ;-P - Sie scheinen Registerkarten mit einer Breite von weniger als 8 Zeichen zu verwenden!
SamB
3

Diese reine CSS-Lösung ist sehr ähnlich, bis auf die Tatsache, dass nach jeder Zeile Auslassungspunkte angezeigt werden.

jhuebsch
quelle
Danke für die Antwort. So sehr ich eine reine CSS-Lösung akzeptieren möchte, ist diese für mich nicht wirklich praktikabel, da sie zusätzliche Markups erfordert und, wie Sie sagen, die Auslassungspunkte angezeigt werden, wenn Sie sie nicht möchten. trotzdem danke. Ich habe dir trotzdem +1 gegeben.
Spudley