Domanda

Devo implementare i puntini di sospensione ( " ... " ) nel mezzo di un testo all'interno di un elemento ridimensionabile. Qui è come potrebbe apparire. Così,

"Lorem ipsum dolor sit amet. Ut ornare dignissim ligula sed commodo."

diventa

"Lorem ipsum dolor sit amet ... commodo."

Quando l'elemento è allungato fino alla larghezza del testo, voglio che i puntini di sospensione scompaiano. Come si può fare?

È stato utile?

Soluzione

In HTML, inserisci il valore completo in un attributo dati- * personalizzato come

<span data-original="your string here"></span>

Quindi assegnare i listener di eventi load e resize a una funzione JavaScript che leggerà l'attributo di dati originale e lo posizionerà nel innerHTML del tuo tag span. Ecco un esempio della funzione dei puntini di sospensione:

function start_and_end(str) {
  if (str.length > 35) {
    return str.substr(0, 20) + '...' + str.substr(str.length-10, str.length);
  }
  return str;
}

Regola i valori o, se possibile, rendili dinamici, se necessario per oggetti diversi. Se hai utenti da browser diversi, puoi rubare una larghezza di riferimento da un testo con lo stesso carattere e la stessa dimensione altrove nella tua dom. Quindi interpolare una quantità appropriata di caratteri da utilizzare.

Un suggerimento è anche quello di avere un abbr-tag sul ... o chi messaggio per rendere l'utente in grado di ottenere una descrizione comando con la stringa completa.

<abbr title="simple tool tip">something</abbr>

Altri suggerimenti

Vorrei proporre il mio esempio di risoluzione di questo problema.

L'idea principale è quella di dividere il testo in due parti pari (o la prima è più grande, se la lunghezza è dispari) una delle quali presenta dei puntini di sospensione alla fine e un'altra allineata a destra con text-overflow: clip .

Quindi tutto ciò che devi fare con js, se vuoi renderlo automatico / universale - è dividere la stringa e impostare gli attributi.

Tuttavia presenta alcuni svantaggi.

  1. Nessun buon avvolgimento di parole o lettere ( text-overflow: '' funziona solo in FF al momento)
  2. Se la divisione avviene tra le parole, lo spazio dovrebbe essere nella prima parte. Altrimenti, sarà crollato.
  3. L'estremità della stringa non dovrebbe avere punti esclamativi, a causa di direction: rtl - verranno spostati a sinistra della stringa. Penso che sia possibile risolvere questo problema inserendo la parte giusta della parola nel tag e il punto esclamativo nello pseudo-elemento :: after . Ma non l'ho ancora fatto funzionare correttamente.

Ma, con tutto ciò, mi sembra davvero interessante, specialmente quando trascini il bordo del browser, cosa che puoi fare facilmente sulla pagina jsfiddle: https://jsfiddle.net/extempl/93ymy3oL/ . O esegui semplicemente lo snippet con una larghezza massima fissa inferiore.

GIF sotto lo spoiler:

  

 Gif

body {
  max-width: 400px;
}

span::before, span::after {
  display: inline-block;
  max-width: 50%;
  overflow: hidden;
  white-space: pre;
}

span::before {
  content: attr(data-content-start);
  text-overflow: ellipsis;
}

span::after {
  content: attr(data-content-end);
  text-overflow: '';
  direction: rtl;
}
<span data-content-start="Look deep into nature, and then you " 
      data-content-end=  "will understand everything better"></span>

<br>
<span data-content-start="https://www.google.com.ua/images/branding/g" 
      data-content-end=  "ooglelogo/2x/googlelogo_color_272x92dp.png"></span>

Quindi il mio collega ha trovato una soluzione che non utilizza elementi dom aggiuntivi. Controlliamo se il div trabocca e aggiungiamo un attributo di dati degli ultimi n caratteri. Il resto è fatto in CSS.

Ecco un po 'di HTML:

<div class="box">
    <div class="ellipsis" data-tail="some">This is my text it is awesome</div>
</div>
<div class="box">
    <div class="ellipsis">This is my text</div>
</div>

E il css:

.box {
    width: 200px;
}

.ellipsis:before {
    float: right;
    content: attr(data-tail);
}

