text-overflow: wielokropek w przeglądarce Firefox 4? (i FF5)

104

Właściwość text-overflow:ellipsis;CSS musi być jedną z niewielu rzeczy, które Microsoft zrobił dobrze dla sieci.

Wszystkie inne przeglądarki obsługują go teraz ... z wyjątkiem Firefoksa.

Twórcy Firefoksa kłócą się o to od 2005 roku, ale pomimo oczywistego popytu na to, wydaje się, że nie są w stanie zmusić się do jego wdrożenia (wystarczyłaby nawet eksperymentalna -moz-implementacja).

Kilka lat temu ktoś wymyślił sposób na zhakowanie Firefoksa 3, aby obsługiwał wielokropek . Hack wykorzystuje tę -moz-bindingfunkcję, aby zaimplementować ją przy użyciu XUL. Dość wiele witryn używa teraz tego hacka.

Złe wiadomości? Firefox 4 usuwa tę -moz-bindingfunkcję , co oznacza, że ​​ten hack już nie zadziała.

Tak więc, gdy tylko Firefox 4 zostanie wydany (słyszę, że pod koniec tego miesiąca) wrócimy do problemu, że nie jest on w stanie obsługiwać tej funkcji.

Więc moje pytanie brzmi: czy można to obejść w inny sposób? (Staram się unikać powrotu do rozwiązania JavaScript, jeśli to w ogóle możliwe)

[EDYTUJ]
Wiele głosów pozytywnych, więc oczywiście nie jestem jedyną osobą, która chce wiedzieć, ale jak dotąd mam jedną odpowiedź, która zasadniczo mówi „użyj javascript”. Nadal liczę na rozwiązanie, które albo w ogóle nie będzie wymagało JS, albo w najgorszym przypadku użyje go tylko jako awaryjnego rozwiązania, w którym funkcja CSS nie działa. Więc zamierzam wystawić nagrodę za to pytanie, jeśli nie ma szans, że ktoś gdzieś znalazł odpowiedź.

[EDYCJA]
Aktualizacja: Firefox przeszedł w tryb szybkiego rozwoju, ale pomimo wydania FF5 ta funkcja nadal nie jest obsługiwana. A teraz, gdy większość użytkowników dokonała aktualizacji z FF3.6, hack nie jest już rozwiązaniem. Dobra wiadomość, powiedziano mi, że może zostać dodana do Firefoksa 6, który wraz z nowym harmonogramem wydań powinien pojawić się za kilka miesięcy. Jeśli tak jest, to chyba mogę to przeczekać, ale szkoda, że ​​nie mogli tego wcześniej załatwić.

[EDYCJA KOŃCOWA]
Widzę, że funkcja wielokropka została wreszcie dodana do „Aurora Channel” Firefoksa (tj. Wersji rozwojowej). Oznacza to, że powinien teraz zostać wydany jako część przeglądarki Firefox 7, która ma się ukazać pod koniec 2011 roku. Co za ulga.

Informacje o wersji dostępne tutaj: https://developer.mozilla.org/en-US/Firefox/Releases/7

Spudley
źródło
19
fwiw, inne niesamowite rzeczy, które Microsoft zrobił dla sieci: AJAX, innerHTML, kopiowanie JavaScript z wystarczającą wiernością, aby w rzeczywistości był to ten sam język w różnych przeglądarkach, nawet jeśli interfejsy API nie były dokładnie takie same, IE6
sdleihssirhc
8
@sdleihssirhc: przejście IE5.5 -> IE6 było rzeczywiście rewolucją. Jesteś jedną z niewielu osób, które widziałem, publicznie to przyznaje;).
mingos
3
@mingos Tak, jestem dość otwarty, proroczy, bystry i inteligentny.
sdleihssirhc
6
@mingos & @sdleihssirhc: Punkt dobrze sformułowany i zgadzam się - IE6 był dobry w swoim czasie. Moje problemy z IE6 nie dotyczą tego, jak dobrze było w tamtym czasie, ale tego, jak spowodowało 10 lat stagnacji w sieci. Ale to nie jest miejsce na debatę na temat dobra lub zła IE. :-) Jest wiele innych miejsc, do których można się udać. W międzyczasie nadal jestem sfrustrowany tym, że programiści Firefox są uparci w kwestii wielokropka.
Spudley,
4
Niestety na razie nie ma rozwiązania CSS. Rozwiązanie awaryjne, którego używam, modernizr nie ma również testu dla tej właściwości. Możesz sprawdzić, czy UserAgent to Firefox i załadować javascript zamiast CSS
nunopolonia

