ฉันจะบังคับให้ WebKit วาด / ทาสีใหม่เพื่อเผยแพร่การเปลี่ยนแปลงสไตล์ได้อย่างไร


247

ฉันมีจาวาสคริปต์เล็กน้อยเพื่อเปลี่ยนสไตล์:

sel = document.getElementById('my_id');
sel.className = sel.className.replace(/item-[1-9]-selected/,'item-1-selected');
return false;

ใช้งานได้ดีกับ FF, Opera และ IE เวอร์ชันล่าสุด แต่ล้มเหลวใน Chrome และ Safari เวอร์ชันล่าสุด

มันมีผลต่อลูกหลานสองคนซึ่งเกิดขึ้นเป็นพี่น้อง การปรับปรุงพี่น้องคนแรก แต่ครั้งที่สองไม่ได้ทำ ลูกขององค์ประกอบที่สองยังมีโฟกัสและมีแท็ก<a>ที่มีรหัสข้างต้นในแอตทริบิวต์onclick

ใน Chrome หน้าต่าง“เครื่องมือสำหรับนักพัฒนา” ถ้าฉันเขยิบ (เช่นยกเลิกการเลือกและการตรวจสอบ) ใดแอตทริบิวต์ใด ๆองค์ประกอบการปรับปรุงพี่น้องสองกับรูปแบบที่ถูกต้อง

มีวิธีแก้ปัญหาที่ง่ายและโปรแกรม "เขยิบ" WebKit ไปทำสิ่งที่ถูกต้องหรือไม่?


ฉันคิดว่าฉันประสบปัญหานี้ใน Android 4.2.2 (Samsung I9500) เมื่อห่อแอพ Canvas ของฉันใน WebView ไร้สาระ!
Josh

3
what-forces-layout.mdเป็นแหล่งอ่านหนังสือที่ดีมาก
vsync

คำตอบ:


312

ฉันพบข้อเสนอแนะที่ซับซ้อนและข้อเสนอง่าย ๆ ที่ไม่ได้ผล แต่ความเห็นของVasil Dinkovหนึ่งในนั้นได้ให้วิธีง่ายๆในการบังคับให้วาด / ทาสีใหม่ซึ่งทำงานได้ดี:

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

ฉันจะให้คนอื่นแสดงความคิดเห็นถ้ามันใช้งานได้กับสไตล์อื่น ๆ นอกเหนือจาก "บล็อก"

ขอบคุณ Vasil!


32
เพื่อหลีกเลี่ยงการริบหรี่คุณอาจลอง'inline-block', 'table'หรือ'run-in'แทน'none'แต่เรื่องนี้อาจจะมีผลข้างเคียง นอกจากนี้การหมดเวลาของ 0 จะทำให้เกิดการ reflow เช่นเดียวกับการสอบถามoffsetHeight:sel.style.display = 'run-in'; setTimeout(function () { sel.style.display = 'block'; }, 0);
123444555621

15
คำตอบนี้ยังคงมีประโยชน์ 2 ปีต่อมา ฉันเพิ่งใช้มันเพื่อแก้ไขปัญหาเฉพาะ Chrome เท่านั้นที่มีเงากล่อง CSS ยังคงอยู่บนหน้าจอหลังจากปรับขนาดเบราว์เซอร์ในบางวิธี ขอบคุณ!
rkulla

5
@danorton คุณตอบในปี 2010 เป็นปี 2013 และข้อผิดพลาดยังคงอยู่ ขอบคุณ ยังไงก็ตามทุกคนรู้ว่ามีปัญหาใด ๆ ที่ลงทะเบียนที่ webkit tracker?
RaphaelDDL

13
ป.ล. : สำหรับฉันทางออกข้างต้นไม่ได้อีกต่อไป ฉันใช้สิ่งนี้แทน (jQuery): sel.hide (). show (0); ที่มา: stackoverflow.com/questions/8840580/...
ProblemsOfSumit

7
สิ่งที่คุณต้องทำคืออ่านคุณสมบัติขนาดคุณไม่จำเป็นต้องเปลี่ยนไปมา
Andrew Bullock

93

เมื่อเร็ว ๆ นี้เราพบสิ่งนี้และค้นพบว่าการส่งเสริมองค์ประกอบที่ได้รับผลกระทบไปยังเลเยอร์คอมโพสิตด้วยtranslateZใน CSS แก้ไขปัญหาโดยไม่จำเป็นต้องใช้ JavaScript เพิ่มเติม

