programing

Chrome / Mac에서 DOM 다시 그리기 / 새로 고침

new-time 2020. 5. 5. 21:28
반응형

Chrome / Mac에서 DOM 다시 그리기 / 새로 고침


때때로 Chrome은 완벽하게 유효한 HTML / CSS를 잘못 렌더링하거나 전혀 렌더링하지 않습니다. DOM 인스펙터를 파는 것만으로도 길을 잘못 인식하고 올바르게 다시 그리기에 충분하기 때문에 마크 업이 좋은 경우 일 수 있습니다. 이것은 내가 작업중 인 프로젝트에서 특정 상황에서 다시 그리기를 강제로 적용하는 코드에서 자주 (그리고 예측 가능하게) 충분히 발생합니다.이것은 대부분의 브라우저 / OS 조합에서 작동합니다 :

    el.style.cssText += ';-webkit-transform:rotateZ(0deg)'
    el.offsetHeight
    el.style.cssText += ';-webkit-transform:none'

에서와 같이 사용하지 않는 CSS 속성을 조정 한 다음 다시 그리기를 강제로 수행하는 정보를 요청한 다음 속성을 해제하십시오. 불행히도, Mac 용 Chrome의 밝은 팀은 다시 그릴 필요없이 offsetHeight를 얻는 방법을 찾았습니다. 따라서 다른 유용한 해킹을 제거하십시오.지금까지 Chrome / Mac에서 동일한 효과를 얻는 데 가장 좋은 것은이 추악한 것입니다.

    $(el).css("border", "solid 1px transparent");
    setTimeout(function()
    {
        $(el).css("border", "solid 0px transparent");
    }, 1000);

마찬가지로 실제로 요소가 약간 점프하도록 한 다음 잠시 차갑게하고 다시 점프하십시오. 설상가상으로 타임 아웃을 500ms 미만으로 떨어 뜨리면 (눈에 띄지 않을 정도로), 브라우저가 원래 상태로 돌아 가기 전에 다시 그리기를하지 않기 때문에 원하는 효과를 얻지 못하는 경우가 많습니다.누구나 Chrome / Mac에서 작동하는이 다시 그리기 / 새로 고침 해킹 (위의 첫 번째 예를 기반으로 함)의 더 나은 버전을 제공하려고합니까?


정확히 무엇을 달성하려고하는지 확실하지 않지만 이것은 브라우저에서 다시 그리기를 강제하기 위해 과거에 내가 사용한 방법입니다. 아마도 당신에게 도움이 될 것입니다.

// in jquery
$('#parentOfElementToBeRedrawn').hide().show(0);

// in plain js
document.getElementById('parentOfElementToBeRedrawn').style.display = 'none';
document.getElementById('parentOfElementToBeRedrawn').style.display = 'block';

이 간단한 다시 그리기가 작동하지 않으면 시도해보십시오. 빈 텍스트 노드를 요소에 삽입하여 다시 그리기를 보장합니다.

var forceRedraw = function(element){

    if (!element) { return; }

    var n = document.createTextNode(' ');
    var disp = element.style.display;  // don't worry about previous display style

    element.appendChild(n);
    element.style.display = 'none';

    setTimeout(function(){
        element.style.display = disp;
        n.parentNode.removeChild(n);
    },20); // you can play with this timeout to make it as short as possible
}

편집 : Šime Vidas에 대한 응답으로 우리가 여기서 달성 한 것은 강제 리플 로우입니다. 마스터 자신에게서 더 많은 것을 알 수 있습니다

http://paulirish.com/2011/dom-html5-css3-performance/


위의 답변 중 어느 것도 나를 위해 일하지 않았습니다.

크기

조정 하면 다시 그리기가 발생 했음을 알았습니다 . 그래서 이것은 나를 위해 그것을했습니다 :

$(window).trigger('resize');

타임 아웃이없는이 솔루션! 진짜

힘을

다시 그리기! Android 및 iOS 용

