Aktualizacja: Obsługa tego w CSS jest cudownie prosta i niewielka, ale nie masz kontroli nad tym, gdzie występują przerwy, kiedy się pojawiają. To dobrze, jeśli nie obchodzi Cię to lub Twoje dane mają długie przebiegi alfanumeryczne bez żadnych naturalnych przerw. Mieliśmy wiele długich ścieżek do plików, adresów URL i numerów telefonów, z których wszystkie mają miejsca, w których znacznie lepiej jest złamać niż inne.
Nasze rozwiązanie polegało na tym, że najpierw użyliśmy zamiany wyrażenia regularnego, aby wstawić spację o zerowej szerokości (& # 8203;) po każdych 15 (powiedzmy) znakach, które nie są białymi znakami lub jednym ze znaków specjalnych, w których wolelibyśmy przerwy. Następnie dokonujemy kolejnej zamiany, aby wstawić spację o zerowej szerokości po tych znakach specjalnych.
Przestrzenie o zerowej szerokości są fajne, ponieważ nigdy nie są widoczne na ekranie; nieśmiałe łączniki były mylące, gdy się pojawiały, ponieważ dane zawierają znaczące łączniki. Spacje o zerowej szerokości również nie są uwzględniane podczas kopiowania tekstu z przeglądarki.
Znaki specjalne, których obecnie używamy, to kropka, ukośnik, lewy ukośnik, przecinek, podkreślenie, @, | i łącznik. Nie sądzisz, że musisz robić cokolwiek, aby zachęcić do łamania myślników, ale Firefox (przynajmniej 3.6 i 4) nie dzieli się samoczynnie na myślniki otoczone liczbami (jak numery telefonów).
Chcieliśmy także kontrolować liczbę znaków między sztucznymi przerwami w oparciu o dostępną przestrzeń układu. Oznaczało to, że wyrażenie regularne pasujące do długich nieprzerwanych przebiegów musiało być dynamiczne. Jest to często wywoływane, a my nie chcieliśmy tworzyć w kółko tych samych identycznych wyrażeń regularnych ze względu na wydajność, więc użyliśmy prostej pamięci podręcznej wyrażeń regularnych, kluczowanej przez wyrażenie regex i jego flagi.
Oto kod; prawdopodobnie nazwałbyś funkcje w pakiecie narzędzi:
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 = {};
Testuj w ten sposób:
makeWrappable('12345678901234567890 12345678901234567890 1234567890/1234567890')
Aktualizacja 2: Wygląda na to, że w rzeczywistości są spacje o zerowej szerokości zawarte w kopiowanym tekście przynajmniej w niektórych okolicznościach, po prostu ich nie widać. Oczywiście zachęcanie ludzi do kopiowania tekstu z ukrytymi znakami jest zaproszeniem do wprowadzania takich danych do innych programów lub systemów, nawet własnych, gdzie może to powodować problemy. Na przykład, jeśli trafi do bazy danych, wyszukiwanie w niej może się nie powieść, a ciągi wyszukiwania takie jak ten prawdopodobnie również się nie powiodą. Używanie klawiszy strzałek do poruszania się po takich danych wymaga (słusznie) dodatkowego naciśnięcia klawisza, aby poruszać się po postaci, której nie widzisz, co jest nieco dziwne dla użytkowników, jeśli zauważą.
W systemie zamkniętym możesz odfiltrować ten znak na wejściu, aby się chronić, ale to nie pomaga innym programom i systemom.
Podsumowując, ta technika działa dobrze, ale nie jestem pewien, jaki byłby najlepszy wybór postaci powodującej przełom.
Aktualizacja 3: Umieszczenie tej postaci w danych nie jest już teoretyczną możliwością, jest to obserwowany problem. Użytkownicy przesyłają dane skopiowane z ekranu, są one zapisywane w bazie danych, przerwy w wyszukiwaniu, dziwne sortowanie itp.
Zrobiliśmy dwie rzeczy:
- Napisałem narzędzie do usuwania ich ze wszystkich kolumn wszystkich tabel we wszystkich źródłach danych dla tej aplikacji.
- Dodano filtrowanie, aby usunąć go z naszego standardowego procesora wejściowego ciągów, więc zniknie, gdy zobaczy go jakikolwiek kod.
Działa to dobrze, podobnie jak sama technika, ale to przestroga.
Aktualizacja 4: Używamy tego w kontekście, w którym przekazywane dane mogą zawierać znaki ucieczki HTML. W odpowiednich okolicznościach może wstawić spacje o zerowej szerokości w środku jednostek HTML, z dziwacznymi wynikami.
Naprawiono dodanie znaku „&” do listy znaków, których nie łamiemy, na przykład:
var longRunsRegex = cachedRegex('([^&\\s\\.\/\\,_@\\|-]{' + position + '})(?=[^&\\s\\.\/\\,_@\\|-])', 'g');