.willnotrender { 
   transform: translateZ(0); 
}

เนื่องจากปัญหาการทาสีเหล่านี้ส่วนใหญ่จะปรากฏใน Webkit / Blink และการแก้ไขนี้ส่วนใหญ่จะมุ่งไปที่ Webkit / Blink ดังนั้นจึงเป็นที่นิยมในบางกรณี โดยเฉพาะอย่างยิ่งตั้งแต่คำตอบที่ได้รับการยอมรับเกือบจะแน่นอนทำให้เกิดreflowและทาสี , ไม่เพียงแค่ทาสี

Webkit และ Blink ทำงานอย่างหนักในการเรนเดอร์ประสิทธิภาพและข้อบกพร่องเหล่านี้เป็นผลข้างเคียงที่โชคร้ายของการปรับให้เหมาะสมซึ่งมีจุดมุ่งหมายเพื่อลดการไหลและสีที่ไม่จำเป็น CSS จะเปลี่ยนหรือสเปคที่ประสบความสำเร็จอื่นจะเป็นทางออกในอนาคตส่วนใหญ่

มีวิธีอื่น ๆ เพื่อให้ได้เลเยอร์คอมโพสิต แต่นี่เป็นวิธีที่ธรรมดาที่สุด


1
ทำงานให้ฉันเมื่อใช้งานแองกูลาร์- ม้าหมุน !
gustavohenke

1
แก้ไขปัญหาที่รัศมีของฉันหายไปในองค์ประกอบภายในแผงเลื่อน
Timo

1
ใช้งานได้กับโครงการ Cordova เช่นกัน!
Quispie

1
ทำงานให้ฉันสำหรับ -webkit-line-clamp ที่ไม่รีเฟรช
Adam Marshall

1
ทำงานกับฉันใน iPad (6.0) ด้วย -webkit-transform: แปล (-50%, -50%)
นอน

51

danorton ทางออกไม่ทำงานสำหรับฉัน ฉันมีปัญหาแปลก ๆ จริง ๆ ที่ webkit จะไม่วาดองค์ประกอบบางอย่างเลย ที่ซึ่งข้อความในอินพุตไม่ได้รับการอัพเดตจนกระทั่ง onblur; และการเปลี่ยน className จะไม่ส่งผลให้วาดใหม่

วิธีแก้ปัญหาของฉันฉันค้นพบโดยบังเอิญคือการเพิ่มองค์ประกอบสไตล์ที่ว่างเปล่าให้กับร่างกายหลังจากสคริปต์

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

ที่แก้ไขมัน นั่นเป็นวิธีที่แปลก? หวังว่านี่จะเป็นประโยชน์สำหรับใครบางคน


3
ฉันจะโหวต 1,000,000 ครั้งถ้าทำได้ นี่เป็นวิธีเดียวที่ฉันจะได้รับโครเมี่ยมเพื่อวาด div โง่ฉันถูกลากไปรอบ ๆ อย่างไรก็ตามคุณไม่ต้องเพิ่มองค์ประกอบสไตล์ (อย่างน้อยฉันก็ไม่ได้) องค์ประกอบใด ๆ ก็ใช้ได้ ฉันสร้าง div ขึ้นมาแล้วให้รหัสเพื่อที่ฉันจะได้ลบออกแล้วเพิ่มองค์ประกอบในแต่ละขั้นตอนเพื่อที่จะไม่เติม DOM ด้วยแท็กที่ไร้ประโยชน์
hobberwickey

6
เพิ่งใช้มิกซ์นี้กับคอมเม้นต์ของ Pumbaa80 กับคำตอบอื่น การแก้ไขที่ฉันจบลงคือvar div = $('<div>').appendTo(element); setTimeout(function(){ div.remove(); }, 0);
bendman

33
บรรทัดเดียวนี้ทำงานได้ดีสำหรับฉัน! $('<style></style>').appendTo($(document.body)).remove();
pdelanauze

1
@pdelanauze คำตอบที่สมบูรณ์แบบ ฉันมีปัญหาการวาดใหม่ร้องเพลง css3 แปลและแปลงเป็น iOS
Marcel Falliere

11
เพิ่งรู้ว่าสิ่งนี้บังคับให้ทาสีทั้งหน้าในขณะที่เวลาส่วนใหญ่คุณเพียงต้องการทาสีบางส่วนของหน้า ...
Ryan Wheale

