簡體   English   中英

DOM元素的計算樣式更改時觸發事件?

[英]Fire an event when DOM element's computed style changes?

是否有非輪詢方法來偵聽元素的計算樣式的更改?

這個幻想代碼段應該簡潔地解釋我的意思:

var el = document.getElementById('doodad');

el.addComputedStyleChangeListener('width', function (prev, new) {
  alert('Previous width: ' + prev + '; New width: ' + new);
});

我知道DOMAttrModified突變事件和即將到來的MutationObserver ,但這還不夠-它們只能用於監視元素的style DOM屬性,這不能完全確定元素的計算風格。


這個用例原本是這個問題的一部分,這確實使我產生了好奇心。

沒有這種方法。 CSS OM還不存在。

尚不清楚“計算樣式更改”是什么意思。

原則上,您可以檢測所用(例如渲染)樣式的更改。 但這需要發生“繪畫”或“布局”之類的事件。

您目前能做的最好的就是請求動畫幀。

getComputedStyle顯然返回了一個計算屬性的實時更新對象。

您可以像這樣進行基本的動畫循環:

var computedStyle = getComputedStyle(element);
var animate = function () {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = computedStyle.color;
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    requestAnimationFrame(animate);
};
animate();

如果任何使用的屬性已更改,則可能僅通過更新來進行優化:

var computedStyle = getComputedStyle(element);
var lastFrameBackground;
var lastFrameColor;
var animate = function () {
    if (
        computedStyle.background !== lastFrameBackground ||
        computedStyle.color !== lastFrameColor
    ) {
       lastFrameBackground = computedStyle.background;
       lastFrameColor = computedStyle.color;

       // assuming expensive drawing code here
       // not like this!
       ctx.clearRect(0, 0, canvas.width, canvas.height);
       ctx.fillStyle = computedStyle.color;
       ctx.fillRect(0, 0, canvas.width, canvas.height);
    }
    requestAnimationFrame(animate);
};
animate();

如果是針對特定CSS動畫的,則可以通過偵聽animationstartanimationend管理requestAnimationFrame循環,或者如果這些事件沒有足夠的瀏覽器支持,則可以在知道動畫將要開始時將其啟動(例如, mouseenter for :hover ),並在動畫屬性的計算值停止更改時停止(即,如果它等於其先前值,則不調用requestAnimationFrame )。

如果您不需要平滑地設置動畫效果,則可以使用setInterval以獲得更好的性能(檢查是否隱藏了requestAnimationFrame隱式requestAnimationFrame的文檔):

var computedStyle = getComputedStyle(element);
setInterval(function () {
    if (!document.hidden) {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = computedStyle.color;
        ctx.fillRect(0, 0, canvas.width, canvas.height);
    }
}, 200);

暫無
暫無

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

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