簡體   English   中英

我可以使用 javascript 強制瀏覽器“刷新”任何掛起的布局更改嗎?

[英]Can I use javascript to force the browser to “flush” any pending layout changes?

我有一個使用 Javascript 構建 UI 的庫,由於涉及到動態內容,我有時想將內容放到瀏覽器中,檢查如何更改布局以支持這一點,然后根據結果執行不同的邏輯。 例如:檢測某些文本是否溢出並用省略號截斷它。

通常我通過發布更改來實現這一點,然后使用 window.setTimeout(0) 等待布局更新並調用其余的邏輯。 這顯然是次優的,因為不同的瀏覽器可能會實現一個太慢而無法防止閃爍的最小超時,或者更快地使用大量 CPU。

理想情況下,我想做 DOM 更改,然后強制布局同步更新並立即內聯運行“修復”邏輯。 有任何想法嗎?

我的理解是讀取任何 CSS 屬性都會強制重排。 您根本不需要setTimeout

渲染摘錄:重繪、回流/重新布局、重新樣式

但有時腳本可能會阻止瀏覽器優化回流,並導致它刷新隊列並執行所有批量更改。 當您請求樣式信息時會發生這種情況,例如

 offsetTop, offsetLeft, offsetWidth, offsetHeight scrollTop/Left/Width/Height clientTop/Left/Width/Height getComputedStyle(), or currentStyle in IE

以上所有這些本質上都是請求有關節點的樣式信息,並且無論何時執行此操作,瀏覽器都必須為您提供最新的值。 為此,它需要應用所有計划的更改,刷新隊列,咬緊牙關並進行回流。

這是將觸發 reflow 的 API 調用/屬性列表

(這個答案曾經鏈接到一個現在 404 的網站。 這是回程機中的一個鏈接。)

我們在 IE8 上遇到了一個瘋狂的問題(Firefox、Chrome 都可以)。 我們在子元素上使用 toggleClass('enoMyAddressesHide') 。

.enoMyAddressesHide{display:none}

但是父 div 容器不會刷新/重新布局其高度。

setTimeout()、讀取位置、讀取元素的寬度和高度沒有幫助。 最后我們可以找到一個可行的解決方案:

jQuery(document).ready(function ($) {
    var RefreshIE8Layout = function () {
        $('.enoAddressBook:first').css('height', 'auto');
        var height = $('.enoAddressBook:first').height();
        $('.enoAddressBook:first').css('height', height);
    };

    $(".enoRowAddressInfo .enoRowAddressInfoArea ul li img.enoMyAddresses").click(function () {
        $(this).parent().find(".enoAllInfoInAddressBox,img.enoMyAddresses").toggleClass('enoMyAddressesHide');

        RefreshIE8Layout(); // fix IE8 bug, not refresh the DOM dimension after using jQuery to manipulate DOM
    });
});

它看起來很愚蠢,但它有效!

是的你可以!!

大多數瀏覽器通過將更改排隊並批量執行來優化回流過程。 刷新渲染樹更改需要您檢索一些布局信息(偏移計算、getComputedStyle() 和滾動值)。

var el = document.getElementById("my-element");
var top = el.offsetTop;

上面的代碼將強制瀏覽器在渲染隊列中執行更改以返回正確的值。

簡單的!!

我不知道這實際上適用於您的實施,但是:

var myDiv = document.getElementById("myDiv");
myDiv.innerHTML = "".concat(myDiv.innerHTML);

我相信設置 innerHTML 會強制為子元素重新加載 DOM。 我不知道如果你把這個范圍限定到整個網站會發生什么。 聽起來您已經很好地融入了 DOM,但這種方法可能會強制您已經創建的任何節點引用變為未定義。 換句話說:

var mySelect = document.getElementById("mySelect");// suppose this lives in myDiv.
var myDiv = document.getElementById("myDiv");
myDiv.innerHTML = "".concat(myDiv.innerHTML);

在上面的例子中,我相信你會失去對 mySelect 的引用。 如果你有很多這樣的事情發生並且你使用的是字段而不是 getter(即,每次訪問它時都沒有使用 $() 或 $get 或 document.getElementById(..) 獲取你關心的每個元素)然后這種類型的沖洗很有可能會讓你失望。

您也肯定會丟失任何您沒有手動跟蹤/設置的頁面狀態數據 - 帶有來自用戶的新文本的文本框,用戶新檢查的復選框等,將使用這種刷新方法重新初始化為其默認狀態。

祝你好運 - 編碼愉快!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM