Обновление: обработка этого в CSS удивительно проста и требует минимальных затрат, но вы не можете контролировать, где происходят разрывы, когда они происходят. Это нормально, если вам все равно, или ваши данные имеют длинные буквенно-цифровые операции без каких-либо естественных разрывов. У нас было много длинных путей к файлам, URL-адресов и телефонных номеров, во всех из которых есть места, на которые лучше прорваться, чем на других.
Наше решение состояло в том, чтобы сначала использовать замену регулярных выражений, чтобы поставить пробел нулевой ширины (& # 8203;) после каждых 15 (скажем) символов, которые не являются пробелами или одним из специальных символов, где мы бы предпочли разрывы. Затем мы делаем другую замену, чтобы поставить пробел нулевой ширины после этих специальных символов.
Пространства с нулевой шириной хороши, потому что они никогда не видны на экране; стеснительные дефисы сбивают с толку, когда они показывают, потому что данные имеют значительные дефисы. Пробелы нулевой ширины также не учитываются при копировании текста из браузера.
В настоящее время используются специальные символы разрыва: точка, косая черта, обратная косая черта, запятая, подчеркивание, @, | и дефис. Вы бы не подумали, что вам нужно что-то делать, чтобы поощрять разрывы после дефисов, но Firefox (по крайней мере, 3.6 и 4) не разрывается сам по себе в дефисах, окруженных номерами (например, номерами телефонов).
Мы также хотели контролировать количество символов между искусственными перерывами, основываясь на доступном пространстве макета. Это означало, что регулярное выражение для соответствия длинным непрерывным циклам должно быть динамическим. Это часто называют, и мы не хотели создавать одни и те же одинаковые регулярные выражения снова и снова из соображений производительности, поэтому мы использовали простой кэш регулярных выражений, определяемый выражением регулярного выражения и его флагами.
Вот код; вы бы, вероятно, назвали пространство функций в пакете утилит:
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 = {};
Тест, как это:
makeWrappable('12345678901234567890 12345678901234567890 1234567890/1234567890')
Обновление 2: Кажется , что нулевой ширины пространства фактически будут включены в скопированный текст , по крайней мере , в некоторых случаях, вы просто не можете их видеть. Очевидно, что поощрение людей к копированию текста со скрытыми символами в нем - это приглашение к вводу подобных данных в другие программы или системы, даже в ваши собственные, где это может вызвать проблемы. Например, если он попадает в базу данных, поиск по нему может завершиться неудачей, и строки поиска, подобные этой, также, вероятно, не пройдут. Использование клавиш со стрелками для перемещения по таким данным требует (справедливо) дополнительного нажатия клавиш для перемещения по символу, который вы не видите, несколько странным для пользователей, если они заметят.
В закрытой системе вы можете отфильтровать этот символ на входе, чтобы защитить себя, но это не помогает другим программам и системам.
В общем, эта техника хорошо работает, но я не уверен, какой будет лучший выбор вызывающего персонажа.
Обновление 3. Наличие этого символа в данных больше не является теоретической возможностью, это наблюдаемая проблема. Пользователи отправляют данные, скопированные с экрана, они сохраняются в БД, поиск прерывается, что-то странно сортируется и т. Д.
Мы сделали две вещи:
- Написал утилиту для удаления их из всех столбцов всех таблиц во всех источниках данных для этого приложения.
- Добавлена фильтрация, чтобы удалить его в нашем стандартном процессоре ввода строк, чтобы он исчез к тому времени, когда его увидит любой код.
Это работает хорошо, как и сама техника, но это предостерегающая история.
Обновление 4: мы используем это в контексте, где данные, подаваемые на это, могут быть экранированы HTML. При правильных обстоятельствах он может вставлять пробелы нулевой ширины в середину сущностей HTML, что приводит к неожиданным результатам.
Исправлено было добавление амперсанда в список символов, на которых мы не разбиваемся, например:
var longRunsRegex = cachedRegex('([^&\\s\\.\/\\,_@\\|-]{' + position + '})(?=[^&\\s\\.\/\\,_@\\|-])', 'g');