.ellipsis {
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
}

Ecco il jsfiddle obbligatorio per questo: http://jsfiddle.net/r96vB/1/

La seguente funzione Javascript eseguirà un troncamento centrale, come OS X:

function smartTrim(string, maxLength) {
    if (!string) return string;
    if (maxLength < 1) return string;
    if (string.length <= maxLength) return string;
    if (maxLength == 1) return string.substring(0,1) + '...';

    var midpoint = Math.ceil(string.length / 2);
    var toremove = string.length - maxLength;
    var lstrip = Math.ceil(toremove/2);
    var rstrip = toremove - lstrip;
    return string.substring(0, midpoint-lstrip) + '...' 
    + string.substring(midpoint+rstrip);
}       

Sostituirà i caratteri al centro con i puntini di sospensione. I miei test unitari mostrano:

var s = '1234567890';
assertEquals(smartTrim(s, -1), '1234567890');
assertEquals(smartTrim(s, 0), '1234567890');
assertEquals(smartTrim(s, 1), '1...');
assertEquals(smartTrim(s, 2), '1...0');
assertEquals(smartTrim(s, 3), '1...90');
assertEquals(smartTrim(s, 4), '12...90');
assertEquals(smartTrim(s, 5), '12...890');
assertEquals(smartTrim(s, 6), '123...890');
assertEquals(smartTrim(s, 7), '123...7890');
assertEquals(smartTrim(s, 8), '1234...7890');
assertEquals(smartTrim(s, 9), '1234...67890');
assertEquals(smartTrim(s, 10), '1234567890');
assertEquals(smartTrim(s, 11), '1234567890');

Non puoi farlo con i CSS. Il problema è che HTML e CSS dovrebbero funzionare su una varietà di browser e caratteri ed è quasi impossibile calcolare la larghezza di una stringa in modo coerente. Questa è una idea che potrebbe aiutarti. Tuttavia, dovresti farlo più volte, fino a quando non trovi la stringa con la larghezza appropriata.

Potrebbe essere un po 'tardi nel gioco, ma stavo cercando una soluzione a questo, e un collega ne ha suggerito uno molto elegante, che condividerò. Richiede alcuni JS, ma non molto.

Immagina di avere un div di una dimensione in cui devi inserire la tua etichetta:

<div style="width: 200px; overflow: hidden"></div>

Ora hai una funzione che accetta due parametri: una stringa con l'etichetta e un elemento DOM (questo div ) per adattarlo a:

function setEllipsisLabel(div, label) 

La prima cosa da fare è creare un span con questa etichetta e inserirlo nel div :

var span = document.createElement('span');
span.appendChild(document.createTextNode(label));
span.style.textOverflow = 'ellipsis';
span.style.display = 'inline-block';
div.appendChild(span);

Impostiamo la proprietà overflow del testo su " ellissi " in modo che quando il testo viene troncato, un bel " ... " viene aggiunto alla fine per illustrare questo. Abbiamo anche impostato display su " blocco in linea " in modo che questi elementi abbiano dimensioni reali dei pixel che possiamo manipolare in seguito. Finora, nulla che non avremmo potuto fare con CSS puro.

Ma vogliamo i puntini di sospensione al centro. Innanzitutto, dovremmo scoprire se ne abbiamo assolutamente bisogno ... Questo può essere fatto confrontando div.clientWidth con span.clientWidth - le ellissi sono necessarie solo se < code> span è più ampio del div .

Se abbiamo bisogno di un puntino di sospensione, cominciamo dicendo che vogliamo un numero fisso di caratteri mostrato alla fine della parola - diciamo 10. Quindi creiamo un intervallo contenente solo gli ultimi 10 caratteri dell'etichetta e rimaniamo nel div:

var endSpan = document.createElement('span');
endSpan.style.display = 'inline-block';
endspan.appendChild(document.createTextNode(label.substring(label.length - 10)));
div.appendChild(endSpan);

Ora, sostituiamo la larghezza del span originale per adattarlo a quello nuovo:

span.style.width = (div.clientWidth - endSpan.clientWidth) + 'px';

Di conseguenza, ora abbiamo una struttura DOM che assomiglia a questa:

