Mam trywialny JavaScript do zmiany stylu:
sel = document.getElementById('my_id');
sel.className = sel.className.replace(/item-[1-9]-selected/,'item-1-selected');
return false;
Działa to dobrze z najnowszymi wersjami FF, Opera i IE, ale zawodzi w najnowszych wersjach Chrome i Safari.
Wpływa na dwóch potomków, którzy są rodzeństwem. Pierwsze rodzeństwo jest aktualizowane, ale drugie nie. Element podrzędny drugiego elementu również ma fokus i zawiera znacznik <a>, który zawiera powyższy kod w atrybucie onclick .
W oknie „Narzędzi programisty” Chrome, jeśli podsuwam (np. Odznaczam i zaznaczam) dowolny atrybut dowolnego elementu, drugie rodzeństwo aktualizuje odpowiedni styl.
Czy istnieje sposób obejścia problemu, aby łatwo i programowo „popchnąć” WebKit do robienia właściwych rzeczy?
css
google-chrome
safari
webkit
Danorton
źródło
źródło
Odpowiedzi:
Znalazłem kilka skomplikowanych sugestii i wiele prostych, które nie zadziałały, ale komentarz do jednego z nich autorstwa Vasila Dinkova podał proste rozwiązanie wymuszające przerysowanie / odmalowanie, które działa dobrze:
Pozwolę komuś innemu komentować, jeśli działa dla stylów innych niż „blok”.
Dzięki, Vasil!
źródło
'inline-block'
,'table'
albo'run-in'
zamiast'none'
, ale może to mieć skutki uboczne. Poza tymoffsetHeight
sel.style.display = 'run-in'; setTimeout(function () { sel.style.display = 'block'; }, 0);
Niedawno się z tym spotkaliśmy i odkryliśmy, że promowanie dotkniętego elementu do warstwy kompozytowej za pomocą translateZ w CSS rozwiązało problem bez potrzeby dodatkowego JavaScript.
Ponieważ te problemy z malowaniem pojawiają się głównie w Webkit / Blink, a ta poprawka dotyczy głównie Webkit / Blink, w niektórych przypadkach lepiej jest. Zwłaszcza, że przyjęta odpowiedź prawie na pewno powoduje ponowne zalanie i odmalowanie , a nie tylko odmalowanie.
Webkit i Blink ciężko pracują nad wydajnością renderowania, a tego rodzaju usterki są niefortunnym efektem ubocznym optymalizacji, które mają na celu ograniczenie niepotrzebnych przepływów i farb. Najprawdopodobniej przyszłym rozwiązaniem będzie zmiana CSS lub inna następna specyfikacja.
Istnieją inne sposoby uzyskania warstwy kompozytowej, ale jest to najczęściej.
źródło
Rozwiązanie danorton nie działało dla mnie. Miałem naprawdę dziwne problemy, w których webkit wcale nie rysował niektórych elementów; gdzie tekst w danych wejściowych nie był aktualizowany aż do onblur; i zmiana className nie spowoduje przerysowania.
Moim rozwiązaniem, przypadkowo odkrytym, było dodanie pustego elementu stylu do ciała, po skrypcie.
To naprawiło to. Jakie to dziwne? Mam nadzieję, że jest to pomocne dla kogoś.
źródło
var div = $('<div>').appendTo(element); setTimeout(function(){ div.remove(); }, 0);
$('<style></style>').appendTo($(document.body)).remove();
Ponieważ wyzwalacz display + offset nie działał dla mnie, znalazłem rozwiązanie tutaj:
http://mir.aculo.us/2009/09/25/force-redraw-dom-technique-for-webkit-based-browsers/
to znaczy
źródło
scale(1)
przypisałem to sobie jakoelement.style.webkitTransform = element.style.webkitTransform
. Powodem tego było ustawienie go jako pierwszego dla nieznacznego zniekształcenia strony w przypadkuabsolute
elementów pozycjonowanych w trybie li!display
rozwiązanie.Miałem ten sam problem. Poprawka „przełączania wyświetlania” danortona działała dla mnie po dodaniu do funkcji krokowej mojej animacji, ale martwiłem się wydajnością i szukałem innych opcji.
W moim przypadku element, który nie był odmalowywany, znajdował się w absolutnym elemencie pozycji, który w tamtym czasie nie miał indeksu Z. Dodanie indeksu Z do tego elementu zmieniło zachowanie Chrome, a odświeżanie przebiegło zgodnie z oczekiwaniami -> animacje stały się płynne.
Wątpię, czy to panaceum. Wyobrażam sobie, że to zależy, dlaczego Chrome zdecydował się nie przerysowywać tego elementu, ale zamieszczam tutaj to konkretne rozwiązanie w ramach pomocy, jakiej ma nadzieję.
Pozdrawiam, Rob
tl; dr >> Spróbuj dodać indeks Z do elementu lub jego elementu nadrzędnego.
źródło
Następujące prace. Musi być ustawiony tylko raz w czystym CSS. I działa bardziej niezawodnie niż funkcja JS. Wydajność wydaje się niezmieniona.
źródło
zoom
zamiast@-webkit-keyframes safariBugFix {from { zoom: 100%; } to { zoom: 99.99999%; }}
Z jakiegoś powodu nie mogłem uzyskać odpowiedzi danortona do pracy, mogłem zobaczyć, co powinno zrobić, więc trochę go poprawiłem:
i zadziałało dla mnie.
źródło
Przyszedłem tutaj, ponieważ po zmianie css musiałem przerysować paski przewijania w Chrome.
Jeśli ktoś ma ten sam problem, rozwiązałem go, wywołując tę funkcję:
Ta metoda nie jest najlepszym rozwiązaniem, ale może działać ze wszystkim, ukrywanie i pokazywanie elementu, który wymaga przerysowania, może rozwiązać każdy problem.
Oto skrzypce, w których go użyłem: http://jsfiddle.net/promatik/wZwJz/18/
źródło
Natknąłem się na to dzisiaj: Element.redraw () dla prototype.js
Za pomocą:
Jednak czasami zauważyłem, że musisz wywołać redraw () bezpośrednio na problematycznym elemencie. Czasami przerysowanie elementu nadrzędnego nie rozwiąże problemu, którego doświadcza dziecko.
Dobry artykuł o tym, jak przeglądarki renderują elementy: Renderowanie: odmalowanie, ponowne wlanie / przekazanie, zmiana stylu
źródło
appendChild
jest metodą DOM, a nie metodą jQuery.Miałem ten problem z wieloma divami, które zostały wstawione do innego diva
position: absolute
, wstawione divy nie miały atrybutu położenia. Kiedy zmieniłem to naposition:relative
działało dobrze. (naprawdę trudno było wskazać problem)W moim przypadku elementy zostały wstawione przez Angulara za pomocą
ng-repeat
.źródło
Nie mogę uwierzyć, że nadal jest to problem w 2014 roku. Właśnie miałem ten problem podczas odświeżania pola podpisu o stałej pozycji w lewym dolnym rogu strony podczas przewijania, podpis przesuwałby się w górę ekranu. Po wypróbowaniu wszystkiego powyżej bez powodzenia zauważyłem, że wiele rzeczy było albo powolnych / powodujących problemy z powodu tworzenia bardzo krótkich przekaźników DOM itp. Powodujących nieco nienaturalne uczucie przewijania itp ...
Skończyło się na zrobieniu stałej pozycji, pełnowymiarowym
pointer-events: none
divu i zastosowaniu odpowiedzi danortona na ten element, co wydaje się wymuszać przerysowanie na całym ekranie bez ingerencji w DOM.HTML:
CSS:
JS:
źródło
z-index
ipointer-events
są tutaj zbędne.Nie żeby to pytanie wymagało kolejnej odpowiedzi, ale po prostu zmiana koloru o jeden bit wymusiła odmalowanie w mojej konkretnej sytuacji.
setTimeout
Okazała krytyczny, aby przesunąć drugą zmianę stylu na zewnątrz pętli prądowej zdarzeń.źródło
Jedyne rozwiązanie, które działa dla mnie, jest podobne do odpowiedzi sowasred2012:
Na stronie mam wiele bloków problemów, dlatego zmieniam
display
właściwość elementu głównego. I używamdisplay: table;
zamiastdisplay: none;
, ponieważnone
resetuje przewijanie przesunięcie.źródło
Korzystam z tej
transform: translateZ(0);
metody, ale w niektórych przypadkach nie jest wystarczająca.Nie jestem fanem dodawania i usuwania zajęć, więc próbowałem znaleźć sposób na rozwiązanie tego problemu i skończyłem z nowym hackem, który działa dobrze:
źródło
Ponieważ wydaje się, że każdy ma własne problemy i rozwiązania, pomyślałem, że dodam coś, co będzie dla mnie odpowiednie. Na Androidzie 4.1 z obecnym Chrome, próbując przeciągnąć płótno do wewnątrz div z przepełnieniem: ukryty, nie mogłem pobrać przerysowania, chyba że dodałem element do nadrzędnego div (gdzie nie wyrządziłoby to żadnej szkody).
Brak migotania ekranu lub prawdziwej aktualizacji i sprzątanie po sobie. Żadnych zmiennych o zasięgu globalnym lub klasowym, tylko lokalne. Wydaje się, że nic nie szkodzi w mobilnym Safari / iPadzie lub przeglądarkach stacjonarnych.
źródło
Pracuję nad aplikacją jonową HTML5, na kilku ekranach mam
absolute
element pozycjonowany, kiedy przewijałem w górę lub w dół na urządzeniach IOS (iPhone 4,5,6, 6+) miałem odmalowany błąd.Próbowałem wielu rozwiązań, z których żadne nie działało, z wyjątkiem tego, które rozwiązało mój problem.
Używam klasy css
.fixRepaint
na tych elementach pozycji absolutnychTo naprawiło mój problem, może komuś pomóc
źródło
To jest w porządku dla JS
Ale w Jquery, a szczególnie, gdy można użyć tylko $ (dokument) .ready i nie można powiązać ze zdarzeniem .load obiektu z jakiegokolwiek konkretnego powodu, następujące działania będą działać.
Musisz pobrać kontener OUTER (MOST) obiektów / div, a następnie usunąć całą jego zawartość do zmiennej, a następnie dodać ją ponownie. Sprawi, że WSZYSTKIE zmiany dokonane w zewnętrznym kontenerze będą widoczne.
źródło
Uważam, że ta metoda jest przydatna podczas pracy z przejściami
źródło
hack „display / offsetHeight” nie działał w moim przypadku, przynajmniej gdy był zastosowany do animowanego elementu.
miałem rozwijane menu, które było otwarte / zamknięte nad treścią strony. artefakty pozostawały w treści strony po zamknięciu menu (tylko w przeglądarkach internetowych). jedynym sposobem, w jaki działał hack „display / offsetHeight” jest zastosowanie go do ciała, co wydaje się paskudne.
znalazłem jednak inne rozwiązanie:
wciąż jest to dość hackerskie (wykorzystuje właściwość CSS3 do wymuszenia renderowania sprzętowego), ale przynajmniej wpływa tylko na dany element i działało dla mnie zarówno na safari, jak i na Chrome na PC i Mac.
źródło
Wydaje się to związane z tym: styl jQuery nie jest stosowany w Safari
Rozwiązanie zaproponowane w pierwszej odpowiedzi zadziałało dla mnie dobrze w tych scenariuszach, a mianowicie: zastosuj i usuń atrapę klasy do ciała po wprowadzeniu zmian stylizacji:
To zmusza safari do przerysowania.
źródło
powyższe sugestie nie działały dla mnie. ale poniżej.
Chcesz dynamicznie zmieniać tekst wewnątrz kotwicy. Słowo „Szukaj”. Utworzono wewnętrzny znacznik „font” z atrybutem id. Zarządzałem zawartością za pomocą javascript (poniżej)
zawartość skryptu:
źródło
Miałem problem z SVG, który znikał w Chrome na Androida, gdy orientacja została zmieniona w pewnych okolicznościach. Poniższy kod nie odtwarza go, ale konfigurację, którą mieliśmy.
Półtora dnia później po szturchaniu i szturchaniu i niezadowoleniu z hackerskich rozwiązań tutaj, odkryłem, że problem był spowodowany faktem, że wydawało się, że element zachowuje pamięć podczas rysowania nowego. Rozwiązaniem było uniknięcie identyfikatora linearGradient na SVG, mimo że był on używany tylko raz na stronę.
Można to osiągnąć na wiele różnych sposobów, ale dla naszej aplikacji kątowej użyliśmy funkcji lodash uniqueId, aby dodać zmienną do zakresu:
Dyrektywa kątowa (JS):
Aktualizacje HTML:
Wiersz 5:
<linearGradient ng-attr-id="{{indicatorColourPatternId}}" x1="0" x2="0" y1="0" y2="1">
Linia 11:
<rect x="0" y="0" rx="5" ry="5" width="100%" height="100%" ng-attr-fill="url(#{{indicatorColourPatternId}})"/>
Mam nadzieję, że ta odpowiedź pozwoli zaoszczędzić komuś dni na zmiażdżenie klawiatury.
źródło
Poleciłbym mniej hackerski i bardziej formalny sposób wymuszenia reflow: użyj forceDOMReflowJS . W twoim przypadku kod wyglądałby następująco.
źródło
Odkryłem, że dodanie stylu zawartości do elementu zmusiło go do odmalowania. Powinna to być inna wartość za każdym razem, gdy chcesz go przerysować i nie musi być pseudoelementem.
źródło
Próbowałem więcej odpowiedzi, ale to nie działa dla mnie. Miałem problem z tym samym klientWidth z safari w porównaniu z innymi przeglądarkami, a ten kod rozwiązał problem:
To naprawdę dziwne, ponieważ jeśli spróbuję ponownie uzyskać wartość clientWidth po get_safe_value, uzyskam złą wartość podczas safari, getter musi znajdować się pomiędzy
sty.transform = "translateZ(1px)";
asty.transform = "";
Drugim rozwiązaniem, które działa zdecydowanie, jest
Problem polega na tym, że tracisz fokus i przewijasz stany.
źródło
Wymusi to odmalowanie, unikając migotania, majsterkowania istniejących elementów i problemów z układem ...
źródło
Proste rozwiązanie z jquery:
lub
Miał plik SVG, który nie wyświetlał się, gdy został dodany do HTML.
Można to dodać po wyświetleniu elementów svg na ekranie.
Lepszym rozwiązaniem jest użycie:
oraz z jQuery:
wyrenderuje to poprawnie w Chrome.
źródło