使用MutationObserver时获取当前MutationRecord的新属性值吗?

问题描述 投票:0回答:2

我有一些类似以下的代码,

const observer = new MutationObserver(records => {
    for (const record of records) {
        if (record.type !== 'attributes') continue

        handleAttrChange(
            record.attributeName!,
            record.oldValue,
            record.target.attributes.getNamedItem(record.attributeName).value,
        )
    }
})

其中handleAttrChange参数是属性名称,旧值和新值。

但是,正如您所知,第三个参数传递给handleAttrChange

record.target.attributes.getNamedItem(record.attributeName!)!.value

始终将是最新的属性值,not我们正在迭代的特定突变记录的“新值”(即不是在发生突变的时间)。

我们如何获得每个突变的“新值”,就像在每个突变发生时所观察到的那样?

javascript html dom mutation-observers
2个回答
0
投票

我认为MutationObserver不可能。 MutationRecord中的任何内容都不会暴露新值,并且由于MuationObserver在微任务中运行,并且更改后未完全同步,因此可以从观察者回调内的元素检索的值可能已更改< [之后如您所见,触发观察者的更改。

const observer = new MutationObserver(records => { for (const record of records) { if (record.type !== 'attributes') continue console.log(div.dataset.foo); console.log(record); } }); observer.observe(div, { attributes: true }); div.setAttribute('data-foo', 'foo'); div.setAttribute('data-foo', 'bar');
<div id="div"></div>
虽然可以使用

synchronous

观察者(侦听元素上的DOMAttrModified事件),但不推荐使用它们,而且速度很慢。如果您知道如何更改属性,则可以修补该方法,以使其首先通过您的

own

逻辑。例如,使用setAttribute

div.setAttribute = (...args) => { console.log(`Setting ${args[0]} from ${div.getAttribute(args[0])} to ${args[1]}`); return HTMLElement.prototype.setAttribute.apply(div, args); }; div.setAttribute('data-foo', 'foo'); div.setAttribute('data-foo', 'bar');
<div id="div"></div>

0
投票
我们可以这样模拟:

const observer = new MutationObserver(records => { let lastAttributeValues = {} let name = '' for (const record of records) { if (record.type !== 'attributes') continue name = record.attributeName if (lastAttributeValues[name] === undefined) { lastAttributeValues[name] = record.oldValue continue } handleAttributeChange(name, lastAttributeValues[name], record.oldValue) lastAttributeValues[name] = record.oldValue } for (const name in lastAttributeValues) { handleAttributeChange(name, lastAttributeValues[name], el.attributes.getNamedItem(name).value) } })

它的作用是,因为我们知道我们可以按顺序获得突变,并且在迭代的过程中拥有给定属性的所有属性值,所以它仅跟踪先前和当前的属性值(按属性名称)并触发handleAttributeChange以及每个先前的值和当前值。
© www.soinside.com 2019 - 2024. All rights reserved.