Comment puis-je forcer WebKit à redessiner / repeindre pour propager les changements de style?

247

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?

danorton
la source
Je pense que je rencontre ce problème sur Android 4.2.2 (Samsung I9500) lorsque j'encapsule mon application de toile dans une WebView. Ridicule!
Josh
3
what-forces-layout.md un très bon endroit pour lire
vsync

Réponses:

312

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:

sel.style.display='none';
sel.offsetHeight; // no need to store this anywhere, the reference is enough
sel.style.display='';

Je laisserai quelqu'un d'autre commenter si cela fonctionne pour des styles autres que «block».

Merci, Vasil!

danorton
la source
32
Pour éviter le scintillement, vous pouvez essayer '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'interrogation offsetHeight:sel.style.display = 'run-in'; setTimeout(function () { sel.style.display = 'block'; }, 0);
user123444555621
15
Cette réponse est toujours utile 2 ans plus tard. Je viens de l'utiliser pour résoudre un problème uniquement dans Chrome où les ombres des boîtes CSS restaient à l'écran après avoir redimensionné le navigateur de certaines manières. Merci!
rkulla
5
@danorton Vous avez répondu en 2010. Nous sommes en 2013 et le bug est toujours là. Merci. Soit dit en passant, quelqu'un sait-il s'il y a un problème enregistré sur webkit tracker?
RaphaelDDL
13
PS: pour moi, la solution ci-dessus ne fonctionnait plus. Au lieu de cela, j'ai utilisé ceci (jQuery): sel.hide (). Show (0); Source: stackoverflow.com/questions/8840580/…
ProblemsOfSumit
7
Tout ce que vous devez faire est de lire une propriété de taille, vous n'avez pas besoin de la changer d'avant en arrière.
Andrew Bullock
93

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.

.willnotrender { 
   transform: translateZ(0); 
}

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.

plus
la source
1
A fonctionné pour moi lors de l'utilisation du carrousel angulaire !
gustavohenke
1
Correction d'un problème où le rayon de la frontière était perdu dans un élément à l'intérieur d'un panneau coulissant
Timo
1
Fonctionne également pour les projets Cordova!
Quispie
1
A travaillé pour moi pour une pince de ligne Web qui ne s'est pas rafraîchie
Adam Marshall
1
A travaillé pour moi sur iPad (6.0) avec -webkit-transform: traduire (-50%, -50%).
Lain
51

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.

<body>
...
<script>doSomethingThatWebkitWillMessUp();</script>
<style></style>
...

Cela l'a corrigé. C'est bizarre? J'espère que cela est utile pour quelqu'un.

Gerben
la source
3
Je voterais 1 000 000 fois si je le pouvais. C'est la seule façon dont je pouvais obtenir du chrome pour repeindre un div stupide que je traînais. Soit dit en passant, vous n'avez pas besoin d'ajouter un élément de style (du moins je ne l'ai pas fait), aucun élément ne fonctionnera. J'ai fait un div et je lui ai donné un identifiant pour pouvoir le supprimer puis ajouter l'élément à chaque étape, afin de ne pas remplir le DOM de balises inutiles.
hobberwickey
6
vient d'utiliser ceci mélangé avec le commentaire de Pumbaa80 sur une autre réponse. Le correctif avec var div = $('<div>').appendTo(element); setTimeout(function(){ div.remove(); }, 0);
lequel
33
Cette ligne unique fonctionne très bien pour moi! $('<style></style>').appendTo($(document.body)).remove();
pdelanauze
1
La réponse @pdelanauze fonctionne parfaitement. J'ai un problème de rafraîchissement chanter css3 traduire et transformer en ios.
Marcel Falliere
11
Sachez simplement que cela oblige à repeindre la page entière, alors que la plupart du temps vous ne voulez repeindre qu'une certaine section de la page ...
Ryan Wheale
33

É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