33

เนื่องจากทริกเกอร์ display + offset ไม่ทำงานสำหรับฉันฉันจึงพบวิธีแก้ไขที่นี่:

http://mir.aculo.us/2009/09/25/force-redraw-dom-technique-for-webkit-based-browsers/

กล่าวคือ

element.style.webkitTransform = 'scale(1)';

3
ผมใช้วิธีนี้ในการสับผมพยายาม แต่แทนที่จะผมได้รับมอบหมายให้กับตัวเองเป็นscale(1) element.style.webkitTransform = element.style.webkitTransformเหตุผลของสิ่งนี้คือการตั้งค่าให้กับอดีตคือการบิดเบือนหน้าเล็กน้อยสำหรับabsoluteองค์ประกอบตำแหน่ง!
bPratik

สิ่งนี้ใช้ได้สำหรับฉันและไม่มีปัญหาในการกะพริบหรือรีเซ็ตตำแหน่งการเลื่อนที่displayโซลูชันทำ
davidtbernal

ฉันมีแอพ Cordova ที่ใช้ SVG แบบไดนามิกจำนวนมาก ทำงานได้ดีทุกที่ยกเว้น iOS7 ซึ่งหากไม่แสดงองค์ประกอบ SVG เมื่อเริ่มต้น เพิ่มวิ $ ('body') [0] .style.webkitTransform = 'scale (1)'; รหัสเริ่มต้นและปัญหาหายไป!
Herc

นี่ยังใช้งานไม่ได้กับ Safari และ iOS รุ่นใหม่ล่าสุด
setholopolus

@setholopolus versoin (s) ที่จะเป็นอย่างไร
EricG

23

ฉันกำลังทุกข์ทรมานกับปัญหาเดียวกัน การแก้ไข 'toggling display' ของ danorton ทำงานได้สำหรับฉันเมื่อเพิ่มไปยังฟังก์ชันขั้นตอนของภาพเคลื่อนไหวของฉัน แต่ฉันกังวลเกี่ยวกับประสิทธิภาพและฉันมองหาตัวเลือกอื่น ๆ

ในกรณีของฉันองค์ประกอบที่ไม่ได้ทาสีใหม่นั้นอยู่ในองค์ประกอบตำแหน่งที่แน่นอนซึ่งในเวลานั้นไม่มีดัชนี z การเพิ่ม z-index ไปยังองค์ประกอบนี้เปลี่ยนพฤติกรรมของ Chrome และ repaints ที่เกิดขึ้นตามที่คาดไว้ -> ภาพเคลื่อนไหวราบรื่น

ฉันสงสัยว่านี่เป็นยาครอบจักรวาลฉันคิดว่ามันขึ้นอยู่กับสาเหตุที่ Chrome เลือกที่จะไม่วาดองค์ประกอบใหม่ แต่ฉันโพสต์โซลูชันเฉพาะนี้ที่นี่เพื่อช่วยหวังว่าจะมีใครบางคน

ไชโยร็อบ

tl; dr >> ลองเพิ่มดัชนี z ลงในองค์ประกอบหรือพาเรนต์ของมัน


8
สุกใส มันยอดเยี่ยมและแก้ไขปัญหาให้ฉัน +++ จะ z-index อีกครั้ง
trisweb

ไม่ทำงานในสถานการณ์ของฉันเกี่ยวกับแถบเลื่อนและการแปลง
Ricky Boyce

16

ผลงานดังต่อไปนี้ จะต้องตั้งค่าครั้งเดียวใน CSS บริสุทธิ์ และทำงานได้อย่างน่าเชื่อถือมากกว่าฟังก์ชั่น JS ประสิทธิภาพดูเหมือนไม่ได้รับผลกระทบ

@-webkit-keyframes androidBugfix {from { padding: 0; } to { padding: 0; }}
body { -webkit-animation: androidBugfix infinite 1s; }

ดูเหมือนว่ามันจะทำงานสำหรับฉันเช่นกัน ใช้สิ่งนี้เพื่อแก้ไขปัญหาการแสดงผลกับ Mobile Safari
Chris

วิธีนี้ช่วยแก้ไขปัญหาของฉันได้บังคับให้ซาฟารีส่งต่อข้อมูล อย่างไรก็ตามฉันใช้zoomแทนการขยาย:@-webkit-keyframes safariBugFix {from { zoom: 100%; } to { zoom: 99.99999%; }}
Ahmed Musallam

