переполнение текста: многоточие в Firefox 4? (и FF5)

104

Свойство text-overflow:ellipsis;CSS должно быть одной из немногих вещей, которые Microsoft сделала правильно для Интернета.

Все остальные браузеры теперь поддерживают его ... кроме Firefox.

Разработчики Firefox спорят по этому поводу с 2005 года, но, несмотря на очевидную потребность в нем, они, похоже, не могут заставить себя реализовать его (даже экспериментальной -moz-реализации было бы достаточно).

Несколько лет назад кто-то разработал способ взломать Firefox 3, чтобы он поддерживал многоточие . Хак использует эту -moz-bindingфункцию для реализации с помощью XUL. Довольно много сайтов сейчас используют этот взлом.

Плохие новости? Firefox 4 удаляет эту -moz-bindingфункцию , а это означает, что этот взлом больше не будет работать.

Итак, как только будет выпущен Firefox 4 (я слышал, в конце этого месяца), мы вернемся к проблеме того, что он не может поддерживать эту функцию.

Итак, мой вопрос: есть ли другой способ обойти это? (Я стараюсь не возвращаться к решению Javascript, если это вообще возможно)

[РЕДАКТИРОВАТЬ]
Большое количество голосов, так что я, очевидно, не единственный, кто хочет знать, но у меня пока есть один ответ, который в основном гласит «используйте javascript». Я все еще надеюсь на решение, которое либо вообще не будет нуждаться в JS, либо, в худшем случае, будет использовать его только как запасной вариант, когда функция CSS не работает. Итак, я собираюсь объявить награду за вопрос, на случай, если кто-то где-то нашел ответ.

[EDIT]
Обновление: Firefox перешел в режим быстрой разработки, но, несмотря на то, что сейчас выпущен FF5, эта функция все еще не поддерживается. И теперь, когда большинство пользователей обновили FF3.6, взлом больше не является решением. Хорошая новость. Мне сказали, что он может быть добавлен в Firefox 6, который с новым графиком выпуска должен выйти всего через несколько месяцев. Если это так, то, думаю, я могу подождать, но жаль, что они не смогли разобраться с этим раньше.

[ОКОНЧАТЕЛЬНОЕ РЕДАКТИРОВАНИЕ]
Я вижу, что функция многоточия наконец-то была добавлена ​​в Firefox "Aurora Channel" (т.е. версия для разработки). Это означает, что теперь он должен быть выпущен как часть Firefox 7, который должен выйти в конце 2011 года. Какое облегчение.

Примечания к выпуску доступны здесь: https://developer.mozilla.org/en-US/Firefox/Releases/7

Spudley
источник
19
fwiw, другие замечательные вещи, которые Microsoft сделала для Интернета: AJAX, innerHTML, копирование JavaScript с достаточной точностью, чтобы на самом деле это был один и тот же язык в разных браузерах, даже если API-интерфейсы не были точно такими же, IE6
sdleihssirhc
8
@sdleihssirhc: переход с IE5.5 на IE6 действительно произвел революцию. Вы один из немногих, кого я видел, кто публично это признал;).
mingos
3
@mingos Да, я довольно непредубежденный, пророческий, проницательный и умный.
sdleihssirhc,
6
@mingos & @sdleihssirhc: Идея сделана хорошо, и я согласен - IE6 был хорош в свое время. Мои проблемы с IE6 не в том, насколько он был хорош в то время, а в том, как он вызвал 10-летнюю стагнацию в Интернете. Но здесь не место для споров о добре или зле IE. :-) Для этого есть много других мест. Между тем, я все еще разочарован разработчиками Firefox за то, что они упорствуют в многоточии.
Spudley
4
К сожалению, на данный момент нет решения CSS. Используемое мной запасное решение, modernizr, также не имеет проверки на это свойство. Вы можете проверить, является ли агент UserAgent Firefox, и загрузить javascript вместо CSS
nunopolonia

Ответы:

27

Спадли, вы могли бы добиться того же, написав небольшой JavaScript с помощью 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);
}

Я понимаю, что должен быть какой-то способ, чтобы все браузеры поддерживали это изначально (без JavaScript), но это то, что у нас есть на данный момент.

РЕДАКТИРОВАТЬ Кроме того, вы можете сделать его более аккуратным, прикрепив cssкласс ко всем этим полям фиксированной ширины, fixWidth а затем выполните что-то вроде следующего:

$(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
пик
источник
2
Я дал вам +1, но не решаюсь принять решение Javascript, если нет ничего другого. Я подожду еще немного, чтобы посмотреть, получу ли я другие ответы. Если JS - единственный вариант, было бы хорошо иметь тот, который хорошо работает, text-overflow:ellipsis;чтобы я мог использовать параметр CSS в других браузерах.
Spudley
Из-за отсутствия какого-либо другого рабочего решения мне неохотно придется принять это. Я изменю его так, чтобы он работал только в Firefox, чтобы я мог использовать функцию CSS в других браузерах. Мы надеемся, что ребята из Mozilla смогут реализовать многоточие для FF5. Спасибо за помощь.
Spudley
Не должно length()быть length? Это собственность.
Alex
Трудно выбрать длину символа, которая будет работать постоянно, особенно если вы используете шрифты переменной ширины или увеличили или уменьшили размер текста в браузере.
spb
21

РЕДАКТИРОВАТЬ 30.09.2011

FF7 отсутствует, эта ошибка устранена и работает!


РЕДАКТИРОВАТЬ 29.08.2011

Эта проблема помечена как решенная и будет доступна в FF 7; в настоящее время планируется выпуск 27.09.2011.

Отметьте свои календари и будьте готовы удалить все те взломы, которые вы использовали.

Старый

У меня есть другой ответ: подождите .

Команда разработчиков FF по горячим следам пытается решить эту проблему.

У них есть предварительное исправление для Firefox 6.

Firefox 6 !! Когда это выйдет?!?

Спокойный, воображаемый, чрезмерно реактивный человек. Firefox находится на пути ускоренного развития. Выпуск FF6 планируется через шесть недель после Firefox 5. Выпуск Firefox 5 запланирован на 21 июня 2011 года.

Так что исправление произойдет где-то в начале августа 2011 ... надеюсь.

Вы можете подписаться на список рассылки, следуя сообщению об ошибке по ссылке в исходном вопросе автора.

Или вы можете щелкнуть здесь ; в зависимости от того, что будет проще всего.

луч
источник
Этот hacks.mozilla.org/2011/07/aurora7 подразумевает, что он будет в Firefox 7, а не 6. Но ваш главный пункт ( подождите ) в любом случае верен.
MatrixFrog 07
«Подождите», кажется, единственный реалистичный ответ, но это трудный ответ, когда ваш босс требует этого. :( К счастью, ожидание, кажется, наконец подходит к концу (хотя проблема будет оставаться, пока есть люди, использующие старые версии firefox)
Spudley 08
5
Нет, он выйдет в Firefox 7 : developer.mozilla.org/en/CSS/…
Кристиан,
6

Должен сказать, я немного разочарован тем, что единственный хакерский хакер в моем приложении будет поддерживать FF4. Приведенное выше решение javascript не учитывает шрифты переменной ширины. Вот более подробный сценарий, объясняющий это. Большая проблема с этим решением заключается в том, что если элемент, содержащий текст, скрыт при запуске кода, ширина поля неизвестна. Это было препятствием для меня, поэтому я перестал работать / тестировать его ... но я решил опубликовать его здесь, если он кому-то пригодится. Обязательно проверьте его, так как мое тестирование было менее чем исчерпывающим. Я намеревался добавить проверку браузера, чтобы запускать код только для FF4 и позволить всем другим браузерам использовать их существующее решение.

Это должно быть доступно для игры здесь: 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 (использует 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);
    }
}

Это будет называться так:

$(function(){
    ellipsify($('#test'));
});
wwwhack
источник
6

Я тоже сталкивался с этим гремлином на прошлой неделе.

Поскольку принятое решение не учитывает шрифты переменной ширины, а решение wwwhack имеет цикл While Loop, я добавлю свои $ 0,02.

Я смог резко сократить время обработки моей задачи с помощью перекрестного умножения. По сути, у нас есть формула, которая выглядит так:

введите описание изображения здесь

Переменная x в данном случае - это то, что нам нужно решить. При возврате в виде целого числа он даст новую длину, которой должен быть переполненный текст. Я умножил MaxLength на 80%, чтобы у эллипсов было достаточно места для отображения.

Вот полный пример 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>

Я понимаю, что это исправление только JS, но пока Mozilla не исправит ошибку, я просто недостаточно умен, чтобы придумать решение CSS.

Этот пример подходит мне лучше всего, потому что JS вызывается каждый раз, когда сетка загружается в нашем приложении. Ширина столбца для каждой сетки различается, и мы не можем контролировать, на каком компьютере пользователи Firefox просматривают наше приложение (что, конечно, у нас не должно быть этого контроля :)).

луч
источник
Спасибо за ответ; Я попробую, и я уверен, что он будет полезен другим, желающим решить ту же проблему. +1
Spudley
Хм, похоже, вы неправильно настроили свой текстовый редактор ;-P - похоже, вы используете вкладки шириной менее 8 символов!
SamB
3

Это чистое решение CSS действительно близко, за исключением того факта, что оно заставляет многоточие появляться после каждой строки.

jhuebsch
источник
Спасибо за ответ. Как бы я ни хотел принять решение на чистом CSS, это не работает для меня, так как требует дополнительной разметки и, как вы говорите, оставляет многоточие, когда вы этого не хотите. Спасибо хоть. Тем не менее я дал вам +1.
Spudley