Texte HTML-débordement détection de points de suspension

j'ai une collection d'éléments de bloc sur une page. Ils ont tous les règles CSS blanc-espace, débordement, texte-débordement réglé de sorte que le texte débordant est tronqué et une ellipse est utilisée.

cependant, tous les éléments ne débordent pas.

y a-t-il quoi qu'il en soit que je puisse utiliser javascript pour détecter quels éléments débordent?

Merci.

ajouté: exemple de structure HTML avec laquelle je travaille.

<td><span>Normal text</span></td>
<td><span>Long text that will be trimmed text</span></td>

les éléments de travée s'adaptent toujours dans les cellules, ils ont la règle d'ellipse appliquée. Je veux détecter quand l'ellipse est appliquée au contenu du texte de la portée.

127
demandé sur deanoj 2011-10-12 13:43:26

11 réponses

il était une fois que j'ai eu besoin de faire cela, et la seule solution fiable cross-browser que j'ai rencontré était le travail de piratage. Je ne suis pas le plus grand fan de solutions comme celle-ci, mais il produit certainement le résultat correct encore et encore.

l'idée est que vous clonez l'élément, retirez toute largeur de limite, et tester si l'élément cloné est plus large que l'original. Si c'est le cas, tu sais que ça va être tronqué.

par exemple, en utilisant 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();

j'ai fait un jsFiddle pour le démontrer, http://jsfiddle.net/cgzW8/2 /

vous pourriez même créer votre propre pseudo-sélecteur personnalisé pour 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;
};

, Puis l'utiliser pour trouver des éléments

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

Démo: http://jsfiddle.net/cgzW8/293 /

Espérons que cela aide, hacky comme il est.

99
répondu Christian Varga 2015-01-06 06:58:55

essayez cette fonction JS, en passant l'élément de portée comme argument:

function isEllipsisActive(e) {
     return (e.offsetWidth < e.scrollWidth);
}
194
répondu Italo Borssatto 2012-04-04 18:57:07

ajouter à la réponse d'italo, vous pouvez également le faire en utilisant jQuery.

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

aussi, comme Smoky l'a souligné, vous pouvez utiliser jQuery outerWidth() au lieu de width().

function isEllipsisActive($jQueryObject) {
    return ($jQueryObject.outerWidth() < $jQueryObject[0].scrollWidth);
}
14
répondu Alex K 2013-10-29 19:06:18

elem.offsetWdith VS ele.scrollWidth Ce travail pour moi! https://jsfiddle.net/gustavojuan/210to9p1 /

$(function() {
  $('.endtext').each(function(index, elem) {
    debugger;
    if(elem.offsetWidth !== elem.scrollWidth){
      $(this).css({color: '#FF0000'})
    }
  });
});
5
répondu Gustavo Juan 2016-02-08 17:05:18

cet exemple montre une infobulle sur une table de cellules avec un texte tronqué. Est dynamique sur la base de la largeur de la table:

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

Démo: https://jsfiddle.net/t4qs3tqs /

il fonctionne sur toutes les versions de jQuery

4
répondu Red 2015-08-07 07:41:17

la solution la plus simple (et cross-browser) est en fait de comparer scrollWidth avec le client width

code de travail ici: https://stackoverflow.com/a/19156627/1213445

4
répondu NicolasBernier 2017-05-23 12:10:45

pour ceux qui utilisent (ou prévoient d'utiliser) la réponse acceptée de Christian Varga, s'il vous plaît être conscient des problèmes de performance.

Cloner / manipuler le DOM d'une telle manière provoque DOM Reflow (voir an explanation on DOM reflow ici) qui nécessite énormément de ressources.

utilisant la solution de Christian Varga sur plus de 100 éléments sur une page a causé un délai de réflexion de 4 secondes au cours de laquelle le JS fil est verrouillé. Étant donné que JS est mono-filetée, cela signifie un délai UX important pour l'utilisateur final.

Italo Borssatto réponse , qui doit être accepté, il était environ 10 fois plus rapide lors de mon profil.

3
répondu RyanGled 2017-06-08 08:09:21

Réponse italo est très bon! Cependant, permettez-moi de le raffiner un peu:

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

compatibilité entre navigateurs

si, en fait, vous essayez le code ci-dessus et utilisez console.log pour imprimer les valeurs de e.offsetWidth et e.scrollWidth , vous remarquerez, sur IE, que, même si vous n'avez pas de troncature de texte, une différence de valeur de 1px ou 2px est expérimentée.

So, en fonction de la taille de la police que vous utilisez, permettent une certaine tolérance!

1
répondu Andry 2016-02-02 18:12:28

je pense que la meilleure façon de le détecter est d'utiliser getClientRects() , il semble que chaque rect a la même hauteur, de sorte que nous pouvons caculer le nombre de lignes avec le nombre de différente top valeur.

getClientRects travail comme ce

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 travail comme ce

vous pouvez détecter comme ce

1
répondu Defims 2016-03-07 09:35:58

toutes les solutions n'ont pas vraiment fonctionné pour moi, ce que a fait travail a été de comparer les éléments scrollWidth à la scrollWidth de son parent (ou enfant, selon lequel élément a la gâchette).

lorsque le scrollWidth de l'enfant est plus élevé que ses parents, cela signifie que .text-ellipsis est actif.


lorsque event est l'élément parent

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

lorsque event est l'élément enfant

function isEllipsisActive(event) {
    let el          = event.currentTarget;
    let width       = el.offsetWidth;
    let widthParent = el.parentElement.scrollWidth;
    return (width >= widthParent);
}
0
répondu Jeffrey Roosendaal 2017-10-20 13:43:28

Avec JQuery:

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

cela affichera votre propriété text-overflow. Donc vous pouvez vérifier si c'était une ellipse avec:

if ($('#yourID').css('text-overflow') === 'ellipsis') {
  // It has overflowed
} else {
  // It has not
}
-1
répondu flamincode 2018-04-20 16:15:22