13

ด้วยเหตุผลบางอย่างที่ฉันไม่สามารถหาคำตอบในการทำงานของ Danorton ได้ฉันสามารถเห็นสิ่งที่มันควรจะทำดังนั้นฉันจึงปรับมันเล็กน้อย:

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

และมันก็ได้ผลกับฉันด้วย


7
ฉันลองทุกอย่างที่เหนือกว่านี้ แต่มีเพียงอันเดียวเท่านั้นที่เหมาะกับฉัน WTF webkit! นี่ไม่ใช่วิทยาศาสตร์คอมพิวเตอร์! นี่คือมนต์ดำ!
Charlie Martin

7

ฉันมาที่นี่เพราะฉันต้องการที่จะวาดใหม่แถบเลื่อนใน Chrome หลังจากเปลี่ยน CSS

หากใครบางคนมีปัญหาเดียวกันฉันแก้ไขได้โดยเรียกใช้ฟังก์ชันนี้:

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

วิธีนี้ไม่ใช่วิธีที่ดีที่สุด แต่อาจใช้ได้กับทุกอย่างการซ่อนและแสดงองค์ประกอบที่จำเป็นต้องวาดใหม่อาจช่วยแก้ปัญหาได้ทุกปัญหา

นี่คือซอที่ฉันใช้: http://jsfiddle.net/promatik/wZwJz/18/


1
ที่ดี! ฉันพยายามเคลื่อนไหวแถบเลื่อนด้วยและนั่นคือสิ่งที่ฉันต้องการ! Btw ดีกว่าใช้ overflow: overlay สำหรับ scrollbars แบบเคลื่อนไหว
ekalchev

6

ฉันพบสิ่งนี้ในวันนี้: Element.redraw () สำหรับ prototype.js

โดยใช้:

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

อย่างไรก็ตามบางครั้งฉันสังเกตเห็นว่าคุณต้องเรียก redraw () บนองค์ประกอบที่มีปัญหาโดยตรง บางครั้งการเขียนองค์ประกอบหลักจะไม่สามารถแก้ปัญหาที่เด็กกำลังประสบอยู่ได้

บทความที่ดีเกี่ยวกับวิธีที่เบราว์เซอร์แสดงองค์ประกอบ: การเรนเดอร์: ทาสี, reflow / relayout, restyle


1
appendChildเป็นวิธี DOM ไม่ใช่วิธี jQuery
ChrisW

4

ฉันมีปัญหานี้กับจำนวนของ divs ที่ใส่เข้าไปในอีก div ด้วยposition: absolutedivs ที่แทรกไว้นั้นไม่มีแอตทริบิวต์ตำแหน่ง เมื่อฉันเปลี่ยนสิ่งนี้position:relativeมันใช้งานได้ดี (ยากมากที่จะระบุปัญหา)

ng-repeatในกรณีขององค์ประกอบที่เขียนโดยเชิงมุมกับ


1
ขอบคุณ! สิ่งนี้ได้ผลกับปัญหาของฉันเช่นกันและมีน้ำหนักเบากว่ามากซึ่งโซลูชันจาวาสคริปต์จำนวนมากดังกล่าวข้างต้น
Dsyko

4

ฉันไม่อยากเชื่อว่านี่จะเป็นปัญหาในปี 2014 ฉันเพิ่งมีปัญหานี้เมื่อรีเฟรชกล่องคำบรรยายภาพตำแหน่งคงที่ในมือซ้ายล่างของหน้าขณะเลื่อนดูคำบรรยายภาพจะเป็น 'ผี' จนถึงหน้าจอ หลังจากลองทุกอย่างข้างต้นโดยไม่ประสบความสำเร็จฉันสังเกตเห็นหลายสิ่งหลายอย่างไม่ว่าจะช้า / ก่อให้เกิดปัญหาเนื่องจากการสร้างรีเลย์ DOM สั้น ๆ ฯลฯ ทำให้เกิดความรู้สึกผิดปกติในการเลื่อน ฯลฯ ...

ฉันลงเอยด้วยการกำหนดตำแหน่งที่แน่นอน div ขนาดเต็มด้วยpointer-events: noneและใช้คำตอบของ Danort กับองค์ประกอบนั้นซึ่งดูเหมือนว่าจะบังคับให้วาดใหม่บนทั้งหน้าจอโดยไม่รบกวน 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';

