обнаружение многоточия переполнения текста для использования в подсказке-триггере [дубликат]

Вы можете сделать это с помощью функции reshape() или с функциями melt() / cast() в пакете reshape. Для второго варианта пример кода:

library(reshape)
cast(dat1, name ~ numbers)

Или с помощью reshape2

library(reshape2)
dcast(dat1, name ~ numbers)
127
задан deanoj 12 October 2011 в 11:17
поделиться

11 ответов

Когда-то мне нужно было это сделать, и единственное кросс-браузерное надежное решение, с которым я столкнулся, - это взломать работу. Я не самый большой поклонник таких решений, но это, безусловно, дает правильный результат снова и снова.

Идея состоит в том, что вы клонируете элемент, удаляете любую ограничительную ширину и проверяете, является ли клонированный элемент более широким, чем оригинал. Если это так, вы знаете, что это будет усечено.

Например, используя jQuery:

var $element = $('#element-to-test');
var $c = $element
           .clone()
           .css({display: 'inline', width: 'auto', visibility: 'hidden'})
           .appendTo('body');

if( $c.width() > $element.width() ) {
    // text was truncated. 
    // do what you need to do
}

$c.remove();

Я сделал jsFiddle, чтобы продемонстрировать это, http: // jsfiddle.net/cgzW8/2/

Вы даже можете создать свой собственный псевдо-селектор для jQuery:

$.expr[':'].truncated = function(obj) {
  var $this = $(obj);
  var $c = $this
             .clone()
             .css({display: 'inline', width: 'auto', visibility: 'hidden'})
             .appendTo('body');

  var c_width = $c.width();
  $c.remove();

  if ( c_width > $this.width() )
    return true;
  else
    return false;
};

Затем используйте его для поиска элементов

$truncated_elements = $('.my-selector:truncated');

Демонстрация: http://jsfiddle.net/cgzW8/293/

Надеюсь, это поможет, взломать, как есть.

95
ответ дан Christian Varga 21 August 2018 в 11:28
поделиться
  • 1
    @Lauri No; Усечение CSS не изменяет текст actual в поле, поэтому контент всегда один и тот же, независимо от того, усечен, видим или скрыт. По-прежнему нет способа программно получить усеченный текст, если бы тогда вам не нужно было клонировать элемент в первую очередь! – Christian Varga 5 April 2013 в 22:08
  • 2
    Кажется, что это не сработает в ситуациях, когда нет white-space: nowrap. – Jakub Hampl 23 July 2014 в 10:31
  • 3
    Должен сказать, что после поиска LOT в Интернете и попыток реализовать множество решений, это, безусловно, самый надежный, который я нашел. Это решение не дает разных результатов между браузерами, такими как element.innerWidth или element.OffsetWidth имеет проблемы при использовании полей или отступов. Отличное решение, хорошо сделано. – Scription 10 September 2014 в 15:06
  • 4
    Для меня это нигде не работало. Я не уверен, как это зависит от CSS (я пытался использовать его на элементах управления вводом, решения ниже работали хотя бы в Chrome и Firefox (но не в IE11)) ... – Alexander 25 November 2015 в 11:09
  • 5
    Отличное решение, особенно с использованием псевдоселектора jQuery. Но иногда это может не работать, потому что ширина вычисляется неправильно, если текст элемента имеет другой стиль (размер шрифта, расстояние между буквами, поля внутренних элементов). В этом случае я бы рекомендовал добавить клон-элемент в $ this.parent () вместо «body». Это даст точную копию элемента, и вычисления будут правильными. Спасибо, в любом случае – Alex 15 February 2016 в 15:08

Добавляя к ответу italo, вы также можете сделать это с помощью jQuery.

function isEllipsisActive($jQueryObject) {
    return ($jQueryObject.width() < $jQueryObject[0].scrollWidth);
}

Кроме того, как заметил Дымки, вы можете использовать jQuery outerWidth () вместо width ().

function isEllipsisActive($jQueryObject) {
    return ($jQueryObject.outerWidth() < $jQueryObject[0].scrollWidth);
}
14
ответ дан Alex Kinnee 21 August 2018 в 11:28
поделиться
  • 1
    Спасибо за ваш код. Но $jQueryObject.width() не является «правильным». потому что он не учитывает маржу ячеек. $jQueryObject.outerWidth(). – Ludovic Guillaume 18 October 2013 в 14:11

Ответ от italo очень хорош! Однако давайте немного уточним:

function isEllipsisActive(e) {
   var tolerance = 2; // In px. Depends on the font you are using
   return e.offsetWidth + tolerance < e.scrollWidth;
}

Совместимость с браузером

Если вы пытаетесь выполнить приведенный выше код и используете console.log для печати значений e.offsetWidth и e.scrollWidth, вы заметите в IE, что даже когда у вас нет усечения текста, возникает разница значений 1px или 2px.

Итак, в зависимости от размер шрифта, который вы используете, допустим определенный допуск!

1
ответ дан Andry 21 August 2018 в 11:28
поделиться
  • 1
    Он не работает на IE10 - offsetWidth идентичен scrollWidth, оба дают мне укороченную ширину. – SsjCosty 23 January 2017 в 13:07
  • 2
    Мне нужна эта допуск на Chrome 60 (последняя). – Jan Żankowski 6 September 2017 в 19:29

Самое простое (и кросс-браузерное) решение фактически сравнивает scrollWidth с clientWidth

Рабочий код здесь: https://stackoverflow.com/a/19156627/1213445

4
ответ дан Community 21 August 2018 в 11:28
поделиться

