J'ai du JavaScript trivial pour effectuer un changement de style:
sel = document.getElementById('my_id');
sel.className = sel.className.replace(/item-[1-9]-selected/,'item-1-selected');
return false;
Cela fonctionne bien avec les dernières versions de FF, Opera et IE, mais échoue sur les dernières versions de Chrome et Safari.
Elle affecte deux descendants, qui sont des frères et sœurs. Le premier frère est mis à jour, mais pas le second. Un enfant du deuxième élément a également le focus et contient la balise <a> qui contient le code ci-dessus dans un attribut onclick .
Dans la fenêtre "Outils de développement" de Chrome, si je décale (par exemple, décochez et cochez) un attribut d' un élément, le deuxième frère met à jour le style correct.
Existe-t-il une solution de contournement pour «pousser» facilement et par programme WebKit à faire la bonne chose?
css
google-chrome
safari
webkit
danorton
la source
la source
Réponses:
J'ai trouvé des suggestions compliquées et beaucoup de simples qui n'ont pas fonctionné, mais un commentaire à l'un d'eux par Vasil Dinkov a fourni une solution simple pour forcer un redessin / repeindre qui fonctionne très bien:
Je laisserai quelqu'un d'autre commenter si cela fonctionne pour des styles autres que «block».
Merci, Vasil!
la source
'inline-block'
,'table'
ou'run-in'
au lieu de'none'
, mais cela peut avoir des effets secondaires. En outre, un délai d'expiration de 0 déclenche une redistribution comme le fait l'interrogationoffsetHeight
:sel.style.display = 'run-in'; setTimeout(function () { sel.style.display = 'block'; }, 0);
Nous avons récemment rencontré cela et découvert que la promotion de l'élément affecté en une couche composite avec translateZ en CSS a résolu le problème sans avoir besoin de JavaScript supplémentaire.
Comme ces problèmes de peinture apparaissent principalement dans Webkit / Blink, et que ce correctif cible principalement Webkit / Blink, il est préférable dans certains cas. D'autant plus que la réponse acceptée provoque presque certainement une refusion et une repeinture , pas seulement une repeinture.
Webkit et Blink ont travaillé dur sur les performances de rendu, et ces types de problèmes sont les effets secondaires malheureux des optimisations visant à réduire les flux et les peintures inutiles. Le changement de CSS ou une autre spécification qui suivra sera probablement la future solution.
Il existe d'autres façons de réaliser une couche composite, mais c'est la plus courante.
la source
La solution danorton n'a pas fonctionné pour moi. J'ai eu des problèmes vraiment étranges où le webkit ne dessinait pas du tout certains éléments; où le texte dans les entrées n'a pas été mis à jour jusqu'à onblur; et changer className n'entraînerait pas de redessin.
Ma solution, j'ai accidentellement découvert, était d'ajouter un élément de style vide au corps, après le script.
Cela l'a corrigé. C'est bizarre? J'espère que cela est utile pour quelqu'un.
la source
var div = $('<div>').appendTo(element); setTimeout(function(){ div.remove(); }, 0);
$('<style></style>').appendTo($(document.body)).remove();
Étant donné que le déclencheur affichage + décalage ne fonctionnait pas pour moi, j'ai trouvé une solution ici:
http://mir.aculo.us/2009/09/25/force-redraw-dom-technique-for-webkit-based-browsers/
c'est à dire
la source
scale(1)
, je l'ai attribué à lui-mêmeelement.style.webkitTransform = element.style.webkitTransform
. La raison en est que le paramétrer sur le premier déformait légèrement la page pour lesabsolute
éléments bien positionnés!display
solution.Je souffrais du même problème. Le correctif `` basculer l'affichage '' de danorton a fonctionné pour moi lorsqu'il a été ajouté à la fonction pas à pas de mon animation, mais j'étais préoccupé par les performances et j'ai cherché d'autres options.
Dans ma circonstance, l'élément qui n'était pas repeint était dans un élément de position absolue qui n'avait pas, à l'époque, d'index z. L'ajout d'un z-index à cet élément a changé le comportement de Chrome et les repeints se sont déroulés comme prévu -> les animations sont devenues fluides.
Je doute que ce soit une panacée, j'imagine que ça dépend pourquoi Chrome a choisi de ne pas redessiner l'élément, mais je poste cette solution spécifique ici dans l'aide qu'il espère.
À la vôtre, Rob
tl; dr >> Essayez d'ajouter un z-index à l'élément ou à un parent de celui-ci.
la source
Les œuvres suivantes. Il ne doit être défini qu'une seule fois en CSS pur. Et cela fonctionne de manière plus fiable qu'une fonction JS. Les performances ne semblent pas affectées.
la source
zoom
place du rembourrage:@-webkit-keyframes safariBugFix {from { zoom: 100%; } to { zoom: 99.99999%; }}
Pour une raison quelconque, je ne pouvais pas obtenir la réponse de Danorton au travail, je pouvais voir ce qu'il était censé faire, alors je l'ai légèrement modifié:
et cela a fonctionné pour moi.
la source
Je suis venu ici parce que je devais redessiner les barres de défilement dans Chrome après avoir changé son CSS.
Si quelqu'un a le même problème, je l'ai résolu en appelant cette fonction:
Cette méthode n'est pas la meilleure solution, mais elle peut fonctionner avec tout, masquer et afficher l'élément à redessiner peut résoudre tous les problèmes.
Voici le violon où je l'ai utilisé: http://jsfiddle.net/promatik/wZwJz/18/
la source
Je suis tombé sur cela aujourd'hui: Element.redraw () pour prototype.js
En utilisant:
Cependant, j'ai remarqué parfois que vous devez appeler directement redraw () sur l'élément problématique. Parfois, redessiner l'élément parent ne résoudra pas le problème rencontré par l'enfant.
Bon article sur la façon dont les navigateurs rendent les éléments: Rendu: repeindre, reflow / relayout, restyle
la source
appendChild
est une méthode DOM, pas une méthode jQuery.J'ai eu ce problème avec un certain nombre de divs qui ont été insérés dans un autre div avec
position: absolute
, les divs insérés n'avaient aucun attribut de position. Quand j'ai changé cela enposition:relative
cela a bien fonctionné. (était vraiment difficile de cerner le problème)Dans mon cas, les éléments ont été insérés par Angular avec
ng-repeat
.la source
Je ne peux pas croire que cela soit toujours un problème en 2014. Je viens d'avoir ce problème lors de l'actualisation d'une zone de légende à position fixe dans le coin inférieur gauche de la page pendant le défilement, la légende «fantôme» sur l'écran. Après avoir essayé tout ce qui précède sans succès, j'ai remarqué que beaucoup de choses étaient soit lentes / provoquant des problèmes en raison de la création de relais DOM très courts, etc. provoquant une sensation quelque peu artificielle de défilement, etc.
J'ai fini par faire une position fixe, une div pleine taille avec
pointer-events: none
et appliquer la réponse de danorton à cet élément, ce qui semble forcer un redessin sur tout l'écran sans interférer avec le DOM.HTML:
CSS:
JS:
la source
z-index
etpointer-events
sont superflues ici.Non pas que cette question ait besoin d'une autre réponse, mais j'ai trouvé que le simple changement de couleur d'un seul bit a forcé une repeinture dans ma situation particulière.
Il
setTimeout
s'est avéré essentiel de déplacer le deuxième changement de style en dehors de la boucle d'événements actuelle.la source
La seule solution qui fonctionne pour moi est similaire à la réponse de sowasred2012:
J'ai beaucoup de blocs problématiques sur la page, donc je change la
display
propriété de l'élément racine. Et j'utilise à ladisplay: table;
place dedisplay: none;
, carnone
réinitialise le décalage de défilement.la source
J'utilise la
transform: translateZ(0);
méthode mais dans certains cas elle n'est pas suffisante.Je ne suis pas fan de l'ajout et de la suppression d'une classe, j'ai donc essayé de trouver un moyen de résoudre ce problème et je me suis retrouvé avec un nouveau hack qui fonctionne bien:
la source
Puisque tout le monde semble avoir ses propres problèmes et solutions, j'ai pensé que j'ajouterais quelque chose qui fonctionne pour moi. Sur Android 4.1 avec Chrome actuel, en essayant de faire glisser une toile dans un div avec débordement: caché, je ne pouvais pas obtenir de redessin à moins que j'ajoute un élément au div parent (où cela ne ferait aucun mal).
Pas de scintillement d'écran ou de mise à jour réelle, et de nettoyage après moi. Aucune variable globale ou portée par classe, juste des sections locales. Il ne semble rien faire de mal sur Mobile Safari / iPad ou les navigateurs de bureau.
la source
Je travaille sur l'application ionique html5, sur quelques écrans que j'ai
absolute
positionné l'élément, lorsque défiler vers le haut ou vers le bas dans les appareils IOS (iPhone 4,5,6, 6+), j'ai eu un bug de repeindre.J'ai essayé de nombreuses solutions, aucune d'entre elles ne fonctionnait, sauf celle-ci pour résoudre mon problème.
J'ai utilisé la classe CSS
.fixRepaint
sur ces éléments de positions absoluesCela a résolu mon problème, cela peut aider quelqu'un
la source
C'est bien pour JS
Mais dans Jquery, et en particulier lorsque vous ne pouvez utiliser que $ (document) .ready et ne pouvez pas vous lier à un événement .load d'un objet pour une raison particulière, ce qui suit fonctionnera.
Vous devez obtenir le conteneur OUTER (MOST) des objets / divs, puis supprimer tout son contenu dans une variable, puis l'ajouter à nouveau. Il rendra visibles TOUTES les modifications effectuées dans le conteneur externe.
la source
J'ai trouvé cette méthode utile pour travailler avec des transitions
la source
le hack "display / offsetHeight" n'a pas fonctionné dans mon cas, du moins lorsqu'il a été appliqué à l'élément en cours d'animation.
j'avais un menu déroulant qui était ouvert / fermé sur le contenu de la page. les artefacts étaient laissés sur le contenu de la page après la fermeture du menu (uniquement dans les navigateurs webkit). la seule façon dont le hack "display / offsetHeight" a fonctionné est de l'appliquer sur le corps, ce qui semble désagréable.
cependant, j'ai trouvé une autre solution:
c'est encore assez hacky (il utilise une propriété CSS3 pour forcer le rendu matériel), mais au moins cela n'affecte que l'élément en question, et a fonctionné pour moi à la fois sur safari et chrome sur PC et Mac.
la source
Cela semble lié à cela: le style jQuery n'est pas appliqué dans Safari
La solution suggérée dans la première réponse a bien fonctionné pour moi dans ces scénarios, à savoir: appliquer et supprimer une classe factice sur le corps après avoir apporté les modifications de style:
Cela oblige le safari à se redessiner.
la source
les suggestions ci-dessus n'ont pas fonctionné pour moi. mais celui ci-dessous le fait.
Vous voulez changer le texte à l'intérieur de l'ancre dynamiquement. Le mot "Rechercher". Création d'une balise intérieure "police" avec un attribut id. Géré le contenu en utilisant javascript (ci-dessous)
contenu du script:
la source
J'avais un problème avec un SVG qui disparaissait sur Chrome pour Android lorsque l'orientation a été modifiée dans certaines circonstances. Le code ci-dessous ne le reproduit pas, mais est la configuration que nous avions.
Un jour et demi plus tard, après avoir poussé et poussé et pas satisfait des solutions hacky proposées ici, j'ai découvert que le problème était dû au fait qu'il semblait garder l'élément en mémoire tout en en dessinant un nouveau. La solution était de rendre l'ID du linearGradient sur le SVG unique, même s'il n'était utilisé qu'une seule fois par page.
Cela peut être réalisé de différentes manières, mais pour notre application angulaire, nous avons utilisé la fonction lodash uniqueId pour ajouter une variable à la portée:
Directive angulaire (JS):
Mises à jour HTML:
Ligne 5:
<linearGradient ng-attr-id="{{indicatorColourPatternId}}" x1="0" x2="0" y1="0" y2="1">
Ligne 11:
<rect x="0" y="0" rx="5" ry="5" width="100%" height="100%" ng-attr-fill="url(#{{indicatorColourPatternId}})"/>
J'espère que cette réponse permet à quelqu'un d'autre d'économiser plusieurs jours sur son clavier.
la source
Je recommanderais une manière moins hackeuse et plus formelle de forcer une refusion: utilisez forceDOMReflowJS . Dans votre cas, votre code se présenterait comme suit.
la source
J'ai trouvé que l'ajout d'un style de contenu à l'élément le forçait à repeindre, cela devrait être une valeur différente chaque fois que vous souhaitez le redessiner et n'a pas besoin d'être sur un pseudo-élément.
la source
J'ai essayé de répondre plus ironiquement mais cela ne fonctionne pas pour moi. J'ai eu du mal à avoir le même clientWidth avec safari par rapport aux autres navigateurs et ce code a résolu le problème:
C'est vraiment étrange parce que si j'essaye à nouveau d'obtenir le clientWidth après get_safe_value, j'obtiens une mauvaise valeur avec safari, le getter doit être entre
sty.transform = "translateZ(1px)";
etsty.transform = "";
L'autre solution qui fonctionne définitivement est
Le problème est que vous perdez les états de focus et de défilement.
la source
Cela obligera à repeindre tout en évitant le scintillement, le bricolage des éléments existants et tout problème de mise en page ...
la source
Une solution simple avec jquery:
ou
Avait un SVG qui ne s'affichait pas lorsqu'il a été ajouté au html.
Cela peut être ajouté une fois que les éléments svg sont à l'écran.
La meilleure solution consiste à utiliser:
et avec jQuery:
cela s'affichera correctement sur Chrome.
la source