2010-06-12 3 views
0

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

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

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

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

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

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

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

Спасибо

Edit:

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

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

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

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

ответ

0

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

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

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

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

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

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

+0

Итак, вы просматриваете страницу в середине слова? E ven ** если ** i t - переносится cor- прямо, это было бы наиболее враждебно. I ' d наиболее раздражает. ;) –

+0

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

1

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

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

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

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

span.marker { 
    border: 0px; padding: 0px; margin: 0px; 
    width:0px: overflow:hidden; height:0px; 
} 
+0

Или первый '
'. Неясно, какое форматирование текста имеет. –

+0

Это метод, который мы заменяем. Я думал, что все в порядке, но это не зависит от меня. Текст - это в основном абзацы. – drawnonward

+0

@ drawnonward: Нет более серьезных проблем в первую очередь? ;-) Если вы знаете: (1) Общее смещение последнего элемента на экране; (2) Аналогично для первого элемента вне экрана; (3) Размер шрифта, высота строки, отступы и край ... Тогда вам следует угадать достаточно близко. Уточните, запустив известный за пределами экрана и уточните одно слово за раз. –

Смежные вопросы