J'ai une collection d'éléments de bloc sur une page. Ils ont tous les règles CSS espace-blanc, débordement, débordement de texte définies de sorte que le texte débordant soit coupé et qu'un Ellipsis soit utilisé.
Cependant, tous les éléments ne débordent pas.
Est-ce que je peux quand même 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 SPAN tiennent toujours dans les cellules, la règle Ellipsis est appliquée. Je souhaite détecter le moment où l’Ellipsis est appliqué au contenu textuel du SPAN.
Jadis, j’avais besoin de faire cela, et la seule solution fiable multi-navigateurs à laquelle j’ai eu à faire face est le piratage. Je ne suis pas le plus grand fan de solutions comme celle-ci, mais cela produit certainement le résultat correct à maintes reprises.
L'idée est de cloner l'élément, de supprimer toute largeur de bordure et de vérifier si l'élément cloné est plus large que l'original. Si c'est le cas, vous savez qu'il aura été 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 démontrer cela, http://jsfiddle.net/cgzW8/2/
Vous pouvez 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;
};
Ensuite, utilisez-le pour trouver des éléments
$truncated_elements = $('.my-selector:truncated');
Démo: http://jsfiddle.net/cgzW8/293/
Espérons que cela aide, hacky tel qu'il est.
Essayez cette fonction JS en passant l’élément span en argument:
function isEllipsisActive(e) {
return (e.offsetWidth < e.scrollWidth);
}
En ajoutant à la réponse de italo, vous pouvez également le faire avec jQuery.
function isEllipsisActive($jQueryObject) {
return ($jQueryObject.width() < $jQueryObject[0].scrollWidth);
}
En outre, comme Smoky l’a souligné, vous pouvez utiliser jQuery outerWidth () au lieu de width ().
function isEllipsisActive($jQueryObject) {
return ($jQueryObject.outerWidth() < $jQueryObject[0].scrollWidth);
}
Pour ceux qui utilisent (ou prévoient d’utiliser) la réponse acceptée de Christian Varga, veuillez prendre en compte les problèmes de performances.
Le clonage/manipulation du DOM de telle manière provoque une redistribution de DOM (voir ne explication sur la redistribution du DOM ici), ce qui constitue une ressource extrêmement précieuse. intensif.
L'utilisation de la solution de Christian Varga sur plus de 100 éléments sur une page a provoqué un délai de refusion de 4 secondes au cours duquel le thread JS est verrouillé. Considérant que JS est mono-thread, cela signifie un retard UX important pour l'utilisateur final.
Italo Borssatto's answer devrait être celui qui a été accepté, il était environ 10 fois plus rapide lors de mon profilage.
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'})
}
});
});
La solution la plus simple (et multi-navigateur) compare réellement scrollWidth à clientWidth
Code de travail ici: https://stackoverflow.com/a/19156627/1213445
Cet exemple affiche une info-bulle sur une table de cellules avec du texte tronqué. Est dynamique en fonction 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/
Cela fonctionne sur toutes les versions de jQuery
Réponse de italo est très bon! Cependant laissez-moi l'affiner un peu:
function isEllipsisActive(e) {
var tolerance = 2; // In px. Depends on the font you are using
return e.offsetWidth + tolerance < e.scrollWidth;
}
Si, en fait, vous essayez le code ci-dessus et utilisez console.log
pour afficher les valeurs de e.offsetWidth
et e.scrollWidth
, vous remarquerez sur IE que, même sans troncature du texte, une différence de valeur de 1px
ou 2px
est expérimenté.
Donc, en fonction de la taille de la police utilisée, autorisez une certaine tolérance!
Je pense que le meilleur moyen de le détecter est d'utiliser getClientRects()
, il semble que chaque recto ait la même hauteur. Nous pouvons donc calculer le nombre de lignes avec le nombre de valeurs différentes de top
.
getClientRects
fonctionne comme this
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
fonctionne comme this
vous pouvez détecter comme this
Toutes les solutions ne fonctionnaient pas vraiment pour moi, ce que fait travail était de comparer les éléments scrollWidth
au scrollWidth
de son parent (ou de son enfant, en fonction de l'élément a la gâchette).
Lorsque l'enfant scrollWidth
est supérieur à ses parents, cela signifie .text-Ellipsis
c'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);
}
Le e.offsetWidth < e.scrollWidth
La solution ne fonctionne pas toujours.
Et si vous voulez utiliser du JavaScript pur, je vous recommande d'utiliser ceci:
(Manuscrit)
public isEllipsisActive(element: HTMLElement): boolean {
element.style.overflow = 'initial';
const noEllipsisWidth = element.offsetWidth;
element.style.overflow = 'hidden';
const ellipsisWidth = element.offsetWidth;
if (ellipsisWidth < noEllipsisWidth) {
return true;
} else {
return false;
}
}