Jak zmusić WebKit do przerysowania / odmalowania w celu propagowania zmian stylu?

247

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?

Danorton
źródło
Wydaje mi się, że ten problem występuje na Androidzie 4.2.2 (Samsung I9500) podczas owijania aplikacji Canvas w WebView. Śmieszny!
Josh
3
what-forces-layout.md bardzo dobre miejsce do czytania
vsync

Odpowiedzi:

312

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:

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

Pozwolę komuś innemu komentować, jeśli działa dla stylów innych niż „blok”.

Dzięki, Vasil!

Danorton
źródło
32
Aby uniknąć migotania można spróbować 'inline-block', 'table'albo 'run-in'zamiast 'none', ale może to mieć skutki uboczne. Poza tym offsetHeightsel.style.display = 'run-in'; setTimeout(function () { sel.style.display = 'block'; }, 0);
przekroczenie
15
Ta odpowiedź jest nadal przydatna 2 lata później. Właśnie użyłem go, aby naprawić problem tylko z Chrome, w którym cienie pola CSS pozostały na ekranie po zmianie rozmiaru przeglądarki w określony sposób. Dzięki!
rkulla
5
@danorton Odpowiedziałeś w 2010 roku. Jest rok 2013, a błąd nadal występuje. Dzięki. Nawiasem mówiąc, ktoś wie, czy jest jakiś problem zarejestrowany na trackerze webkit?
RaphaelDDL 24.04.13
13
PS .: dla mnie powyższe rozwiązanie już nie działa. Zamiast tego użyłem tego (jQuery): sel.hide (). Show (0); Źródło: stackoverflow.com/questions/8840580/…
ProblemsOfSumit
7
Wszystko, co musisz zrobić, to przeczytać właściwość rozmiaru, nie musisz jej zmieniać w tę iz powrotem.
Andrew Bullock,
93

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.

.willnotrender { 
   transform: translateZ(0); 
}

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.

morewry
źródło
1
Pracował dla mnie podczas korzystania z karuzeli kątowej !
gustavohenke
1
Naprawiono problem polegający na tym, że promień graniczny został utracony w elemencie w przesuwanym panelu
Timo,
1
Działa również w projektach Cordova!
Quispie 22.04.16
1
Pracowałem dla mnie nad zaciskiem -webkit-line, który nie został odświeżony
Adam Marshall
1
Pracowałem dla mnie na iPadzie (6.0) z opcją -webkit-transform: translate (-50%, -50%).
Lain
51

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.

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

To naprawiło to. Jakie to dziwne? Mam nadzieję, że jest to pomocne dla kogoś.

Gerben
źródło
3
Głosowałbym za 1.000.000 razy, gdybym mógł. To jest jedyny sposób, w jaki mogę uzyskać chrom, aby odmalować głupią divę, którą przeciągałem. Nawiasem mówiąc, nie musisz dodawać elementu stylu (przynajmniej ja tego nie zrobiłem), żaden element będzie działał. Zrobiłem div i podałem mu identyfikator, dzięki czemu mogłem usunąć, a następnie dodać element na każdym kroku, aby nie wypełniać DOM niepotrzebnymi tagami.
hobberwickey
6
właśnie użyłem tego zmieszanego z komentarzem Pumbaa80 do innej odpowiedzi. var div = $('<div>').appendTo(element); setTimeout(function(){ div.remove(); }, 0);
Naprawiłem
33
Ta pojedyncza linia działa dla mnie świetnie! $('<style></style>').appendTo($(document.body)).remove();
pdelanauze
1
Odpowiedź @pdelanauze działa idealnie. Mam problem z przerysowaniem śpiewania css3, tłumaczenia i przekształcania w iOS.
Marcel Falliere
11
Po prostu wiedz, że wymusza to odświeżenie całej strony, podczas gdy przez większość czasu chcesz tylko
odmalować
33

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

