2010-06-12 4 views
0

Je fais la pagination en javascript. Ceci est une pagination typographique, ne pas couper les résultats de la base de données. Pour la plupart, cela fonctionne, mais j'ai rencontré un problème Heisenberg où je ne peux pas mesurer le texte sans l'affecter.mesure html rendu en javascript sans affecter la mesure

Je n'essaie pas de measure text before it is rendered. Je veux que la position réelle apparaisse à l'écran, pour que je puisse paginer là où il est enveloppé naturellement. Je mesure la position verticale des caractères, pas la largeur horizontale des chaînes. La façon dont je fais cela est similaire à this answer en ce sens que j'applique un style à un bloc de texte, puis je mesure la position de la nouvelle travée. Si la plage n'atteint pas la fin de la page, je l'efface et fais une nouvelle plage dans une recherche linéaire.

Le problème est que la disposition du texte sous-pixel anti-aliasé est différente lorsque l'intervalle est appliqué. Dans de rares cas, le texte s'enroule différemment lorsque je le mesure. Je n'ai vu cela que lors de l'emballage à un trait d'union, et je suppose que cela n'arriverait pas lors de l'emballage à l'espace blanc.

À titre d'exemple concret, «prepare-he» est la chaîne avec laquelle j'ai des problèmes. Quand je mesure jusqu'à "préparer" il apparaît, comme prévu, d'être dans la page actuelle. Quand je mesure "préparé", la phrase entière se termine à la ligne suivante, en la déplaçant vers la page suivante, de sorte que le "d" est le caractère à percer. Je casse le texte entre "préparer" et "d-il" et c'est faux. Essayer d'évaluer les caractères individuels ouvre toute une boîte de vers que je préférerais éviter. L'habillage change car, avec la nouvelle plage, la ligne est plus large de 1 pixel.

Une solution à mon problème pourrait être soit une meilleure façon de mesurer le texte en utilisant javascript, ou un moyen d'envelopper le texte dans un nouvel élément sans affecter la mise en page.

J'ai essayé de définir margin-right:-1px pour la classe de l'étendue en cours de création afin d'envelopper le texte. Cela n'a eu aucun effet notable. Je le fais dans un UIWebView sur l'iPhone. Certains appels liés à la mesure sont disponibles dans WebKit normal et ne sont pas disponibles ici. Par exemple, Range n'a pas getBoundingClientRect ou prend en charge un décalage différent de 0 dans setStart ou setEnd.

Merci

Edit:

J'ai essayé la suggestion de unomi de faire la adimensionnel span. Cela n'a eu aucun effet. La classe que je donne la durée n'a pas de règles et est juste utilisée pour la suppression rapide.

J'ai essayé d'effectuer une itération en arrière plutôt qu'en avant dans le texte. Les erreurs d'emballage sont apparues à différents endroits mais le problème global est resté.

Le texte est principalement des paragraphes avec un style simple. Je ne pense pas que la méthode que j'utilise fonctionnerait avec des tables ou des listes. Dans les paragraphes, j'applique la portée à un caractère à la fois.

J'ai essayé de réduire la taille de la police pour l'intervalle. Les règles d'encapsulation semblent autoriser l'encapsulation à une étendue, même si elle se trouve dans un mot, ce qui remplace un ensemble d'erreurs par un autre.

Répondre

0

Je n'ai pas trouvé de solution idéale. C'est la solution que j'ai trouvée.

J'applique l'étendue de mesure à un caractère à la fois. J'ai trouvé deux cas où il y avait des problèmes. Parfois, un mot finissait par être plus long et le mot s'enroulait sur la ligne suivante lorsqu'il était mesuré. Parfois, un mot avec un trait d'union ou un caractère similaire se divise différemment lorsqu'il est mesuré.

Pour le cas d'un mot entier enveloppant différemment, je change la classe de l'étendue de mesure pour avoir une taille de police plus petite. Si le même caractère ne passe pas à la ligne suivante lorsque vous utilisez une taille de police plus petite, j'ignore la mesure comme non valide et continue la recherche.

Dans le cas d'un habillage de mot divisé différemment, je mesure le même caractère que le caractère précédent. Si l'étendue n'est pas entourée de deux caractères, je suppose que le caractère suivant s'enroulera et se cassera là. Ces problèmes semblent survenir car le formatage modifie le crénage entre les caractères. Lorsque j'utilise un span pour mesurer la position d'un personnage, il se trouve dans une position légèrement différente car il commence à une limite de pixels et ignore le crénage par rapport au caractère précédent.

Je n'ai pas essayé d'englober tout le bloc de texte au lieu d'un seul caractère. Cela ajouterait de la complexité et je suppose que les mêmes problèmes surgiraient d'une manière légèrement différente.

+0

Alors vous êtes en train de faire des pages au milieu d'un mot? E ven ** if ** i t est un trait d'union rectangle, qui serait le plus hostile à l'utilisateur. Je suis le plus agacé. ;) –

+0

Non, le but est de faire correspondre le wrapping de mot naturel utilisé par le navigateur Web.Le problème est que l'utilisation d'un span pour mesurer le texte change la taille du mot et les règles d'emballage, de sorte qu'il peut se casser au milieu d'un mot pendant la mesure. La meilleure solution serait un moyen de mesurer le texte qui ne change pas les règles d'emballage ou de casser les mots au milieu. La solution ci-dessus fonctionne autour du fait que la mesure change ce qui est mesuré. – drawnonward

1

Ceci est un peu un cop-out, mais voulez-vous vraiment couper un paragraphe?
Est-ce que cela n'améliorerait pas la lisibilité de simplement casser à la première <p> qui dérive de la fenêtre d'affichage?

Ok, donc, pour être clair, il semble que vous testiez la position d'une travée qui est déplacée caractère par caractère à travers un texte? Si c'est correct, et le problème que vous avez est de casser des mots, pourquoi ne pas simplement sauter de l'espace blanc à l'espace blanc (en incluant les traits d'union) plutôt que d'un caractère à l'autre?

Conserver 1 emplacement précédent et le rompre lorsque l'écran actuel est hors de la fenêtre d'affichage.

Je suppose que, avant d'en faire trop, sommes-nous sûrs que nous ne pouvons pas vraiment faire de cette période une dimension sans dimension?

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

Ou le premier '
'. Le formatage du texte n'est pas clair. –

+0

C'est la méthode que nous remplaçons. Je pensais que c'était bien, mais ce n'est pas à moi de décider. Le texte est principalement des paragraphes. – drawnonward

+0

@drawnonward: Il n'y a pas d'autres problèmes sérieux à résoudre en premier? ;-) Si vous connaissez: (1) le décalage total du dernier élément à l'écran; (2) De même pour le premier élément hors écran; (3) Taille de la police, hauteur de la ligne, marge et marge ... Ensuite, vous devriez être en mesure de deviner assez proche. Affinez en commençant par connaître hors écran et affinez un mot à la fois. –