Odpowiedzi:

27

Spudley, możesz osiągnąć to samo, pisząc mały JavaScript przy użyciu jQuery:

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

Rozumiem, że powinien istnieć sposób, aby wszystkie przeglądarki obsługiwały to natywnie (bez JavaScript), ale to właśnie mamy w tym momencie.

EDYCJA Możesz również uczynić to bardziej schludnym, dołączając cssklasę do wszystkich tych pól o stałej szerokości, powiedz, fixWidth a następnie wykonaj coś takiego:

$(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
źródło
2
Dałem ci +1, ale waham się, czy zaakceptować rozwiązanie Javascript, chyba że nic innego nie jest możliwe. Poczekam trochę dłużej, aby zobaczyć, czy otrzymam inne odpowiedzi. Jeśli JS jest jedyną opcją, dobrze byłoby mieć taką, która dobrze się gra, text-overflow:ellipsis;więc nadal mogę używać opcji CSS w innych przeglądarkach.
Spudley,
W przypadku braku innego działającego rozwiązania będę musiał niechętnie zaakceptować to. Zmodyfikuję go tak, aby działał tylko w przeglądarce Firefox, więc będę mógł używać funkcji CSS w innych przeglądarkach. Mamy nadzieję, że chłopaki z Mozilli będą mogli zaimplementować wielokropek dla FF5. Dzięki za pomoc.
Spudley,
Nie powinno length()być length? To własność.
Alex
Trudno jest wybrać długość znaków, która działa przez cały czas, zwłaszcza jeśli używasz czcionek o zmiennej szerokości lub zwiększyłeś lub zmniejszyłeś rozmiar tekstu w przeglądarce.
spb
21

EDYCJA 30.09.2011

FF7 jest niedostępny, ten błąd został rozwiązany i działa!


EDYCJA 29.08.2011

Ten problem jest oznaczony jako rozwiązany i będzie dostępny w grze FF 7; obecnie ma zostać wydana 27.09.2011.

Zaznacz swoje kalendarze i przygotuj się do usunięcia wszystkich hacków, które wprowadziłeś.

STARY

Mam inną odpowiedź: czekaj .

Zespół programistów FF usilnie dąży do rozwiązania tego problemu.

Mają wstępny zestaw poprawek dla przeglądarki Firefox 6.

Firefox 6 !! Kiedy to wyjdzie?!?

Spokojna, wyimaginowana, nadreaktywna osoba. Firefox jest na szybkiej ścieżce deweloperskiej. Wydanie FF6 ma nastąpić sześć tygodni po wydaniu Firefoksa 5. Firefox 5 zostanie wydany 21 czerwca 2011 r.

Więc to załatwia sprawę gdzieś na początku sierpnia 2011 ... miejmy nadzieję.

Możesz zapisać się na listę mailingową podążając za błędem z linku w pytaniu pierwotnego nadawcy.

Możesz też kliknąć tutaj ; cokolwiek jest najłatwiejsze.

promień
źródło
To hacks.mozilla.org/2011/07/aurora7 sugeruje, że będzie to Firefox 7, a nie 6. Ale twój główny punkt ( czekanie ) jest ważny i tak.
MatrixFrog,
„Poczekaj” wydaje się jedyną realistyczną odpowiedzią, ale trudno ją przyjąć, gdy wymaga tego twój szef. :( Na szczęście wydaje się, że oczekiwanie wreszcie dobiega końca (chociaż problem będzie się utrzymywał tak długo, jak długo będą ludzie używali starych wersji
Firefoksa
5
Nie, to jest przeznaczone dla Firefoksa 7 : developer.mozilla.org/en/CSS/ ...
Christian
6

Muszę powiedzieć, że jestem trochę rozczarowany, że jedynym hackiem dotyczącym przeglądarki w mojej aplikacji będzie obsługa FF4. Powyższe rozwiązanie javascript nie uwzględnia czcionek o zmiennej szerokości. Oto bardziej szczegółowy skrypt, który to wyjaśnia. Duży problem z tym rozwiązaniem polega na tym, że jeśli element zawierający tekst jest ukryty podczas uruchamiania kodu, to szerokość pola nie jest znana. To było dla mnie zerwanie umowy, więc przestałem nad nim pracować / testować ... ale pomyślałem, że opublikuję to tutaj, na wypadek, gdyby przydało się to komuś. Pamiętaj, aby przetestować to dobrze, ponieważ moje testy były mniej niż wyczerpujące. Zamierzałem dodać kontrolę przeglądarki, aby uruchamiać kod tylko dla FF4 i pozwolić wszystkim innym przeglądarkom korzystać z ich istniejącego rozwiązania.

Powinno to być dostępne tutaj: 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 (używa 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);
    }
}

Nazywa się to następująco:

$(function(){
    ellipsify($('#test'));
});
wwwhack
źródło
6

W zeszłym tygodniu też spotkałem tego gremlina .

Ponieważ zaakceptowane rozwiązanie nie uwzględnia czcionek o zmiennej szerokości, a rozwiązanie wwwhack ma pętlę While Loop, dorzucę moje 0,02 $.

Udało mi się radykalnie skrócić czas przetwarzania mojego problemu za pomocą mnożenia krzyżowego. Zasadniczo mamy formułę, która wygląda następująco:

wprowadź opis obrazu tutaj

Zmienna x w tym przypadku jest tym, co musimy rozwiązać. Zwracana jako liczba całkowita poda nową długość, jaką powinien mieć przepełniony tekst. Pomnożyłem MaxLength przez 80%, aby dać elipsom wystarczająco dużo miejsca do pokazania.

Oto pełny przykład HTML:

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

Rozumiem, że jest to tylko poprawka JS, ale dopóki Mozilla nie naprawi błędu, po prostu nie jestem wystarczająco inteligentny, aby wymyślić rozwiązanie CSS.

Ten przykład działa najlepiej, ponieważ JS jest wywoływany za każdym razem, gdy w naszej aplikacji ładuje się grid. Szerokość kolumn dla każdej siatki jest różna i nie mamy kontroli nad typem komputera, na którym użytkownicy Firefoksa wyświetlają naszą aplikację (czego oczywiście nie powinniśmy mieć takiej kontroli :)).

promień
źródło
Dziękuję za odpowiedź; Spróbuję i jestem pewien, że przyda się innym, którzy chcą rozwiązać ten sam problem. +1
Spudley
Hmm, wygląda na to, że źle skonfigurowałeś swój edytor tekstu ;-P - wydaje się, że używasz tabulatorów o szerokości mniejszej niż 8 znaków!
SamB
3

To czyste rozwiązanie CSS jest naprawdę bliskie, z wyjątkiem faktu, że powoduje pojawienie się wielokropka po każdej linii.

jhuebsch
źródło
Dziękuję za odpowiedź. Chociaż chciałbym zaakceptować czyste rozwiązanie CSS, to nie jest dla mnie realne, ponieważ wymaga dodatkowych znaczników i, jak mówisz, pozostawia wielokropek pokazujący, kiedy go nie chcesz. w każdym razie dzięki. Mimo to dałem Ci +1.
Spudley,