element.style.webkitTransform = 'scale(1)';
EricG
źródło
3
Użyłem tego w hackie, którego próbowałem, ale zamiast tego scale(1)przypisałem to sobie jako element.style.webkitTransform = element.style.webkitTransform. Powodem tego było ustawienie go jako pierwszego dla nieznacznego zniekształcenia strony w przypadku absoluteelementów pozycjonowanych w trybie li!
bPratik
To działało dla mnie i nie miałem problemów z migotaniem lub resetowaniem pozycji przewijania, co displayrozwiązanie.
davidtbernal
Miałem aplikację Cordova używającą dużo dynamicznego SVG. Działało dobrze wszędzie oprócz iOS7, gdzie po prostu nie wyświetlał elementów SVG podczas uruchamiania. Dodano prosty $ („body”) [0] .style.webkitTransform = 'scale (1)'; do kodu inicjalizacji i problem zniknął!
Herc
W tej chwili nie działa to w najnowszych przeglądarkach Safari i iOS.
setholopolus
@setholopolus, która wersja (-y) by to była?
EricG
23

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.

Rob Murphy
źródło
8
Znakomity. To jest niesamowite i rozwiązało problem. +++ ponownie indeksuje Z.
trisweb
Nie działało w mojej sytuacji dotyczącej pasków przewijania i transformacji.
Ricky Boyce,
16

Następujące prace. Musi być ustawiony tylko raz w czystym CSS. I działa bardziej niezawodnie niż funkcja JS. Wydajność wydaje się niezmieniona.

@-webkit-keyframes androidBugfix {from { padding: 0; } to { padding: 0; }}
body { -webkit-animation: androidBugfix infinite 1s; }
chwasty
źródło
Wygląda na to, że to też działa dla mnie. Wykorzystano to do rozwiązania problemu z renderowaniem w Mobile Safari
Chris
To rozwiązuje mój problem, zmusza safari do wycofania się. Jednak zoomzamiast @-webkit-keyframes safariBugFix {from { zoom: 100%; } to { zoom: 99.99999%; }}
paddingu
13

Z jakiegoś powodu nie mogłem uzyskać odpowiedzi danortona do pracy, mogłem zobaczyć, co powinno zrobić, więc trochę go poprawiłem:

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

i zadziałało dla mnie.

sowasred2012
źródło
7
Próbowałem wszystkiego powyżej, ale tylko ten działał dla mnie. WTF webkit! To nie jest informatyka! To jest czarna magia!
Charlie Martin
7

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

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

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/

António Almeida
źródło
1
Wspaniały! Próbowałem też animować paski przewijania i właśnie tego potrzebowałem! Btw lepiej użyć przelewu: nakładka na animowane paski przewijania
ekalchev
6

Natknąłem się na to dzisiaj: Element.redraw () dla prototype.js

Za pomocą:

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

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

Adam Eberlin
źródło
1
appendChildjest metodą DOM, a nie metodą jQuery.
ChrisW,
4

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 na position:relativedziałało dobrze. (naprawdę trudno było wskazać problem)

W moim przypadku elementy zostały wstawione przez Angulara za pomocą ng-repeat.

JustGoscha
źródło
1
Dzięki! To zadziałało również w przypadku mojego problemu i jest o wiele lżejsze niż wiele powyższych rozwiązań javascript.
Dsyko
4

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: nonedivu i zastosowaniu odpowiedzi danortona na ten element, co wydaje się wymuszać przerysowanie na całym ekranie bez ingerencji w 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';
gofr
źródło
Nie mogę ci wystarczająco podziękować za obejście tego problemu, które było dla mnie jedyne. Tak, jest rok 2017 i problem się utrzymuje. Mój problem dotyczył strony w języku RTL, która byłaby pusta, jeśli byłaby ręcznie odświeżana na urządzeniach mobilnych z Androidem. Zasady z-indexi pointer-eventssą tutaj zbędne.
Amin Mozafari
Wcześniej korzystałem z poprawki danortona, ale naprawdę zmagałem się z błyskiem treści od ustawienia wyświetlania na brak. Twoje rozwiązanie okazało się dla mnie świetne bez zawartości flash!
Justin Noel,
3

