[javascript] 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');


답변

최근에이 문제가 발생 하여 translateZ 를 사용하여 영향을받는 요소를 컴포지트 레이어 로 승격하면 추가 자바 스크립트가 없어도 문제가 해결 되는 것으로 나타났습니다 .

.willnotrender { 
   transform: translateZ(0); 
}

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


답변

타임 아웃이없는이 솔루션! 진짜 힘을 다시 그리기! Android 및 iOS 용

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


답변

이것은 나를 위해 작동합니다. 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);