Я думаю, что лучший способ обнаружить это использование getClientRects(), кажется, что каждый прямоугольник имеет одинаковую высоту, поэтому мы можем выкачать число строк с числом различных значений top.

getClientRects работают как , этот

function getRowRects(element) {
    var rects = [],
        clientRects = element.getClientRects(),
        len = clientRects.length,
        clientRect, top, rectsLen, rect, i;

    for(i=0; i<len; i++) {
        has = false;
        rectsLen = rects.length;
        clientRect = clientRects[i];
        top = clientRect.top;
        while(rectsLen--) {
            rect = rects[rectsLen];
            if (rect.top == top) {
                has = true;
                break;
            }
        }
        if(has) {
            rect.right = rect.right > clientRect.right ? rect.right : clientRect.right;
            rect.width = rect.right - rect.left;
        }
        else {
            rects.push({
                top: clientRect.top,
                right: clientRect.right,
                bottom: clientRect.bottom,
                left: clientRect.left,
                width: clientRect.width,
                height: clientRect.height
            });
        }
    }
    return rects;
}

getRowRects работает как этот

, вы можете обнаружить как this

1
ответ дан Defims 21 August 2018 в 11:28
поделиться

С помощью JQuery:

$('#divID').css('text-overflow')

Это выведет ваше свойство переполнения текста. Таким образом, вы можете проверить, было ли это многоточие:

if ($('#yourID').css('text-overflow') === 'ellipsis') {
  // It has overflowed
} else {
  // It has not
}
-1
ответ дан flamincode 21 August 2018 в 11:28
поделиться

Попробуйте эту функцию JS, передав элемент span в качестве аргумента:

function isEllipsisActive(e) {
     return (e.offsetWidth < e.scrollWidth);
}
189
ответ дан Italo Borssatto 21 August 2018 в 11:28
поделиться
  • 1
    Это должен быть ответ - очень элегантный и работает на Chrome и IE (9) – Roy Truelove 25 June 2013 в 17:40
  • 2
    Этот ответ и ответ Алекса не будут работать в IE8; есть некоторые нечетные случаи, когда ширина прокрутки и внешняя ширина одинаковы ... но она имеет многоточие, а затем некоторые случаи, когда они одинаковы ... и нет эллипсиса NO. Другими словами, первое решение - единственное, что работает во всех браузерах. – user 5 December 2013 в 18:01
  • 3
    Не работает в IE11 ... – Alexander 25 November 2015 в 11:00
  • 4
    не работает для диапазона – huan feng 16 December 2015 в 06:34
  • 5
    Для тех, кто должен понимать offsetWidth, scrollWidth и clientWidth, вот очень хорошее объяснение: stackoverflow.com/a/21064102/1815779 – Linh Dam 4 February 2016 в 04:26

Все решения на самом деле не работали для меня, что работа сравнивала элементы scrollWidth с scrollWidth его родительского (или дочернего, в зависимости от того, какой элемент имеет триггер) .

Когда дочерний scrollWidth выше, чем его родители, это означает, что .text-ellipsis активен.


Когда event является родительским элементом

function isEllipsisActive(event) {
    let el          = event.currentTarget;
    let width       = el.offsetWidth;
    let widthChild  = el.firstChild.offsetWidth;
    return (widthChild >= width);
}

Когда event является дочерним элементом

function isEllipsisActive(event) {
    let el          = event.currentTarget;
    let width       = el.offsetWidth;
    let widthParent = el.parentElement.scrollWidth;
    return (width >= widthParent);
}
0
ответ дан Jeffrey Roosendaal 21 August 2018 в 11:28
поделиться

elem.offsetWdith VS ele.scrollWidth Эта работа для меня! https://jsfiddle.net/gustavojuan/210to9p1/

$(function() {
  $('.endtext').each(function(index, elem) {
    debugger;
    if(elem.offsetWidth !== elem.scrollWidth){
      $(this).css({color: '#FF0000'})
    }
  });
});
5
ответ дан Matthew Herbst 21 August 2018 в 11:28
поделиться

Этот пример показывает всплывающую подсказку в таблице сотока с усеченным текстом. Является динамическим, основанным на ширине таблицы:

$.expr[':'].truncated = function (obj) {
    var element = $(obj);

    return (element[0].scrollHeight > (element.innerHeight() + 1)) || (element[0].scrollWidth > (element.innerWidth() + 1));
};

$(document).ready(function () {
    $("td").mouseenter(function () {
        var cella = $(this);
        var isTruncated = cella.filter(":truncated").length > 0;
        if (isTruncated) 
            cella.attr("title", cella.text());
        else 
            cella.attr("title", null);
    });
});

Демо: https://jsfiddle.net/t4qs3tqs/

Он работает со всей версией jQuery

4
ответ дан Red 21 August 2018 в 11:28
поделиться

Для тех, кто использует (или планирует использовать) принятый ответ от Christian Varga, обратите внимание на проблемы с производительностью.

Клонирование / манипулирование DOM таким образом вызывает DOM Reflow (см. объяснение DOM reflow здесь), который чрезвычайно ресурсоемкий.

Использование решения Christian Varga на 100+ элементах на странице вызвало задержку затухания 4 секунды, в течение которой поток JS заблокирован. Учитывая, что JS является однопоточным, это означает значительную задержку UX для конечного пользователя.

Ответ Italo Borssatto отвечает , это было примерно в 10 раз быстрее во время моего профилирования.

3
ответ дан RyanGled 21 August 2018 в 11:28
поделиться