<div style="width: 200px; overflow: hidden">
   <span style="display: inline-block; text-overflow: ellipsis; width: 100px">
      A really long label is shown in this span
   </span>
   <span style="display: inline-block"> this span</span>
</div>

Poiché il primo span ha overflow del testo impostato su " ellissi " ;, mostrerà " ... " alla fine, seguito dai 10 caratteri del secondo intervallo, risultanti nell'ellissi mostrata approssimativamente al centro del div .

Non è necessario codificare nemmeno la lunghezza di 10 caratteri per endSpan: questo può essere approssimato calcolando il rapporto tra la larghezza iniziale del span e quella del div , sottraendo la proporzione appropriata dalla lunghezza dell'etichetta e dividendo per due.

Dopo alcune ricerche sulle scatole flessibili ho trovato questa soluzione CSS pura che credo sia piuttosto interessante.

<div style="width:100%;border:1px solid green;display:inline-flex;flex-wrap:nowrap;">
   <div style="flex: 0 1 content;text-overflow: ellipsis;overflow:hidden;white-space:nowrap;"> Her comes very very very very very very very very very very very very very very very very very very very long </div>
   <div style="flex: 1 0 content;white-space:nowrap;"> &nbsp;but flexible line</div>
</div>

Ecco il bit più breve che ho trovato che sostituisce 3 caratteri nel mezzo con ....

function shorten(s, max) {
  return s.length > max ? s.substring(0, (max / 2) - 1) + '...' + s.substring(s.length - (max / 2) + 2, s.length) : s
}

Questa soluzione è una combinazione delle soluzioni precedenti e mette l'ultima parola intera alla fine del testo abbreviato. Tuttavia, nel caso in cui l'ultima parola sia più lunga di un terzo dello spazio disponibile, viene anche abbreviata da sinistra. Se viene trovato un trattino (" - "), taglialo da lì, in caso contrario, taglialo comunque.

function truncate(text, textLimit) {
    if (!text) return text;
    if (textLimit < 1) return string;
    if (text.length < textLimit) return text;
    if (textLimit === 1) return text.substring(0,1) + '...';
    /* extract the last word */
    var lastPart = text.slice( string.lastIndexOf(' ')+1 );
    /* if last word is longer then a third of the max available space
       cut it from the left */
    var lastPartLimit = Math.ceil(textLimit / 3);
    if(lastPart.length > lastPartLimit) {
        var truncatedLastPart = lastPart;
        /* Try to find a dash and cut the last word there */
        var lastDashPart = text.slice( text.lastIndexOf('-')+1 );
        if(lastDashPart.length < lastPartLimit){
            truncatedLastPart = lastDashPart;
        }
        /* If the last part is still to long or not available cut it anyway */
        if(truncatedLastPart.length > lastPartLimit) {
            var lastIndex = lastPart.length - lastPartLimit;
            truncatedLastPart = lastPart.substring( lastIndex );
        }
        lastPart = truncatedLastPart;
    }
    var dots = '... ';
    var firsPartLength = textLimit - lastPart.length - dots.length;
    return text.substring(0, firstPartLength) + dots + lastPart;
}

console.log( truncate("New York City", 10) ); // Ne... City (max of 10 characters)
console.log( truncate("New York Kindergarden", 14) ); // Ne...ergarden (max of 14 characters, last word gets cut from the left by a third)
console.log( truncate("New York Kinder-garden", 14) ); // Ne...garden (max of 14 characters, last word gets cut by the dash from the left)

Ho appena creato una funzione che può tagliare al centro, vicino a End ed End ma non è stata ancora testata perché finalmente ne avevo bisogno sul lato server

//position acceptable values : middle, end, closeEnd
function AddElipsis(input, maxChars, position) {
    if (typeof input === 'undefined') {
        return "";
    }
    else if (input.length <= maxChars) {
        return input;
    }
    else {
        if (position == 'middle') {
            var midPos = Math.floor(maxChars / 2) - 2;
            return input.substr(0, midPos) + '...' + input.substr(input.length - midPos, input.length);
        }
        else if (position == 'closeEnd') {
            var firstPart = Math.floor(maxChars * 0.80) - 2;
            var endPart = Math.floor(maxChars * 0.20) - 2;
            return input.substr(0, firstPart) + '...' + input.substr(input.length - endPart, input.length);
        }
        else {
            return input.substr(0, maxChars - 3) + '...';
        }
    }
}