ฉันไม่สามารถขอบคุณมากพอสำหรับวิธีแก้ปัญหาของคุณซึ่งเป็นคนเดียวที่ทำงานให้ฉัน ใช่มันเป็นปี 2017 และปัญหายังคงมีอยู่ ปัญหาของฉันเกี่ยวข้องกับหน้าภาษา RTL ซึ่งจะแสดงผลเปล่าหากรีเฟรชด้วยตนเองบนอุปกรณ์มือถือ Android z-indexและpointer-eventsกฎฟุ่มเฟือยที่นี่
Amin Mozafari

ฉันเคยใช้การแก้ไขของ Danorton มาก่อน แต่ก็ต้องดิ้นรนกับแฟลชของเนื้อหาจากการตั้งค่าการแสดงผลเป็น none โซลูชันของคุณทำงานได้อย่างยอดเยี่ยมสำหรับฉันโดยไม่มีแฟลชเนื้อหา!
Justin Noel

3

ไม่ใช่ว่าคำถามนี้ต้องการคำตอบอื่น แต่ฉันพบว่าการเปลี่ยนสีโดยการบังคับให้ทาสีใหม่ในสถานการณ์เฉพาะของฉัน

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

การsetTimeoutพิสูจน์ที่สำคัญเพื่อย้ายการเปลี่ยนแปลงสไตล์ที่สองนอกลูปเหตุการณ์ปัจจุบัน


1
การตั้งค่าการหมดเวลาเป็น 0 พิสูจน์แล้วว่ามีประโยชน์สำหรับฉันในสถานการณ์ที่แตกต่างกัน การวาดซ้ำไม่ได้เกิดขึ้นก่อนการตรวจสอบ jQuery ที่ไม่เป็นการรบกวนทำให้เกิดการแข็งตัวของหน้าจอในขณะที่แยกวิเคราะห์แบบฟอร์มขนาดใหญ่ คิดว่าฉันจะแสดงความคิดเห็นในกรณีที่มีคนอยู่ในสถานการณ์เดียวกัน โซลูชันอื่นไม่ทำงานในสถานการณ์นี้
k29

2

ทางออกเดียวสำหรับฉันนั้นคล้ายกับคำตอบของ sowasred2012:

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

ฉันมีจำนวนมากของบล็อกปัญหาบนหน้าเว็บดังนั้นฉันเปลี่ยนdisplayคุณสมบัติขององค์ประกอบราก และฉันใช้display: table;แทนdisplay: none;เพราะnoneจะรีเซ็ตการเลื่อนชดเชย


2

ฉันใช้transform: translateZ(0);วิธีการ แต่ในบางกรณีมันไม่เพียงพอ

ฉันไม่ชอบการเพิ่มและลบชั้นเรียนดังนั้นฉันจึงพยายามหาวิธีแก้ปัญหานี้และจบลงด้วยการแฮ็คใหม่ที่ทำงานได้ดี:

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

// ios redraw fix
animation: redraw 1s linear infinite;

1

เนื่องจากทุกคนดูเหมือนจะมีปัญหาและวิธีการแก้ปัญหาของตัวเองฉันคิดว่าฉันจะเพิ่มสิ่งที่เหมาะกับฉัน บน Android 4.1 ที่มี Chrome ปัจจุบันพยายามลากผืนผ้าใบไปรอบ ๆ ภายใน div ที่มีโอเวอร์โฟลว์: ซ่อนอยู่ฉันไม่สามารถวาดใหม่ได้นอกจากว่าฉันจะเพิ่มองค์ประกอบลงใน div parent (ซึ่งจะไม่ทำอันตรายใด ๆ )

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

ไม่มีการสั่นหน้าจอหรืออัปเดตจริงและทำความสะอาดหลังจากตัวเอง ไม่มีตัวแปรที่กำหนดขอบเขตระดับโลกหรือระดับเพียงแค่คนในท้องถิ่น ดูเหมือนจะไม่ทำอะไรเสียหายใน Mobile Safari / iPad หรือเบราว์เซอร์เดสก์ท็อป


1

ฉันกำลังทำงานกับแอพพลิเคชั่น ionic html5 ในบางหน้าจอที่ฉันได้absoluteจัดวางองค์ประกอบไว้เมื่อเลื่อนขึ้นหรือลงในอุปกรณ์ IOS (iPhone 4,5,6, 6+) ฉันมีข้อผิดพลาดในการทาสีใหม่