element.style.webkitTransform = 'scale(1)';
EricG
la source
3
Je l'ai utilisé dans un hack que j'essayais, mais au lieu de cela scale(1), je l'ai attribué à lui-même element.style.webkitTransform = element.style.webkitTransform. La raison en est que le paramétrer sur le premier déformait légèrement la page pour les absoluteéléments bien positionnés!
bPratik
Cela a fonctionné pour moi et n'a pas eu de problèmes de scintillement ou de réinitialisation de la position de défilement de la displaysolution.
davidtbernal
J'avais une application Cordova utilisant beaucoup de SVG dynamique. A bien fonctionné partout sauf iOS7, où ne serait tout simplement pas afficher les éléments SVG au démarrage. Ajout d'un simple $ ('body') [0] .style.webkitTransform = 'scale (1)'; au code d'initialisation et le problème a disparu!
Herc
Cela ne fonctionne pas pour le moment, sur les derniers Safari et iOS.
setholopolus
@setholopolus quelle (s) vers (s) serait-ce?
EricG
23

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.

Rob Murphy
la source
8
Brillant. C'est génial et a résolu le problème pour moi. A +++ indexerait à nouveau z.
trisweb
N'a pas fonctionné dans ma situation concernant les barres de défilement et les transformations.
Ricky Boyce
16

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.

@-webkit-keyframes androidBugfix {from { padding: 0; } to { padding: 0; }}
body { -webkit-animation: androidBugfix infinite 1s; }
sue
la source
On dirait que ça marche aussi pour moi. Utilisé pour résoudre un problème de rendu avec Mobile Safari
Chris
Cela corrige mon problème, force Safari à relayer. Cependant, j'ai utilisé à la zoomplace du rembourrage:@-webkit-keyframes safariBugFix {from { zoom: 100%; } to { zoom: 99.99999%; }}
Ahmed Musallam
13

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é:

$('#foo').css('display', 'none').height();
$('#foo').css('display', 'block');

et cela a fonctionné pour moi.

sowasred2012
la source
7
J'ai tout essayé au-dessus, mais seul celui-ci a fonctionné pour moi. Webkit WTF! Ce n'est pas de l'informatique! C'est de la magie noire!
Charlie Martin
7

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:

//Hack to force scroll redraw
function scrollReDraw() {
    $('body').css('overflow', 'hidden').height();
    $('body').css('overflow', 'auto');
}

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/

António Almeida
la source
1
Génial! J'essayais aussi d'animer les barres de défilement et c'est ce dont j'avais besoin! BTW Better Use Overflow: Overlay pour les barres de défilement animées
Ekalchev
6

Je suis tombé sur cela aujourd'hui: Element.redraw () pour prototype.js

En utilisant:

Element.addMethods({
  redraw: function(element){
    element = $(element);
    var n = document.createTextNode(' ');
    element.appendChild(n);
    (function(){n.parentNode.removeChild(n)}).defer();
    return element;
  }
});

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

Adam Eberlin
la source
1
appendChildest une méthode DOM, pas une méthode jQuery.
ChrisW
4

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.

JustGoscha
la source
1
Merci! Cela a également fonctionné pour mon problème et est beaucoup plus léger que la plupart des solutions javascript ci-dessus.
Dsyko
4

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: noneet 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:

<div id="redraw-fix"></div>

CSS:

div#redraw-fix {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 25;
    pointer-events: none;
    display: block;
}

JS:

sel = document.getElementById('redraw-fix');
sel.style.display='none';
sel.offsetHeight; // no need to store this anywhere, the reference is enough
sel.style.display='block';
gaufre
la source
Je ne peux pas vous remercier assez pour votre solution de contournement qui est la seule qui a fonctionné pour moi. Oui, c'est 2017 et le problème persiste. Mon problème était lié à une page de langue RTL qui resterait vierge si elle était actualisée manuellement sur les appareils mobiles Android. Les règles z-indexet pointer-eventssont superflues ici.
Amin Mozafari du
J'ai déjà utilisé le correctif de danorton, mais je me débattais vraiment avec le flash du contenu de la configuration de l'affichage à aucun. Votre solution a fonctionné très bien pour moi sans flash de contenu!
Justin Noel
3

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.

