мера визуализации HTML в JavaScript, не влияя на измерение - PullRequest
0 голосов
/ 12 июня 2010

Я делаю нумерацию страниц в JavaScript. Это типографская нумерация страниц, а не разделение результатов базы данных. По большей части это работает, но я столкнулся с проблемой Гейзенберга, где я не могу измерить текст, не затрагивая его.

Я не пытаюсь измерить текст перед его обработкой . Я хочу, чтобы фактическое положение отображалось на экране, чтобы я мог разбить его на страницы, где он естественным образом обернут. Я измеряю вертикальное положение символов, а не горизонтальную ширину строк. То, как я это делаю, похоже на этот ответ в том смысле, что я применяю стиль к блоку текста, а затем измеряю положение вновь созданного диапазона. Если интервал не достигает конца страницы, я очищаю его и создаю новый интервал при линейном поиске.

Проблема в том, что сглаженный субпиксельный текстовый макет отличается при применении диапазона. В редких случаях это заставляет текст по-разному переноситься, когда я его измеряю. Я видел это только при переносе через дефис и полагаю, что этого не произойдет при переносе в пробел.

В качестве конкретного примера, "подготовленный он" - это строка, с которой у меня проблемы. Когда я подхожу к «подготовке», то, как и ожидалось, оказывается внутри текущей страницы. Когда я измеряю «подготовлено», вся фраза переносится на следующую строку, перемещая ее на следующую страницу, так что похоже, что «d» - это символ, на который нужно перейти. Я разбиваю текст между «подготовить» и «д-он», и это неправильно. Попытка оценить отдельных персонажей открывает целую банку червей, которых я бы предпочел избежать. Обтекание изменяется, потому что с новым диапазоном линия становится на 1 пиксель шире.

Решением моей проблемы может быть либо лучший способ измерить текст с помощью javascript, либо способ обернуть текст в новый элемент без влияния на макет.

Я попытался установить margin-right:-1px для класса создаваемого диапазона, чтобы обернуть текст. Это не оказало заметного эффекта.

Я делаю это в UIWebView на iPhone. Существуют некоторые вызовы, связанные с измерениями, которые доступны в обычном WebKit и которые недоступны здесь. Например, Range не имеет getBoundingClientRect или поддерживает установку смещения, отличного от 0, в setStart или setEnd.

Спасибо

Edit:

Я попробовал предложение от unomi о том, чтобы сделать промежуток безразмерным. Это не имело никакого эффекта. Класс, который я даю промежутку, не имеет правил и просто используется для быстрого удаления.

Я пытался выполнять итерацию назад, а не вперед по тексту. Ошибки упаковки были обнаружены в разных местах, но общая проблема осталась.

Текст состоит в основном из абзацев с простым оформлением. Я не думаю, что метод, который я использую, будет работать с таблицами или списками. В абзацах я применяю интервал к одному символу за раз.

Я попытался уменьшить размер шрифта для диапазона. Кажется, что правила переноса позволяют переносить интервал, даже если он находится внутри слова, поэтому один набор ошибок заменяется другим.

Ответы [ 2 ]

1 голос
/ 12 июня 2010

Это немного отговорка, но вы действительно хотите разделить абзац?
Не улучшит ли это удобочитаемость, чтобы просто разбить первый <p>, который отклоняется от области просмотра?

Хорошо, так что для ясности, звучит так, будто вы тестируете позицию диапазона, который перемещается символ за символом через текст? Если это правильно, и проблема в том, что вы разбиваете слова, почему бы вам просто не перепрыгнуть с пробела на пробел (возможно, включая дефисы), а не с символа на символ?

Сохранить 1 предыдущее местоположение и разбить его, когда текущее местоположение отключено.

Полагаю, прежде чем будет сделано слишком много, мы уверены, что не сможем сделать этот промежуток действительно безразмерным?

span.marker {
  border: 0px; padding: 0px; margin: 0px; 
  width:0px: overflow:hidden; height:0px;
}
0 голосов
/ 15 июня 2010

Я не нашел идеального решения.Это решение, которое я придумал.

Я применяю интервал измерения к одному символу за раз.Я нашел два случая, когда были проблемы.Иногда слово будет длиннее, и слово будет переноситься на следующую строку при измерении.Иногда слово с дефисом или похожим символом при измерении делится по-разному.

Для случая, когда целое слово переносится по-разному, я изменяю класс диапазона измерения, чтобы иметь меньший размер шрифта.Если этот же символ не переносится на следующую строку при использовании меньшего размера шрифта, я игнорирую измерение как недействительное и продолжаю поиск.

Для случая переноса слов по-разному, я измеряю тот же символ спредыдущий персонаж.Если диапазон не содержит двух символов, то я предполагаю, что следующий символ будет перенесен и разбит там.

Эти проблемы, кажется, возникают, потому что форматирование изменяет кернинг между символами.Когда я использую диапазон для измерения положения символа, он находится в несколько ином положении, поскольку он начинается на границе пикселей и игнорирует кернинг предыдущего символа.

Я не пытался охватить весь символблок текста вместо одного символа.Это добавило бы некоторую сложность, и я подозреваю, что те же проблемы возникнут немного по-другому.

...