พยายามแก้ปัญหามากมายไม่มีใครทำงานได้ยกเว้นคนนี้ช่วยแก้ปัญหา

ฉันใช้คลาส css .fixRepaintกับองค์ประกอบตำแหน่งที่แน่นอนเหล่านั้น

.fixRepaint{
    transform: translateZ(0);
}

สิ่งนี้ได้แก้ไขปัญหาของฉันแล้วอาจช่วยได้บ้าง


1
Opss วิธีที่ฉันไม่ได้เห็นว่า @morewry ขอบคุณที่ชี้ให้เห็น
Anjum ....

0

นี่เป็นเรื่องปกติสำหรับ JS

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

แต่ใน Jquery และโดยเฉพาะอย่างยิ่งเมื่อคุณสามารถใช้ $ (เอกสาร). ready และไม่สามารถผูกกับเหตุการณ์. load ของวัตถุได้ด้วยเหตุผลใดก็ตามสิ่งต่อไปนี้จะใช้ได้

คุณต้องรับคอนเทนเนอร์ OUTER (MOST) ของอ็อบเจกต์ / div แล้วลบเนื้อหาทั้งหมดลงในตัวแปรแล้วเพิ่มเข้าไปอีกครั้ง มันจะทำให้การเปลี่ยนแปลงทั้งหมดที่ทำในภาชนะด้านนอกมองเห็นได้

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

0

ฉันพบว่าวิธีนี้มีประโยชน์เมื่อทำงานกับช่วงการเปลี่ยนภาพ

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

0

แฮ็ค "display / offsetHeight" ไม่ทำงานในกรณีของฉันอย่างน้อยตอนที่มันถูกนำไปใช้กับองค์ประกอบที่กำลังเคลื่อนไหว

ฉันมีเมนูแบบเลื่อนลงที่กำลังเปิด / ปิดอยู่เหนือเนื้อหาของหน้า สิ่งประดิษฐ์ถูกทิ้งไว้บนเนื้อหาของหน้าหลังจากเมนูปิด (เฉพาะในเบราว์เซอร์ webkit) วิธีเดียวที่แฮ็ก "display / offsetHeight" ทำงานคือถ้าฉันใช้มันกับร่างกายซึ่งดูเหมือนจะน่ารังเกียจ

อย่างไรก็ตามฉันหาวิธีแก้ปัญหาอื่น:

  1. ก่อนที่องค์ประกอบจะเริ่มเคลื่อนไหวให้เพิ่มคลาสที่กำหนด "-webkit-backface-visible: hidden;" ในองค์ประกอบ (คุณสามารถใช้รูปแบบอินไลน์ได้ฉันเดา)
  2. เมื่อทำแอนิเมชั่นเสร็จแล้วให้ลบคลาส (หรือสไตล์)

นี่ยังค่อนข้างแฮ็ก (ใช้คุณสมบัติ CSS3 เพื่อบังคับให้แสดงผลฮาร์ดแวร์) แต่อย่างน้อยก็มีผลกับองค์ประกอบที่เป็นปัญหาเท่านั้นและทำงานให้ฉันทั้งบนซาฟารีและโครมบนพีซีและ Mac


0

ดูเหมือนว่าจะเกี่ยวข้องกับสิ่งนี้: สไตล์ jQuery ไม่ถูกใช้ใน Safari

วิธีแก้ปัญหาที่แนะนำในการตอบกลับครั้งแรกได้ผลดีสำหรับฉันในสถานการณ์เหล่านี้กล่าวคือ: ใช้และลบคลาสหุ่นให้กับร่างกายหลังจากทำการเปลี่ยนแปลงสไตล์:

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

บังคับให้ซาฟารีวาดภาพใหม่


เพื่อให้มันใช้งานได้ใน Chrome ฉันต้องเพิ่ม: $ ('body'). addClass ('dummyclass'). delay (0) .removeClass ('dummyclass');
mbokil

0

คำแนะนำข้างต้นไม่ได้ผลสำหรับฉัน แต่ด้านล่างไม่

ต้องการเปลี่ยนข้อความภายในจุดยึดแบบไดนามิก คำว่า "ค้นหา" สร้างแท็ก "font" ด้านในด้วยแอตทริบิวต์ id จัดการเนื้อหาโดยใช้ javascript (ด้านล่าง)