//Assuming black is the starting color, we tweak it by a single bit
elem.style.color = '#000001';

//Change back to black
setTimeout(function() {
    elem.style.color = '#000000';
}, 0);

Il setTimeouts'est avéré essentiel de déplacer le deuxième changement de style en dehors de la boucle d'événements actuelle.

TMan
la source
1
Définir un délai d'expiration de 0 s'est révélé utile pour moi dans une situation différente mais similaire. Le redessin ne se produisait pas avant que la validation discrète de jquery ne gèle l'écran pendant qu'il analysait un grand formulaire. Je pensais que je commenterais au cas où quelqu'un serait dans la même situation. Les autres solutions n'ont pas fonctionné dans ce scénario.
k29
2

La seule solution qui fonctionne pour moi est similaire à la réponse de sowasred2012:

$('body').css('display', 'table').height();
$('body').css('display', 'block');

J'ai beaucoup de blocs problématiques sur la page, donc je change la displaypropriété de l'élément racine. Et j'utilise à la display: table;place de display: none;, car noneréinitialise le décalage de défilement.

Ilya Sviridenko
la source
2

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:

@keyframes redraw{
    0% {opacity: 1;}
    100% {opacity: .99;}
}

// ios redraw fix
animation: redraw 1s linear infinite;
Guillaume Gautier
la source
1

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).

var parelt = document.getElementById("parentid");
var remElt = document.getElementById("removeMe");
var addElt = document.createElement("div");
addElt.innerHTML = " "; // Won't work if empty
addElt.id="removeMe";
if (remElt) {
    parelt.replaceChild(addElt, remElt);
} else {
    parelt.appendChild(addElt);
}

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.

Eric Ruck
la source
1

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 .fixRepaintsur ces éléments de positions absolues

.fixRepaint{
    transform: translateZ(0);
}

Cela a résolu mon problème, cela peut aider quelqu'un

Anjum ....
la source
1
Opss comment je n'ai pas vu ça. @morewry Merci d'avoir signalé
Anjum ....
0

C'est bien pour JS

sel.style.display='none';
sel.offsetHeight; // no need to store this anywhere, the reference is enough
sel.style.display='block';

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.

$(document).ready(function(){
    applyStyling(object);
    var node = $("div#body div.centerContainer form div.centerHorizontal").parent().parent();
    var content = node.html();
    node.html("");
    node.html(content);
}
WiR3D
la source
0

J'ai trouvé cette méthode utile pour travailler avec des transitions

$element[0].style.display = 'table'; 
$element[0].offsetWidth; // force reflow
$element.one($.support.transition.end, function () { 
    $element[0].style.display = 'block'; 
});
jschr
la source
0

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:

  1. avant que l'élément ne commence à s'animer, ajoutez une classe qui définit "-webkit-backface -visibility: hidden;" sur l'élément (vous pouvez également utiliser le style en ligne, je suppose)
  2. une fois l'animation terminée, supprimez la classe (ou le style)

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.

tedtedson
la source
0

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:

$('body').addClass('dummyclass').removeClass('dummyclass');

Cela oblige le safari à se redessiner.

Steve
la source
Pour que cela fonctionne dans Chrome, j'ai dû ajouter: $ ('body'). AddClass ('dummyclass'). Delay (0) .removeClass ('dummyclass');
mbokil
0

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)

Chercher

contenu du script:

    var searchText = "Search";
    var editSearchText = "Edit Search";
    var currentSearchText = searchText;

    function doSearch() {
        if (currentSearchText == searchText) {
            $('#pSearch').panel('close');
            currentSearchText = editSearchText;
        } else if (currentSearchText == editSearchText) {
            $('#pSearch').panel('open');
            currentSearchText = searchText;
        }
        $('#searchtxt').text(currentSearchText);
    }