Un'altra pugnalata:

function truncate( str, max, sep ) {
    max = max || 10;
    var len = str.length;
    if(len > max){
        sep = sep || "...";
        var seplen = sep.length;
        if(seplen > max) { return str.substr(len - max) }

        var n = -0.5 * (max - len - seplen);
        var center = len/2;
        return str.substr(0, center - n) + sep + str.substr(len - center + n);
    }
    return str;
}

console.log( truncate("123456789abcde") ); // 123...bcde (using built-in defaults) 
console.log( truncate("123456789abcde", 8) ); // 12...cde (max of 8 characters) 
console.log( truncate("123456789abcde", 12, "_") ); // 12345_9abcde (customize the separator) 

Questo ti darà un po 'più di controllo sulla posizione dei puntini di sospensione e sul testo segnaposto:

function ellipsis(str, maxLength, ellipsisLocationPercentage,placeholder) {
    /*
    ARGUMENTS:
    str - the string you want to maninpulate
    maxLength -  max number of characters allowed in return string
    ellipsisLocationPercentage (optional) - How far (percentage wise) into the return string you want the ellipses to be placed
        Examples:
        .85 : This is a very long string. This is a very long string. This is a very long string. This is a ver[...]very long string.
        .25 : This is a very long string. [...]g. This is a very long string. This is a very long string. This is a very long string.
    placeholder (optional) - this will be used to replace the removed substring. Suggestions : '...', '[..]', '[ ... ]', etc....
    */
    if(ellipsisLocationPercentage == null || isNaN(ellipsisLocationPercentage) || ellipsisLocationPercentage >= 1 || ellipsisLocationPercentage <= 0){
        //we've got null or bad data.. default to something fun, like 85% (that's fun, right??)
        ellipsisLocationPercentage = .85;
    }
    if(placeholder == null || placeholder ==""){
        placeholder = "[...]";
    }

    if (str.length > (maxLength-placeholder.length)) {
        //get the end of the string
        var beginning = str.substr(0, (maxLength - placeholder.length)*ellipsisLocationPercentage );
        var end = str.substr(str.length-(maxLength - placeholder.length) * (1-ellipsisLocationPercentage));
        return beginning + placeholder + end;
    }
    return str;
}

Puoi chiamare questa funzione chiamando:

ellipsis("This is a very long string. Be Scared!!!!", 8);//uses default values
ellipsis("This is a very long string. Be Scared!!!!", 8,.5);//puts ellipsis at half way point
ellipsis("This is a very long string. Be Scared!!!!", 8,.75,'<..>');//puts ellipsis at 75% of the way into the string and uses '<..>' as the placeholder

Per fare un taglio netto e avere un'intera parola alla fine del testo abbreviato, ho usato la seguente funzione.

function prepareText(text){
  var returnString = text;
  var textLimit = 35;
  if(text.length > textLimit){
    var lastWord = text.slice( text.lastIndexOf(' ')+1 );
    var indexFromEnd = lastWord.length;
    var ellipsis = '... ';

    returnString = text.slice(0, textLimit - indexFromEnd - ellipsis.length);
    returnString = returnString + ellipsis + lastWord;
  }
  return returnString;
}

$('#ex1Modified').html( prepareText( $('#ex1').html() ) );

$('#ex2Modified').html( prepareText( $('#ex2').html() ) );

$('#ex3Modified').html( prepareText( $('#ex3').html() ) );
body{color:#777; font-family: sans-serif;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<h2>Shortened Quotes from Albert Einstein</h2>

<div id="ex1">"The true sign of intelligence is not knowledge but imagination."</div>
<div id="ex1Modified"></div>
<br>
<div id="ex2">"Look deep into nature, and then you will understand everything better."</div>
<div id="ex2Modified"></div>
<br>
<div id="ex3">"You can't blame gravity for falling in love."</div>
<div id="ex3Modified"></div>

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top