ค้นหา

เนื้อหาของสคริปต์:

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

0

ฉันมีปัญหากับ SVG ที่หายไปบน Chrome สำหรับ Android เมื่อการวางแนวนั้นเปลี่ยนไปในบางสถานการณ์ รหัสด้านล่างไม่ได้ทำซ้ำ แต่เป็นการตั้งค่าที่เรามี

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>

ครึ่งวันต่อมาหลังจากการเจาะและการแหย่และไม่พอใจกับโซลูชันแฮ็คที่นำเสนอที่นี่ฉันค้นพบว่าปัญหาเกิดจากข้อเท็จจริงที่ว่ามันดูเหมือนจะเก็บองค์ประกอบในหน่วยความจำในขณะที่วาดใหม่ วิธีการแก้ปัญหาคือการสร้าง ID ของ linearGradient บน SVG ที่ไม่ซ้ำกันแม้ว่าจะเคยใช้เพียงครั้งเดียวต่อหน้า

สิ่งนี้สามารถทำได้หลายวิธี แต่สำหรับแอพเชิงมุมของเราเราใช้ฟังก์ชัน lodash uniqueId เพื่อเพิ่มตัวแปรในขอบเขต:

คำสั่งเชิงมุม (JS):

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

อัปเดต HTML:

บรรทัด 5: <linearGradient ng-attr-id="{{indicatorColourPatternId}}" x1="0" x2="0" y1="0" y2="1">

บรรทัด 11: <rect x="0" y="0" rx="5" ry="5" width="100%" height="100%" ng-attr-fill="url(#{{indicatorColourPatternId}})"/>

ฉันหวังว่าคำตอบนี้จะช่วยประหยัดแป้นพิมพ์ได้อย่างยอดเยี่ยม


0

ฉันจะแนะนำวิธีที่น้อย hackish และเป็นทางการมากขึ้นที่จะบังคับให้ reflow: ใช้forceDOMReflowJS ในกรณีของคุณรหัสของคุณจะมีลักษณะดังนี้

sel = document.getElementById('my_id');
forceReflowJS( sel );
return false;

0

ฉันพบว่าเพียงแค่เพิ่มสไตล์เนื้อหาให้กับองค์ประกอบบังคับให้ทาสีใหม่นี้ควรเป็นค่าที่แตกต่างกันทุกครั้งที่คุณต้องการให้วาดใหม่และไม่จำเป็นต้องอยู่ในองค์ประกอบหลอก

.selector {
    content: '1'
}

0

ฉันพยายามตอบคำถามอย่างไม่มั่นใจ แต่มันไม่ได้ผลสำหรับฉัน ฉันมีปัญหาในการมีลูกค้าเดียวกันกับซาฟารีเมื่อเทียบกับเบราว์เซอร์อื่น ๆ และรหัสนี้แก้ไขปัญหา:

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

มันแปลกจริงๆเพราะถ้าฉันลองอีกครั้งเพื่อรับลูกค้ากว้างหลังจาก get_safe_value ฉันได้รับค่าที่ไม่ดีกับซาฟารีผู้ทะเยอทะยานต้องอยู่ระหว่างsty.transform = "translateZ(1px)"; และsty.transform = "";

โซลูชันอื่น ๆ ที่ใช้งานได้อย่างแน่นอนคือ

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

ปัญหาคือคุณสูญเสียการโฟกัสและเลื่อน


0

สิ่งนี้จะบังคับให้วาดใหม่ในขณะที่หลีกเลี่ยงการกะพริบองค์ประกอบที่มีอยู่การเปลี่ยนแปลงและปัญหาการจัดวาง ...

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

-1

วิธีแก้ปัญหาง่ายๆด้วย jquery:

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

หรือ

element.innerHTML = element.innerHTML;

มี SVG ที่ไม่แสดงเมื่อเพิ่มลงใน html

สามารถเพิ่มได้หลังจากองค์ประกอบ svg อยู่บนหน้าจอ

ทางออกที่ดีกว่าคือการใช้:

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

และด้วย jQuery:

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

สิ่งนี้จะแสดงอย่างถูกต้องบน Chrome


ปัญหาเกี่ยวกับวิธีการนี้คือคุณหลวมตัวจัดการเหตุการณ์ใด ๆ ที่คุณได้ลงทะเบียนไว้ในวัตถุหรือลูกหลานของมัน
Haqa
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.