Como posso imitar text-overflow: reticências no Firefox?
-
10-07-2019 - |
Pergunta
Eu tenho algum texto dinâmico contido em um div que está definido para o que um usuário digita em um campo de caixa de texto. Se o texto não couber na div, agora ele só é cortada na borda e todo o texto que ultrapassa a fronteira não é visível. Gostaria de truncar o texto para que ele se encaixa dentro da caixa e tem um reticências (...) anexado no final. Por exemplo:
|----div width------|
Here is some sample text that is too long.
Here is some sam...
Obviamente, o exemplo é fácil porque a tag de código usa uma fonte de largura fixa, por isso é tão simples como personagens de contagem. Eu tenho uma fonte de largura variável por isso, se eles entram "WWWWWWWWWWW" que vai encher-se em muito menos caracteres que "................" faria.
Qual é a melhor maneira de fazer isso? Eu encontrei uma solução potencial para simplesmente encontrar a largura de pixel real do texto aqui: http://www.codingforums.com/archive/index.php/t-100367.html
Mas mesmo com um método como esse, é um pouco estranho para implementar as reticências. Então, se é 20 caracteres, e acho que ele não se encaixa, eu teria de truncar a 19, adicionar o reticências, e em seguida, verifique se ele se encaixa novamente. Em seguida, truncar a 18 (mais o reticências) e tente novamente. E de novo. E mais uma vez ... até que ele se encaixa. Existe uma maneira melhor?
EDIT:. Decidi com base nas respostas que a minha abordagem original é melhor, só que eu tenho tentado melhorar a solução no link acima, não criando um elemento td separado simplesmente para medir, que se sente como um hack
Aqui está o meu código:
<div id="tab" class="tab">
<div id="tabTitle" class="tabTitle">
<div class="line1">user-supplied text will be put here</div>
<div class="line2">more user-supplied text will be put here</div>
</div>
</div>
e estilos:
.tab {
padding: 10px 5px 0px 10px;
margin-right: 1px;
float: left;
width: 136px;
height: 49px;
background-image: url(../images/example.gif);
background-position: left top;
background-repeat: no-repeat;
}
.tab .tabTitle {
height: 30px;
width: 122px;
overflow: hidden;
text-overflow: ellipsis;
font-size: 12px;
font-weight: bold;
color: #8B8B8B;
}
.tab .tabTitle .line1, .tab .tabTitle .line2 {
display:inline;
width:auto;
}
eo javascript que guarnições e acrescenta as reticências:
function addOverflowEllipsis( containerElement, maxWidth )
{
var contents = containerElement.innerHTML;
var pixelWidth = containerElement.offsetWidth;
if(pixelWidth > maxWidth)
{
contents = contents + "…"; // ellipsis character, not "..." but "…"
}
while(pixelWidth > maxWidth)
{
contents = contents.substring(0,(contents.length - 2)) + "…";
containerElement.innerHTML = contents;
pixelWidth = containerElement.offsetWidth;
}
}
O "line1" e "line2" divs são passadas para a função. Ele funciona no caso de uma única entrada palavra como "WWWWWWWWWWWWWWWWW" mas não funciona de um multi-palavra de entrada "WWWWW WWWWW WWWWW" porque ele só acrescenta quebras de linha e medidas do texto como sendo a largura da "WWWWW".
Existe uma maneira eu posso corrigir isso sem recorrer a copiar o texto em um elemento de medição escondido? Alguma maneira para definir o estilo dos divs linha para que eles não quebrar o texto?
Solução
Alguns maneira de definir o estilo dos divs linha para que eles não quebrar o texto?
Lá você tem o white-space: nowrap
para. Sim, isso funciona em navegadores antigos também.
Outras dicas
Esta questão tem de estar trabalhando em Firefox também.
HTML
<div class="ellipsis">Here goes too long text and when it is takes more than 200px in "end" of the text appears "..."</div>
CSS
.ellipsis{
width:200px;
text-overflow:ellipsis;
-o-text-overflow:ellipsis;
-moz-binding:url('bindings.xml#ellipsis');//issue for Firefox
}
bindings.xml
<bindings xmlns="http://www.mozilla.org/xbl" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="none">
<content><children/></content>
</binding>
<binding id="ellipsis">
<content>
<xul:label crop="end"><children/></xul:label>
</content>
<implementation>
<field name="label">document.getAnonymousNodes(this)[0]</field>
<field name="style">this.label.style</field>
<property name="display">
<getter>this.style.display</getter>
<setter>if(this.style.display!= val)this.style.display=val</setter>
</property>
<property name="value">
<getter>this.label.value</getter>
<setter>if(this.label.value!=val)this.label.value=val</setter>
</property>
<method name="update">
<body>
var strings= this.textContent.split(/\s+/g)
if(!strings[0])strings.shift()
if(!strings[strings.length-1])strings.pop()
this.value=strings.join('')
this.display=strings.length?'':'none'
</body>
</method>
<constructor>this.update()</constructor>
</implementation>
<handlers>
<handler event="DOMSubtreeModified">this.update()</handler>
</handlers>
</binding>
</bindings>
Se você estiver usando jQuery, há um ótimo plugin eu uso.
Como alternativa, [este exemplo] (404 NOT FOUND!) Parece funcionar cross browser.
Todas as perguntas, bateu-me nos comentários!
404 link: http://www.hedgerwow.com/360/ dhtml / text_overflow / demo2.php
A nova versão do CSS (CSS3) deve incluir text-overflow:ellipsis
, que faz isso para você. Ele atualmente trabalha em versões do IE 6 e para cima, assim como o Safari e Chrome. Não é suportado pelo Firefox, então isso não é realmente uma resposta útil ainda, mas vale a pena tendo em mente que a melhor maneira de verdade vai, finalmente, ser deixar alça CSS isso.
CSS3 especificações projecto: http: //www.w3.org/TR/2001/WD-css3-text-20010517/#text-overflow-props
Os navegadores suportados: http://www.quirksmode.org/css/contents.html (rolagem para baixo para "text-overflow" perto do fundo)
Muito simplesmente, não, não há nenhuma maneira melhor sem recorrer a hacks.
Você poderia, por exemplo, usar uma posição: espaço absoluto para posicionar o seu "..." no topo do conteúdo real, com overflow: hidden conjunto no recipiente, e só esconder o espaço extra se os ajustes de conteúdo dentro o recipiente. Isso deixaria você executar o código de truncagem apenas uma vez.
Pessoalmente, eu tinha acabado de executar o cálculo largura de pixel algumas vezes extra. Definir o texto e lendo a largura é uma operação rápida, por isso não deve ser perceptível.
Use text-overflow:ellipsis
. A sua não IE-only ... A maioria das grandes navegador pode fazer isso.
Mas se você não pode aqui é um plugin jQuery para isso.
Para responder a apenas um dos pontos que você levanta:
Então, se é 20 caracteres e acho que ele não se encaixa, eu teria que truncar a 19, adicionar o reticências, e em seguida, verifique se ele se encaixa novamente. Então truncar a 18 (mais a elipse) e tente novamente. E de novo. E de novo ... até que ele se encaixa. Tem alguma melhor maneira?
Um muito mais rápida maneira de encontrar o tamanho correto é cortar a corda ao meio, teste que para ver se ele se encaixa. Se isso acontecer: adicionar um quarto de parte de trás comprimento original, e se ele não cortará um quarto fora, então testar se para ver se ele se encaixa. Repita recursivamente com 1 / 8th, 1/16, 1 / 32th, ... do comprimento original, até que este add / valor subtrair é inferior a 1.
É um algoritmo de busca:. Para cordas que são mais do que apenas algumas palavras normalmente você pode reduzir o número de testes que você precisa para executar no DOM por um fator de 10
Tente isto:
Update:
Se você usar a proprietária {word-wrap: break-palavra;}, IE vai forçar uma quebra de linha. Navegadores modernos poderia ter o padrão. {overflow: visible;}, e que iria transbordar corretamente, sem expandir o recipiente
Não, não é tarefa simples. Eu tive que fazer mesma coisa ano atrás e descobriu que até mesmo Internet Explorer (a partir da versão 6), Opera e Safari pode fazê-lo, mas não o Firefox. Então, desculpe, apenas hacks pode poupar
Com o Opera:
-o-text-overflow:ellipsis;
Eu mudei this.value=strings.join('')
para this.value=strings.join(' ')
de resposta Binyamin 's, e funcionou para mim muito bem!
Sobre o Firefox 4.0 eo, ainda por implementar, propriedade text-overflow:ellipsis
CSS:
Este link dá uma solução parcial para o problema.
Ela produz um resultado semelhante ao text-overflow:ellipsis
usando apenas css.