var forceRedraw = function(element){
  var disp = element.style.display;
  element.style.display = 'none';
  var trick = element.offsetHeight;
  element.style.display = disp;
};

최근에이 문제가 발생 하여 translateZ 를 사용하여 영향을받는 요소를

컴포지트 레이어

승격하면 추가 자바 스크립트가 없어도 문제가 해결 되는 것으로 나타났습니다 .

.willnotrender { 
   transform: translateZ(0); 
}

이러한 페인팅 문제는 주로 Webkit / Blink에 표시되며이 수정은 대부분 Webkit / Blink를 대상으로하기 때문에 경우에 따라 선호됩니다. 특히 많은 JavaScript 솔루션이 리 페인팅 뿐만 아니라

리플 로우 및 리 페인트를

유발하기 때문에 .


이것은 나를 위해 작동합니다.

Kudos는 여기에 간다

.

jQuery.fn.redraw = function() {
    return this.hide(0, function() {
        $(this).show();
    });
};

$(el).redraw();

요소를 숨기고 setTimeout 0 내에 다시 표시하면 다시 그리기가 수행됩니다.

$('#page').hide();
setTimeout(function() {
    $('#page').show();
}, 0);

이것은 나를 위해 속임수를 쓰는 것 같습니다. 또한 실제로 전혀 표시되지 않습니다.

$(el).css("opacity", .99);
setTimeout(function(){
   $(el).css("opacity", 1);
},20);

window.getComputedStyle()

리플 로우


오늘 Chrome v51을 사용하는 OSX El Capitan에서이 문제에 부딪 쳤습니다. 해당 페이지는 Safari에서 정상적으로 작동했습니다. 나는이 페이지에서 거의 모든 제안을 시도했다. 아무 것도 효과가 없었다. 모두 부작용이 있었다. 나는 아래 코드를 구현했다. 슈퍼 간단하고 부작용이 없다.솔루션 : 필요에 따라 문제가있는 요소에서 클래스를 전환하십시오. 각 토글은 강제로 다시 그립니다. (편의를 위해 jQuery를 사용했지만 바닐라 JavaScript는 문제가되지 않습니다 ...)jQuery 클래스 토글

$('.slide.force').toggleClass('force-redraw');

CSS 클래스

.force-redraw::before { content: "" }

그리고 그게 다야...참고 : 효과를 보려면 "전체 페이지"에서 스 니펫을 실행해야합니다.

 

