10
votes

Puis-je utiliser JavaScript pour forcer le navigateur à "affleurer" tout changement en attente?

J'ai une bibliothèque qui construit l'interface utilisateur à l'aide de JavaScript, et en raison du contenu dynamique impliqué, je veux parfois mettre du contenu sur le navigateur, examinez comment la mise en page a été modifiée pour supporter cela, puis effectuez une logique différente selon le résultat. . Par exemple: détecter si un texte débordant et le tronque avec une ellipsis.

Habituellement, je le mettez en train de mettre en place cela en mettant les modifications, puis à l'aide de fenêtre.Settimeout (0) pour attendre que la mise en page soit mise à jour et invoque le reste de la logique. Ceci est évidemment sous-optimal, car différents navigateurs peuvent soit implémenter un délai minimal trop lent pour éviter tout scintillement ou plus rapide qui utilise beaucoup de processeur.

Idéalement, je voudrais faire les changements DOM, puis forcer la mise en page à mettre à jour de manière synchrone et exécuter la logique "Fix-up" immédiatement en ligne. Des idées?


2 commentaires

Je ne comprends pas. Pourquoi Settimeout (0) avec un délai d'expiration minimale lent-il un scintillement?


Si le délai d'attente minimal est trop long (disons plus de 100 ms), puis la chaîne de mise à jour que je ferai provoquer une scintillement: la première étape fera quelque chose, puis la deuxième étape corrige cela et la troisième étape fait quelque chose d'autre et ainsi de suite - au lieu de tout faire à la fois.


4 Réponses :


8
votes

Ma compréhension est que la lecture des propriétés CSS forcera une refusion. Vous ne devriez pas avoir besoin de Settimeout code> du tout.

extrait de Rendu: Repeindre, RefeLow / Relayout, Restyle : P>

Mais parfois, le script peut empêcher le navigateur d'optimiser les réflexions et de la faire rincer la file d'attente et d'effectuer tous les changements par lots. Cela se produit lorsque vous demandez des informations de style, telles que P>

 offsetTop, offsetLeft, offsetWidth, offsetHeight
 scrollTop/Left/Width/Height
 clientTop/Left/Width/Height
 getComputedStyle(), or currentStyle in IE


6 commentaires

Ils peuvent déclencher une refusion, mais je doute que le reflet réel soit effectué immédiatement (~ synchrone). Edit: j'ai vu dans votre lien le navigateur configurera une file d'attente des modifications dont vos scripts nécessitent et les exécuteront en lots.


Ce que je fais, c'est essayer de lire les propriétés de la mise en page comme vous le décrivez, mais dans certains navigateurs (notamment, c'est-à-dire), cela ne fonctionnera pas bien car les propriétés n'ont pas encore été mise à jour pour prendre en compte mes modifications.


True, ClientHeight , CurrentStyle n'a pas déclenché une réflexion immédiate dans IE8


@Petermajeed: merci; Trouvé une version en direct.


Site en direct pour Voici une liste des appels / propriétés de l'API qui déclencheront un refus gist.github.com/paulirish/5d52fb081b3570c81e3a


Merci, j'ai édité la réponse avec le nouveau lien et un wayback pour l'ancien.



0
votes

Je n'ai aucune idée de ce que cela fonctionnera réellement pour votre mise en œuvre, mais:

var mySelect = document.getElementById("mySelect");// suppose this lives in myDiv.
var myDiv = document.getElementById("myDiv");
myDiv.innerHTML = "".concat(myDiv.innerHTML);


1 commentaires

Oui, c'est un buste: je ne suis pas sur le point de reporter la page entière comme cela briserait beaucoup de choses que je n'ai aucun contrôle.



3
votes

Nous avons rencontré un problème fou avec IE8 (Firefox, chrome va bien). Nous utilisons Toggleclass ("ENOMYADDRESSHIDE") sur l'élément enfant.

jQuery(document).ready(function ($) {
    var RefreshIE8Layout = function () {
        $('.enoAddressBook:first').css('height', 'auto');
        var height = $('.enoAddressBook:first').height();
        $('.enoAddressBook:first').css('height', height);
    };

    $(".enoRowAddressInfo .enoRowAddressInfoArea ul li img.enoMyAddresses").click(function () {
        $(this).parent().find(".enoAllInfoInAddressBox,img.enoMyAddresses").toggleClass('enoMyAddressesHide');

        RefreshIE8Layout(); // fix IE8 bug, not refresh the DOM dimension after using jQuery to manipulate DOM
    });
});


3 commentaires

Cela semble intéressant. Pensez-vous réinitialiser la hauteur à auto après la définition de quelque chose de spécifique conservera le comportement de refusion? Parce que j'aimerais vraiment avoir la hauteur toujours automatique.


@Guss dans mon test (avec le navigateur natif IE8 sur Win7), ce que nous devons faire est Changer la propriété Hauteur CSS Propriété. Vous pouvez passer à autre chose ( 100%, 50px , ...), puis remplissez-le sur auto .


Impressionnant. Je ne suis pas sûr quand je vais essayer d'essayer (été occupé avec d'autres projets dernièrement) mais cela ressemble à ce que je cherchais, alors je vais aller de l'avant et accepter votre réponse. Merci!



0
votes

Oui, vous pouvez !!

La plupart des navigateurs optimisent le processus de refusion en faisant file d'attente les modifications et les exécutant en lots. Rincer les changements d'arborescence nécessite de récupérer certaines informations de mise en page (calculs de compensation, getcomputedstyle () et des valeurs de défilement). xxx

Le code ci-dessus obligera le navigateur à exécuter des changements dans la file d'attente de rendu afin de renvoyer les valeurs correctes.

simple !!


1 commentaires

Ne le fait pas du tout.