Comment trouver la dernière position de mot visible dans un conteneur de texte?

Est-il possible de trouver la position du dernier mot visible d'un texte (débordement: caché) dans une petite div?

Par exemple:

<div style="height: 50px; width: 50px; overflow: hidden;"> Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. </div> 

Comment calculer la position du dernier Word visible dans le conteneur div? J'aime remplir tout le div133!

JSFiddle ici: http://jsfiddle.net/SmokeyPHP/NQLcc/1/

HTML:

 <div id="txt"> Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. </div> 

CSS:

 #txt { width: 75px; height: 75px; border: 1px solid #F00; overflow: hidden; } 

JS:

 var cntnr = $("#txt"); cntnr.html('<span>'+cntnr.html().replace(/ /g,'</span> <span>')+'</span>') var words = Array.prototype.slice.call(cntnr.find("span"),0).reverse(); var lastw = null; for(var i=0,c=words.length;i<c;i++) { var w = $(words[i]); var wbot = w.height() + w.offset().top; var wleft = w.offset().left; var wright = wleft+w.width(); if(wbot <= cntnr.height() && wleft <= cntnr.width() && wright <= cntnr.width()) { lastw = w.text(); break; } } cntnr.html(cntnr.text()); alert(lastw); 

Le JS pourrait probablement être raccourci, mais je l'ai laissé comme j'étais en train d'écrire et de penser en même temps … En substance, vous enveloppez tous les mots dans une portée, puis faites une boucle en arrière dans les travées, voyez si leurs limites tombent Le conteneur, et dès que nous trouvons une étendue qui s'assoit à l'intérieur des limites du conteneur, sort de la boucle et renvoie ce mot, après avoir renvoyé le texte au texte brut (en supprimant les espaces temporaires).

Oui, il est possible de détecter le dernier mot affiché à l'aide de Javascript.

Malheureusement, je n'ai pas le temps d'écrire le code qui peut le faire, mais je vais expliquer l'algorithme.

Si vous avez une case 50×50 et que vous souhaitez détecter le dernier mot visible, procédez comme suit:

  1. Créez un div hors écran qui a 50 pixels de largeur mais pas de restriction sur la hauteur. Pour cette démonstration, nous appelons cette division du clonedDiv.
  2. Obtenez la chaîne qui était dans la division d'origine et insérez le premier mot dans le clonedDiv.
  3. Vérifiez la hauteur du clonedDiv.
  4. Appliquer cette logique: Si c'est <= 50px puis ajouter le mot suivant et réessayer. Si elle est supérieure à 50px de hauteur, alors c'est le mot qui provoque le débordement. Votre réponse sera le mot PRÉCÉDENT.

Notez que l'algorithme ci-dessus utilise une méthode de force brute pour trouver le mot. L'algorithme consiste essentiellement à ajouter un mot à la fois jusqu'à ce qu'il trouve le mot qui cause le débordement. Vous pouvez améliorer cela en utilisant une variation de l'algorithme de recherche binaire qui améliorera l'algorithme d'O (n) à O (log (n)).

Une solution possible:

 var $div = $('div'), size = [$div.width(), $div.height()], words = $.trim($div.text()).split(/\s+/), word; for (var i = 0, len = words.length; i < len; i++) { var $clone = $div.clone().text(words.join(' ')).insertAfter($div); $clone.contents().wrap('<span />'); var $child = $clone.children('span'); if ($child.width() <= size[0] && $child.height() <= size[1]) { word = words.pop(); $clone.remove(); break; } words.pop(); $clone.remove(); } console.log(word); 

DEMO: http://jsfiddle.net/bcn78/

Working DEMO

J'ai emprunté une réponse ici et l'ai changé un peu.

 function countVisibleCharacters(element) { var text = element.firstChild.nodeValue; var r = 0; element.removeChild(element.firstChild); for(var i = 0; i < text.length; i++) { var newNode = document.createElement('span'); newNode.appendChild(document.createTextNode(text.charAt(i))); element.appendChild(newNode); if(newNode.offsetLeft < element.offsetWidth) { r++; } } return r; } var c = countVisibleCharacters(document.getElementsByTagName('div')[0]); var str = document.getElementById('myDiv'); str = str.textContent; str = str.substring(0, c); str = str.substr(str.trim().lastIndexOf(" ")+1); alert(str); 

En plus de @SmokeyPhp répondre:

Tout d'abord, c'était une excellente réponse qui m'a beaucoup aidé, mais il y a eu des erreurs dans la condition.

Deuxièmement, je travaille avec la bibliothèque jqlite au lieu de jQuery, alors cette réponse a également été très utile dans ce domaine (toutes les méthodes qu'il utilisait faisaient partie de la bibliothèque jqlite).

En plus de détecter le dernier mot visible dans une étendue ou une div, ma fonction remplaça également le reste du texte par "…".

Je publie le code que j'utilise, fondamentalement, le code @SmokeyPhp posté, mais réparé si nécessaire, et j'espère que d'autres en bénéficieront:

 function dotdotdot(containersToDotdotdot) { function dotdotdotContainers(containers) { for (var i = 0; i < containers.length; i++) { var cntnr = $jq(containers[i]); cntnr.html('<span>' + cntnr.html().replace(/ /g,'</span> <span>') + '</span>'); var words = Array.prototype.slice.call(cntnr.find("span"), 0).reverse(); var lastw = null; for (var j = 0; j < words.length; j++) { var w = $jq(words[j]); var wbot = w.height() + w.offset().top; var wleft = w.offset().left; var wright = wleft + w.width(); if (wbot <= (cntnr.offset().top + cntnr.height()) && wleft >= (cntnr.offset().left) && wright <= (cntnr.offset().left + cntnr.width())) { lastw = words.length - j - 1; break; } } cntnr.html(lastw === null || lastw === (words.length - 1) ? cntnr.text() : (cntnr.text().split(' ').slice(0, lastw).join(' ') + '...')); } } if (containersToDotdotdot instanceof Array) { for (var i = 0; i < containersToDotdotdot.length; i++) { dotdotdotContainers($jq(containersToDotdotdot[i])); } } else { dotdotdotContainers($jq(containersToDotdotdot)); } } 

Comme vous pouvez le voir, ma fonction dotdotdot peut obtenir un tableau de classes / ids pour dotdotdot, ou une seule classe / id.

Le $ jq est le remplacement de jqlite pour $ de jQuery.

Merci @SmokeyPhp, j'ai cherché depuis longtemps une méthode qui ne nécessite pas jQuery pour dotdotdot texte, et votre méthode est fantastique.

Bonjour, avez-vous travaillé comme suit …

 function Searchinput() { var str = "This is a test "; // Content of the div var lastWord = str.substr(str.trim().lastIndexOf(" ")+1); alert(lastWord) } 

http://jsbin.com/UWUTar/1/edit