$(window).resize(function() {
  $('.slide.force').toggleClass('force-redraw');
});
.force-redraw::before {
  content: "";
}
html,
body {
  height: 100%;
  width: 100%;
  overflow: hidden;
}
.slide-container {
  width: 100%;
  height: 100%;
  overflow-x: scroll;
  overflow-y: hidden;
  white-space: nowrap;
  padding-left: 10%;
  padding-right: 5%;
}
.slide {
  position: relative;
  display: inline-block;
  height: 30%;
  border: 1px solid green;
}
.slide-sizer {
  height: 160%;
  pointer-events: none;
  //border: 1px solid red;

}
.slide-contents {
  position: absolute;
  top: 10%;
  left: 10%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p>
  This sample code is a simple style-based solution to maintain aspect ratio of an element based on a dynamic height.  As you increase and decrease the window height, the elements should follow and the width should follow in turn to maintain the aspect ratio.  You will notice that in Chrome on OSX (at least), the "Not Forced" element does not maintain a proper ratio.
</p>
<div class="slide-container">
  <div class="slide">
    <img class="slide-sizer" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">
    <div class="slide-contents">
      Not Forced
    </div>
  </div>
  <div class="slide force">
    <img class="slide-sizer" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">
    <div class="slide-contents">
      Forced
    </div>
  </div>
</div>

 


function resizeWindow(){
    var evt = document.createEvent('UIEvents');
    evt.initUIEvent('resize', true, false,window,0);
    window.dispatchEvent(evt); 
}

500 밀리 초 후에이 함수를 호출하십시오.


스타일 시트에 선언 된 스타일을 유지하려면 다음과 같은 것을 사용하는 것이 좋습니다.

jQuery.fn.redraw = function() {
    this.css('display', 'none'); 
    var temp = this[0].offsetHeight;
    this.css('display', '');
    temp = this[0].offsetHeight;
};

$('.layer-to-repaint').redraw();

NB : 최신 웹킷 / 블링크에서는

offsetHeight

다시 그리기를 트리거하기 위해 값을 저장해야합니다 . 그렇지 않으면 VM (최적화 목적으로)이 해당 명령을 생략합니다.

Update: added the second offsetHeight reading, it is necessary to prevent browser from queueing/caching a following CSS property/class change with the restore of the display value (this way a CSS transition that can follow should be rendered)


Sample Html:

<section id="parent">
  <article class="child"></article>
  <article class="child"></article>
</section>

Js:

  jQuery.fn.redraw = function() {
        return this.hide(0,function() {$(this).show(100);});
        // hide immediately and show with 100ms duration

    };

call function:

$('article.child').redraw();

//<==bad idea

$('#parent').redraw();

An approach that worked for me on IE (I couldn't use the display technique because there was an input that must not loose focus)

It works if you have 0 margin (changing the padding works as well)

if(div.style.marginLeft == '0px'){
    div.style.marginLeft = '';
    div.style.marginRight = '0px';
} else {
    div.style.marginLeft = '0px';
    div.style.marginRight = '';
}

CSS only. This works for situations where a child element is removed or added. In these situations, borders and rounded corners can leave artifacts.

el:after { content: " "; }
el:before { content: " "; }

My fix for IE10 + IE11. Basically what happens is that you add a DIV within an wrapping-element that has to be recalculated. Then just remove it and voila; works like a charm :)

    _initForceBrowserRepaint: function() {
        $('#wrapper').append('<div style="width=100%" id="dummydiv"></div>');
        $('#dummydiv').width(function() { return $(this).width() - 1; }).width(function() { return $(this).width() + 1; });
        $('#dummydiv').remove();
    },

Most answers require the use of an asynchroneous timeout, which causes an annoying blink.

But I came up with this one, which works smoothly because it is synchroneous:

var p = el.parentNode,
    s = el.nextSibling;
p.removeChild(el);
p.insertBefore(el, s);

This is my solution that worked for disappearing content...

<script type = 'text/javascript'>
    var trash_div;

    setInterval(function()
    {
        if (document.body)
        {
            if (!trash_div)
                trash_div = document.createElement('div');

            document.body.appendChild(trash_div);
            document.body.removeChild(trash_div);
        }
    }, 1000 / 25); //25 fps...
</script>

I ran into a similar issue and this simple line of JS helped to fix it:

document.getElementsByTagName('body')[0].focus();

In my case it was a bug with a Chrome extension not redrawing the page after changing its CSS from within the extension.


I wanted to return all the states to the previous state (without reloading) including the elements added by jquery. The above implementation not gonna works. and I did as follows.

// Set initial HTML description
var defaultHTML;
function DefaultSave() {
  defaultHTML = document.body.innerHTML;
}
// Restore HTML description to initial state
function HTMLRestore() {
  document.body.innerHTML = defaultHTML;
}



DefaultSave()
<input type="button" value="Restore" onclick="HTMLRestore()">

I had a react component list which when scrolled, then opened another page, then when returning back the list was not rendered on Safari iOS until page was scrolled. So this is the fix.

    componentDidMount() {
        setTimeout(() => {
            window.scrollBy(0, 0);
        }, 300);
    }

Below css works for me on IE 11 and Edge, no JS needed. scaleY(1) does the trick here. Seems the simplest solution.

.box {
    max-height: 360px;
    transition: all 0.3s ease-out;
    transform: scaleY(1);
}
.box.collapse {
    max-height: 0;
}

참고URL : https://stackoverflow.com/questions/8840580/force-dom-redraw-refresh-on-chrome-mac

반응형