Atualização: lidar com isso em CSS é maravilhosamente simples e com pouca sobrecarga, mas você não tem controle sobre onde ocorrem as quebras quando ocorrem. Tudo bem se você não se importa, ou seus dados têm execuções alfanuméricas longas sem interrupções naturais. Tínhamos muitos caminhos de arquivos, URLs e números de telefone longos, todos com lugares em que é significativamente melhor procurar do que outros.
Nossa solução foi usar primeiro uma substituição de regex para colocar um espaço de largura zero (& # 8203;) após cada 15 (digamos) caracteres que não são espaços em branco ou um dos caracteres especiais onde preferimos quebras. Em seguida, fazemos outra substituição para colocar um espaço de largura zero após esses caracteres especiais.
Espaços com largura zero são bons, porque eles nunca são visíveis na tela; hífens tímidos eram confusos quando mostraram, porque os dados têm hífens significativos. Os espaços com largura zero também não são incluídos quando você copia o texto do navegador.
Os caracteres de interrupção especiais que estamos usando atualmente são ponto final, barra invertida, barra invertida, vírgula, sublinhado, @, | e hífen. Você não acha que precisaria fazer algo para encorajar a quebra de hífens, mas o Firefox (pelo menos 3.6 e 4) não quebra sozinho em hífens cercados por números (como números de telefone).
Também queríamos controlar o número de caracteres entre quebras artificiais, com base no espaço de layout disponível. Isso significava que o regex para corresponder a longas execuções sem interrupção precisava ser dinâmico. Isso é chamado muito, e não queríamos criar as mesmas regexes idênticas repetidamente por motivos de desempenho; portanto, usamos um cache de regex simples, codificado pela expressão de regex e seus sinalizadores.
Aqui está o código; você provavelmente nomeará as funções em um pacote de utilitários:
makeWrappable = function(str, position)
{
if (!str)
return '';
position = position || 15; // default to breaking after 15 chars
// matches every requested number of chars that's not whitespace or one of the special chars defined below
var longRunsRegex = cachedRegex('([^\\s\\.\/\\,_@\\|-]{' + position + '})(?=[^\\s\\.\/\\,_@\\|-])', 'g');
return str
.replace(longRunsRegex, '$1​') // put a zero-width space every requested number of chars that's not whitespace or a special char
.replace(makeWrappable.SPECIAL_CHARS_REGEX, '$1​'); // and one after special chars we want to allow breaking after
};
makeWrappable.SPECIAL_CHARS_REGEX = /([\.\/\\,_@\|-])/g; // period, forward slash, backslash, comma, underscore, @, |, hyphen
cachedRegex = function(reString, reFlags)
{
var key = reString + (reFlags ? ':::' + reFlags : '');
if (!cachedRegex.cache[key])
cachedRegex.cache[key] = new RegExp(reString, reFlags);
return cachedRegex.cache[key];
};
cachedRegex.cache = {};
Teste assim:
makeWrappable('12345678901234567890 12345678901234567890 1234567890/1234567890')
Atualização 2: Parece que espaços com largura zero estão incluídos no texto copiado em pelo menos algumas circunstâncias, você simplesmente não pode vê-los. Obviamente, incentivar as pessoas a copiarem textos com caracteres ocultos é um convite para que dados como esses sejam inseridos em outros programas ou sistemas, até os seus, onde isso pode causar problemas. Por exemplo, se ele terminar em um banco de dados, as pesquisas nele poderão falhar e as cadeias de pesquisa como essa provavelmente também falharão. O uso das teclas de seta para mover dados como esse requer (com razão) um pressionamento de tecla extra para mover o personagem que você não pode ver, um tanto bizarro para os usuários, se eles perceberem.
Em um sistema fechado, você pode filtrar esse caractere na entrada para se proteger, mas isso não ajuda outros programas e sistemas.
No total, essa técnica funciona bem, mas não tenho certeza de qual seria a melhor escolha de personagem causador de quebra.
Atualização 3: Ter esse personagem nos dados não é mais uma possibilidade teórica, é um problema observado. Os usuários enviam os dados copiados da tela, eles são salvos no banco de dados, as pesquisas quebram, as coisas ficam estranhamente etc.
Fizemos duas coisas:
- Escreveu um utilitário para removê-los de todas as colunas de todas as tabelas em todas as fontes de dados para este aplicativo.
- Adicionado filtro para removê-lo para o nosso processador de entrada de string padrão, para que ele acabe quando qualquer código o vir.
Isso funciona bem, assim como a própria técnica, mas é uma história de advertência.
Atualização 4: estamos usando isso em um contexto em que os dados fornecidos a isso podem ser escapados em HTML. Sob as circunstâncias certas, ele pode inserir espaços de largura zero no meio de entidades HTML, com resultados descolados.
A correção foi adicionar e comercial à lista de caracteres que não quebramos, assim:
var longRunsRegex = cachedRegex('([^&\\s\\.\/\\,_@\\|-]{' + position + '})(?=[^&\\s\\.\/\\,_@\\|-])', 'g');