Nie żeby to pytanie wymagało kolejnej odpowiedzi, ale po prostu zmiana koloru o jeden bit wymusiła odmalowanie w mojej konkretnej sytuacji.

//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);

setTimeoutOkazała krytyczny, aby przesunąć drugą zmianę stylu na zewnątrz pętli prądowej zdarzeń.

TMan
źródło
1
Ustawienie limitu czasu 0 okazało się przydatne w innej, ale podobnej sytuacji. Przerysowanie nie występowało, zanim dyskretna walidacja jquery nie zamroziła ekranu podczas analizowania dużej formy. Pomyślałem, że skomentuję na wypadek, gdyby ktoś znalazł się w tej samej sytuacji. Inne rozwiązania nie działały w tym scenariuszu.
k29
2

Jedyne rozwiązanie, które działa dla mnie, jest podobne do odpowiedzi sowasred2012:

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

Na stronie mam wiele bloków problemów, dlatego zmieniam displaywłaściwość elementu głównego. I używam display: table;zamiast display: none;, ponieważ noneresetuje przewijanie przesunięcie.

Ilya Sviridenko
źródło
2

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:

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

// ios redraw fix
animation: redraw 1s linear infinite;
Guillaume Gautier
źródło
1

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

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);
}

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.

Eric Ruck
źródło
1

Pracuję nad aplikacją jonową HTML5, na kilku ekranach mam absoluteelement 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 .fixRepaintna tych elementach pozycji absolutnych

.fixRepaint{
    transform: translateZ(0);
}

To naprawiło mój problem, może komuś pomóc

Anjum ....
źródło
1
Opss trochę, jak tego nie widziałem. @ morewry Dzięki za wskazanie
Anjum ....
0

To jest w porządku dla JS

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

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.

$(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
źródło
0

Uważam, że ta metoda jest przydatna podczas pracy z przejściami

$element[0].style.display = 'table'; 
$element[0].offsetWidth; // force reflow
$element.one($.support.transition.end, function () { 
    $element[0].style.display = 'block'; 
});
jschr
źródło
0

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:

  1. zanim element zacznie się animować, dodaj klasę, która definiuje „-webkit-backface-visibility: hidden;” na elemencie (domyślam się, że można również użyć stylu wbudowanego)
  2. po zakończeniu animacji usuń klasę (lub styl)

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.

Tedtedson
źródło
0

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:

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

To zmusza safari do przerysowania.

Steve
źródło
Aby to działało w Chrome, musiałem dodać: $ („body”). AddClass („dummyclass”). Delay (0) .removeClass („dummyclass”);
mbokil
0

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)

Szukaj

zawartość skryptu:

    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
źródło
0

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.

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>

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

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

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.

Jamie Barker
źródło
0

Poleciłbym mniej hackerski i bardziej formalny sposób wymuszenia reflow: użyj forceDOMReflowJS . W twoim przypadku kod wyglądałby następująco.

sel = document.getElementById('my_id');
forceReflowJS( sel );
return false;
Jack Giffin
źródło
0

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.

.selector {
    content: '1'
}
Steve
źródło
0

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:

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

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

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

Problem polega na tym, że tracisz fokus i przewijasz stany.

bormat
źródło
0

Wymusi to odmalowanie, unikając migotania, majsterkowania istniejących elementów i problemów z układem ...

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());  
    });
}
użytkownik2026189
źródło
-1

Proste rozwiązanie z jquery:

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

lub

element.innerHTML = element.innerHTML;

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:

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

oraz z jQuery:

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

wyrenderuje to poprawnie w Chrome.

Yaron Shamir
źródło
Problem z tym podejściem polega na tym, że tracisz wszystkie procedury obsługi zdarzeń zarejestrowane na obiekcie lub jego potomkach.
Haqa