ganesh
la source
0

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.

body {
  font-family: tahoma, sans-serif;
  font-size: 12px;
  margin: 10px;
}
article {
  display: flex;
}
aside {
  flex: 0 1 10px;
  margin-right: 10px;
  min-width: 10px;
  position: relative;
}
svg {
  bottom: 0;
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
}
.backgroundStop1 {
  stop-color: #5bb79e;
}
.backgroundStop2 {
  stop-color: #ddcb3f;
}
.backgroundStop3 {
  stop-color: #cf6b19;
}
<article>
  <aside>
    <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="100%" width="100%">
      <defs>
        <linearGradient id="IndicatorColourPattern" x1="0" x2="0" y1="0" y2="1">
          <stop class="backgroundStop1" offset="0%"></stop>
          <stop class="backgroundStop2" offset="50%"></stop>
          <stop class="backgroundStop3" offset="100%"></stop>
        </linearGradient>
      </defs>
      <rect x="0" y="0" rx="5" ry="5" width="100%" height="100%" fill="url(#IndicatorColourPattern)"></rect>
    </svg>
  </aside>
  <section>
    <p>Donec et eros nibh. Nullam porta, elit ut sagittis pulvinar, lacus augue lobortis mauris, sed sollicitudin elit orci non massa. Proin condimentum in nibh sed vestibulum. Donec accumsan fringilla est, porttitor vestibulum dolor ornare id. Sed elementum
      urna sollicitudin commodo ultricies. Curabitur tristique orci et ligula interdum, eu condimentum metus eleifend. Nam libero augue, pharetra at maximus in, pellentesque imperdiet orci.</p>
    <p>Fusce commodo ullamcorper ullamcorper. Etiam eget pellentesque quam, id sodales erat. Vestibulum risus magna, efficitur sed nisl et, rutrum consectetur odio. Sed at lorem non ligula consequat tempus vel nec risus.</p>
  </section>
</article>

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):

scope.indicatorColourPatternId = _.uniqueId('IndicatorColourPattern');

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.

Jamie Barker
la source
0

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.

sel = document.getElementById('my_id');
forceReflowJS( sel );
return false;
Jack Giffin
la source
0

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.

.selector {
    content: '1'
}
Steve
la source
0

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:

var get_safe_value = function(elm,callback){
    var sty = elm.style
    sty.transform = "translateZ(1px)";
    var ret = callback(elm)//you can get here the value you want
    sty.transform = "";
    return ret
}
// for safari to have the good clientWidth
var $fBody = document.body //the element you need to fix
var clientW = get_safe_value($fBody,function(elm){return $fBody.clientWidth})

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

var $fBody = document.body //the element you need to fix
$fBody.style.display = 'none';
var temp = $.body.offsetHeight;
$fBody.style.display = ""
temp = $.body.offsetHeight;

var clientW = $fBody.clientWidth

Le problème est que vous perdez les états de focus et de défilement.

bormat
la source
0

Cela obligera à repeindre tout en évitant le scintillement, le bricolage des éléments existants et tout problème de mise en page ...

function forceRepaint() {
    requestAnimationFrame(()=>{
      const e=document.createElement('DIV');
      e.style='position:fixed;top:0;left:0;bottom:0;right:0;background:#80808001;\
               pointer-events:none;z-index:9999999';
      document.body.appendChild(e);
      requestAnimationFrame(()=>e.remove());  
    });
}
user2026189
la source
-1

Une solution simple avec jquery:

$el.html($el.html());

ou

element.innerHTML = element.innerHTML;

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:

document.createElementNS('http://www.w3.org/2000/svg', 'svg');

et avec jQuery:

$(svgDiv).append($(document.createElementNS('http://www.w3.org/2000/svg', 'g'));

cela s'affichera correctement sur Chrome.

Yaron Shamir
la source
Le problème avec cette approche est que vous perdez tous les gestionnaires d'événements que vous avez enregistrés sur l'objet ou ses descendants.
Haqa