更新:在 CSS 中处理这个非常简单且开销很低,但是您无法控制中断发生的位置。如果您不在乎,那很好,或者您的数据有很长的字母数字运行而没有任何自然中断。我们有很多长文件路径、URL 和电话号码,所有这些都有比其他文件更容易破解的地方。
我们的解决方案是首先使用正则表达式替换,在每 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');