Ich habe ein triviales JavaScript, um eine Stiländerung zu bewirken:
sel = document.getElementById('my_id');
sel.className = sel.className.replace(/item-[1-9]-selected/,'item-1-selected');
return false;
Dies funktioniert gut mit den neuesten Versionen von FF, Opera und IE, schlägt jedoch mit den neuesten Versionen von Chrome und Safari fehl.
Es betrifft zwei Nachkommen, die zufällig Geschwister sind. Das erste Geschwister-Update, das zweite nicht. Ein untergeordnetes Element des zweiten Elements hat ebenfalls den Fokus und enthält das <a> -Tag, das den obigen Code in einem onclick- Attribut enthält.
Im Chrome „Developer Tools“ Fenster wenn ich Schubs (zB uncheck & check) jedes Attribut von jedem Element, die zweite Geschwister - Updates auf den richtigen Stil.
Gibt es eine Problemumgehung, um WebKit einfach und programmgesteuert dazu zu bringen, das Richtige zu tun?
css
google-chrome
safari
webkit
Danorton
quelle
quelle
Antworten:
Ich fand einige komplizierte Vorschläge und viele einfache, die nicht funktionierten, aber ein Kommentar von Vasil Dinkov zu einem von ihnen bot eine einfache Lösung, um ein Neuzeichnen / Neulackieren zu erzwingen, das einwandfrei funktioniert:
Ich lasse jemanden kommentieren, wenn es für andere Stile als "Block" funktioniert.
Danke, Vasil!
quelle
'inline-block'
,'table'
oder'run-in'
statt'none'
, aber dies kann Nebenwirkungen haben. Auch ein Timeout von 0 löst einen Reflow aus, genau wie das AbfragenoffsetHeight
:sel.style.display = 'run-in'; setTimeout(function () { sel.style.display = 'block'; }, 0);
Wir sind kürzlich darauf gestoßen und haben festgestellt, dass das Heraufstufen des betroffenen Elements auf eine zusammengesetzte Ebene mit translateZ in CSS das Problem behoben hat, ohne dass zusätzliches JavaScript erforderlich war.
Da diese Malprobleme hauptsächlich in Webkit / Blink auftreten und dieses Update hauptsächlich auf Webkit / Blink abzielt, ist es in einigen Fällen vorzuziehen. Zumal die akzeptierte Antwort mit ziemlicher Sicherheit einen Reflow und ein Repaint verursacht , nicht nur ein Repaint.
Webkit und Blink haben hart an der Renderleistung gearbeitet, und diese Art von Störungen sind der unglückliche Nebeneffekt von Optimierungen, die darauf abzielen, unnötige Flüsse und Farben zu reduzieren. CSS wird sich ändern oder eine andere nachfolgende Spezifikation wird höchstwahrscheinlich die zukünftige Lösung sein.
Es gibt andere Möglichkeiten, eine Verbundschicht zu erzielen, dies ist jedoch die häufigste.
quelle
Die Danorton-Lösung hat bei mir nicht funktioniert. Ich hatte einige wirklich seltsame Probleme, bei denen das Webkit einige Elemente überhaupt nicht zeichnete. wo der Text in den Eingaben erst bei Unschärfe aktualisiert wurde; Das Ändern des Klassennamens würde nicht zu einem erneuten Zeichnen führen.
Ich habe versehentlich festgestellt, dass meine Lösung darin bestand, dem Body nach dem Skript ein leeres Stilelement hinzuzufügen.
Das hat es behoben. Wie komisch ist das? Hoffe das ist hilfreich für jemanden.
quelle
var div = $('<div>').appendTo(element); setTimeout(function(){ div.remove(); }, 0);
$('<style></style>').appendTo($(document.body)).remove();
Da der Display + Offset-Trigger bei mir nicht funktioniert hat, habe ich hier eine Lösung gefunden:
http://mir.aculo.us/2009/09/25/force-redraw-dom-technique-for-webkit-based-browsers/
dh
quelle
scale(1)
ich es sich selbst zugewiesen alselement.style.webkitTransform = element.style.webkitTransform
. Der Grund dafür war, dass das Einstellen auf das erstere die Seite fürabsolute
ly positionierte Elemente leicht verzerrte !display
Lösung hatte.Ich hatte das gleiche Problem. Danortons 'Toggling Display'-Fix funktionierte für mich, als er zur Schrittfunktion meiner Animation hinzugefügt wurde, aber ich war besorgt über die Leistung und suchte nach anderen Optionen.
Unter meinen Umständen befand sich das Element, das nicht neu gestrichen wurde, innerhalb eines absoluten Positionselements, das zu diesem Zeitpunkt keinen Z-Index hatte. Durch Hinzufügen eines Z-Index zu diesem Element wurde das Verhalten von Chrome geändert, und das Neulackieren erfolgte wie erwartet -> Animationen wurden reibungslos.
Ich bezweifle, dass dies ein Allheilmittel ist. Ich kann mir vorstellen, dass es davon abhängt, warum Chrome das Element nicht neu gezeichnet hat, aber ich poste diese spezielle Lösung hier in der Hilfe, die jemand hofft.
Prost, Rob
tl; dr >> Versuchen Sie, dem Element oder einem übergeordneten Element einen Z-Index hinzuzufügen.
quelle
Folgendes funktioniert. Es muss nur einmal in reinem CSS eingestellt werden. Und es funktioniert zuverlässiger als eine JS-Funktion. Die Leistung scheint davon nicht betroffen zu sein.
quelle
zoom
statt Polsterung verwendet:@-webkit-keyframes safariBugFix {from { zoom: 100%; } to { zoom: 99.99999%; }}
Aus irgendeinem Grund konnte ich Danortons Antwort nicht auf die Arbeit bringen, ich konnte sehen, was es tun sollte, also habe ich es ein wenig angepasst:
und es hat bei mir funktioniert.
quelle
Ich bin hierher gekommen, weil ich nach dem Ändern des CSS Bildlaufleisten in Chrome neu zeichnen musste.
Wenn jemand das gleiche Problem hat, habe ich es durch Aufrufen dieser Funktion gelöst:
Diese Methode ist nicht die beste Lösung, funktioniert jedoch möglicherweise mit allem. Das Ausblenden und Anzeigen des Elements, das neu gezeichnet werden muss, kann jedes Problem lösen.
Hier ist die Geige, wo ich sie benutzt habe: http://jsfiddle.net/promatik/wZwJz/18/
quelle
Ich bin heute darauf gestoßen : Element.redraw () für prototype.js
Verwenden von:
Manchmal ist mir jedoch aufgefallen, dass Sie redraw () für das problematische Element direkt aufrufen müssen. Manchmal löst das Neuzeichnen des übergeordneten Elements das Problem des Kindes nicht.
Guter Artikel über die Art und Weise, wie Browser Elemente rendern: Rendern: Repaint, Reflow / Relayout, Restyle
quelle
appendChild
ist eine DOM-Methode, keine jQuery-Methode.Ich hatte dieses Problem mit einer Anzahl von Divs, die in ein anderes Div
position: absolute
eingefügt wurden. Die eingefügten Divs hatten kein Positionsattribut. Als ich das geändert habe, hatposition:relative
es gut funktioniert. (war wirklich schwer, das Problem zu lokalisieren)In meinem Fall wurden die Elemente von Angular mit eingefügt
ng-repeat
.quelle
Ich kann nicht glauben, dass dies 2014 immer noch ein Problem ist. Ich hatte gerade dieses Problem, als ich beim Scrollen ein Beschriftungsfeld mit fester Position unten links auf der Seite aktualisierte. Die Beschriftung würde sich auf dem Bildschirm nach oben bewegen. Nachdem ich alles oben ohne Erfolg ausprobiert hatte, bemerkte ich, dass viele Dinge entweder langsam waren oder Probleme verursachten, weil sehr kurze DOM-Relayouts usw. erstellt wurden, was ein etwas unnatürliches Gefühl beim Scrollen usw. verursachte.
pointer-events: none
Am Ende machte ich eine feste Position, div in voller Größe mit und wendete Danortons Antwort auf dieses Element an, was eine Neuzeichnung auf dem gesamten Bildschirm zu erzwingen scheint, ohne das DOM zu stören.HTML:
CSS:
JS:
quelle
z-index
undpointer-events
Regeln sind hier überflüssig.Nicht, dass diese Frage eine andere Antwort braucht, aber ich fand, dass das einfache Ändern der Farbe durch ein einzelnes Bit ein Neulackieren in meiner speziellen Situation erzwang.
Es hat sich
setTimeout
als kritisch erwiesen, die zweite Stiländerung außerhalb der aktuellen Ereignisschleife zu verschieben.quelle
Die einzige Lösung, die für mich funktioniert, ähnelt der Antwort von sowasred2012:
Ich habe viele Problemblöcke auf der Seite, daher ändere ich die
display
Eigenschaft des Stammelements. Und ich benutzedisplay: table;
stattdessendisplay: none;
, weilnone
der Bildlaufversatz zurückgesetzt wird.quelle
Da jeder seine eigenen Probleme und Lösungen zu haben scheint, dachte ich mir, ich würde etwas hinzufügen, das für mich funktioniert. Unter Android 4.1 mit aktuellem Chrome wurde versucht, eine Leinwand innerhalb eines Divs mit Überlauf zu ziehen: Ausgeblendet konnte ich kein Neuzeichnen erhalten, es sei denn, ich habe dem übergeordneten Div ein Element hinzugefügt (wo es keinen Schaden anrichten würde).
Kein Bildschirmflimmern oder echtes Update und Aufräumen nach mir. Keine globalen oder klassenbezogenen Variablen, nur Einheimische. Scheint auf Mobile Safari / iPad oder Desktop-Browsern nichts zu schaden.
quelle
Ich arbeite an einer ionischen HTML5-App. Auf einigen Bildschirmen habe ich
absolute
ein Element positioniert. Beim Scrollen nach oben oder unten auf iOS-Geräten (iPhone 4,5,6, 6+) hatte ich einen Repaint-Fehler.Versuchte viele Lösungen, von denen keine funktionierte, außer diese löste mein Problem.
Ich habe CSS-Klasse
.fixRepaint
für diese absoluten Positionselemente verwendetDies hat mein Problem behoben, es kann jemandem helfen
quelle
Ich benutze die
transform: translateZ(0);
Methode, aber in einigen Fällen ist es nicht ausreichend.Ich bin kein Fan des Hinzufügens und Entfernens einer Klasse, also habe ich versucht, einen Weg zu finden, dies zu lösen, und am Ende einen neuen Hack gefunden, der gut funktioniert:
quelle
Dies ist in Ordnung für JS
In Jquery und insbesondere dann, wenn Sie nur $ (document) .ready verwenden und aus einem bestimmten Grund nicht an das .load-Ereignis eines Objekts binden können, funktioniert Folgendes.
Sie müssen den OUTER (MOST) -Container der Objekte / Divs abrufen, den gesamten Inhalt in eine Variable entfernen und ihn dann erneut hinzufügen. Dadurch werden ALLE im Außencontainer vorgenommenen Änderungen sichtbar.
quelle
Ich habe festgestellt, dass diese Methode bei der Arbeit mit Übergängen hilfreich ist
quelle
Der Hack "display / offsetHeight" hat in meinem Fall nicht funktioniert, zumindest wenn er auf das zu animierende Element angewendet wurde.
Ich hatte ein Dropdown-Menü, das über dem Seiteninhalt geöffnet / geschlossen wurde. Die Artefakte wurden nach dem Schließen des Menüs auf dem Seiteninhalt belassen (nur in Webkit-Browsern). Der "display / offsetHeight" -Hack hat nur funktioniert, wenn ich ihn auf den Körper angewendet habe, was böse erscheint.
Ich habe jedoch eine andere Lösung gefunden:
Dies ist immer noch ziemlich hackig (es verwendet eine CSS3-Eigenschaft, um das Hardware-Rendering zu erzwingen), aber zumindest betrifft es nur das betreffende Element und hat für mich sowohl auf Safari als auch auf Chrome auf PC und Mac funktioniert.
quelle
Dies scheint damit verbunden zu sein: tun jQuery-Stil wird in Safari nicht angewendet
Die in der ersten Antwort vorgeschlagene Lösung hat in diesen Szenarien für mich gut funktioniert: Anwenden und Entfernen einer Dummy-Klasse auf den Körper, nachdem die Stiländerungen vorgenommen wurden:
Dies zwingt die Safari zum Neuzeichnen.
quelle
Die obigen Vorschläge haben bei mir nicht funktioniert. aber das unten tut.
Möchten Sie den Text im Anker dynamisch ändern? Das Wort "Suche". Erstellt ein inneres Tag "font" mit einem ID-Attribut. Verwaltete den Inhalt mit Javascript (unten)
Skriptinhalt:
quelle
Ich hatte ein Problem mit einem SVG, das unter Chrome für Android verschwand, als die Ausrichtung unter bestimmten Umständen geändert wurde. Der folgende Code gibt es nicht wieder, aber es ist das Setup, das wir hatten.
Tag und einen halben Tag nach dem Stochern und Stupsen und nicht glücklich mit dem Hacky ich angebotenen Lösungen , stellte ich fest, dass das Problem durch die Tatsache verursacht wurde, dass das Element beim Zeichnen eines neuen in Erinnerung zu bleiben schien. Die Lösung bestand darin, die ID des linearGradient in der SVG eindeutig zu machen, obwohl sie immer nur einmal pro Seite verwendet wurde.
Dies kann auf viele verschiedene Arten erreicht werden, aber für unsere Winkel-App haben wir die Funktion lodash uniqueId verwendet, um dem Bereich eine Variable hinzuzufügen:
Winkelrichtlinie (JS):
HTML-Updates:
Zeile 5:
<linearGradient ng-attr-id="{{indicatorColourPatternId}}" x1="0" x2="0" y1="0" y2="1">
Zeile 11:
<rect x="0" y="0" rx="5" ry="5" width="100%" height="100%" ng-attr-fill="url(#{{indicatorColourPatternId}})"/>
Ich hoffe, diese Antwort erspart jemand anderem Tage, um seine Tastatur zu zerschlagen.
quelle
Ich würde eine weniger hackige und formellere Methode empfehlen, um einen Reflow zu erzwingen: Verwenden Sie forceDOMReflowJS . In Ihrem Fall würde Ihr Code wie folgt aussehen.
quelle
Ich habe festgestellt, dass das Hinzufügen eines Inhaltsstils zum Element das Neulackieren erzwang. Dies sollte jedes Mal ein anderer Wert sein, wenn Sie möchten, dass es neu gezeichnet wird, und muss sich nicht auf einem Pseudoelement befinden.
quelle
Ich habe versucht, mehr zu antworten, aber es funktioniert nicht für mich. Ich hatte Probleme, die gleiche Clientbreite mit Safari im Vergleich zu anderen Browsern zu haben, und dieser Code löste das Problem:
Es ist wirklich seltsam, denn wenn ich erneut versuche, die clientWidth nach get_safe_value zu erhalten, erhalte ich mit safari einen schlechten Wert, der Getter muss dazwischen liegen
sty.transform = "translateZ(1px)";
und liegensty.transform = "";
Die andere Lösung, die definitiv funktioniert, ist
Das Problem ist, dass Sie den Fokus verlieren und den Status scrollen.
quelle
Dadurch wird das Neulackieren erzwungen, während Flackern, Basteln vorhandener Elemente und Layoutprobleme vermieden werden ...
quelle
Eine einfache Lösung mit jquery:
oder
Hatte eine SVG, die nicht angezeigt wurde, als sie dem HTML hinzugefügt wurde.
Dies kann hinzugefügt werden, nachdem die SVG-Elemente auf dem Bildschirm angezeigt werden.
Bessere Lösung ist zu verwenden:
und mit jQuery:
Dies wird in Chrome korrekt gerendert.
quelle