【问题标题】:JS to monitor the CSS property change like "display:none"=>"display:block"?JS 来监控 CSS 属性的变化,比如“display:none”=>“display:block”?
【发布时间】:2012-05-05 02:56:26
【问题描述】:

当图像的 CSS 属性“显示”已被任何其他 JS 脚本/函数更改时,我想运行一些 JS 代码。是否有任何方法可以监视该更改并设置回调函数?

$(this).bind.('propertychange', function(){}) 

不能这样做,setInterval 也是个坏主意。

还能做什么?

【问题讨论】:

  • 为什么不能覆盖/拦截其他 JS 函数,而不是搞乱对 CSS 属性更改的绑定?
  • @Jeff 感谢您的 cmets。原因是我无法更改他们的代码,或者他们的代码太复杂而无法更改。另一方面,在不同系统之间保持清洁是一种很好的做法。
  • 我理解(相信我),但您可以覆盖该函数,执行条件句柄,然后调用原始函数而不影响其他系统。我已经做了无数次了。

标签: javascript jquery css callback


【解决方案1】:

这就是你要找的东西:

document.documentElement.addEventListener('DOMAttrModified', function(e){
  if (e.attrName === 'style') {
    console.log('prevValue: ' + e.prevValue, 'newValue: ' + e.newValue);
  }
}, false);

【讨论】:

  • 太棒了!这就是我要找的。谢谢。
  • @Marian - 很好的解决方案,但我似乎无法让它在我的 Chrome 调试器中工作?你知道我可能会错过什么吗?我在您的个人资料图片上添加了一个 ID,并尝试使用 $('#testt').attr("style","display:none"); 隐藏该图片,但我没有看到任何日志语句。 “documentElement”是否应该是实际元素的占位符?您能否还包括一个更详细地描述这一点的链接?谢谢。
  • @marian-zburlea - 我得到了与 jmort253 相同的结果。此代码看起来仅适用于 Firefox,不适用于 Chrome。这是真的吗?
  • 另一种方法是使用 setInterval 并通过将默认值与当前值进行比较来监听属性更改,但这会消耗资源
【解决方案2】:

这是在您不想修改的旧 JavaScript 文件中:

// this is your original, unmodified function
function originalFunction(sel) {
    alert(sel);
    $(sel).css("display","none");
}

这在您的代码中:

// here is a sample callback function you pass into the extended function below
function myCallback(s) {
    alert("The image with src = '" + $(s).attr("src") + "' has been modified!");
}


// here is how you can extend the function to do what you want 
  // without needing to modify the actual code above
originalFunction = (function(legacyFn, callback) {

    // 1 arg function to be returned and reassigned to originalFunction
    return function(sel) {

        // call "original" originalFunction, with alert and image hide.
        legacyFn(sel);  

        if(callback) callback(sel);  // invoke your callback
    }

})(originalFunction, myCallback);

变量originalFunction 被分配了一个接受一个参数的函数。接受一个参数的函数由一个接受 2 个参数的匿名自执行函数返回,即在修改之前对 originalFunction 的引用和对 callback 函数的引用。这两个函数引用在闭包内被“锁定”,因此当 originalFunction 被自执行函数分配一个新值时,legacyFn 参数在修改之前仍然包含对 originalFunction 的引用.

综上所述,在更高的层次上,originalFunctionmyCallback作为参数传入自执行匿名函数并传入变量legacyFn和callback,然后将新函数分配给@987654331 @。

现在,当您调用originalFunction('.someClassOnAnImage') 时,legacyFn 将触发,这将提醒选择器并将显示属性设置为无。之后,回调函数(如果存在)将触发,然后您将看到:

The image with src = '.someClassOnAnImage' has been modified!

虽然这不如假设的或特定于平台的 addEventListener 好,但它确实允许您修改遗留代码中函数的行为,而无需物理破解打开这些文件并修改它们。这只是扩展功能以执行其他行为,但无需为此修改原始功能甚至原始文件。

您可以将所有扩展巧妙地包含在一个单独的 JavaScript 文件(或您正在使用的任何 JavaScript 文件)中,如果您想恢复原始行为,只需删除扩展函数即可。

【讨论】:

  • 是的。这是一个有用的答案,但对我不起作用。因为这个解决方案有两个条件。第一:它们的功能不应该是匿名的,而是命名的(即使在全局名称空间中)。第二:我必须知道所有改变了 CSS 的函数的名称(可能不止一个函数)。这些条件使该解决方案与它们的代码和逻辑混合在一起。一旦他们更改了代码,我们就必须更新此代码。谢谢你的帮助。 :)
  • 好点!有趣的是你提到这一点。我实际上不得不回去重构我的一些方法,以便为它们命名。虽然我认为这对我和我的场景来说是一个很好的实践,但我可以看到这个解决方案如何在您的特定场景中受到限制。感谢您的跟进!
【解决方案3】:

答案:查看其他帖子>>is there an alternative to DOMAttrModified that will work in webkit

咆哮: DOM Mutation 事件是解决问题的关键。然而,在新一波的浏览器大战中,Wekit 和 Gecko 不能在事情上达成一致。虽然 Gecko 有 DOMAttrModified,但 webkit 有一个叫做突变观察者的东西(它打破了事件处理程序附加到事件的模式,但是当我们想要锁定用户/编码器时,谁关心一致性?;)

P.S:这里只是为未来具有相同智慧的寻求者添加这个。

【讨论】:

    【解决方案4】:

    根据 Jeff 的建议,我建议编写一个修改图像样式属性的函数,然后将该函数用作所有其他函数必须通过才能修改该图像样式属性的瓶颈。

    function showImage(selector, callback) {
        $(selector).css("display","block");
        if(callback)
            callback();
    }
    
    function hideImage(selector, callback) {
        $(selector).css("display","none");
        if(callback)
            callback();
    }
    

    当您必须更改图像 CSS 属性时,可以从 JavaScript 中的任何位置调用上述两个函数。这些函数还接受一个函数作为参数,假设该函数作为第二个参数传入,之后将执行该函数。

    您可以将其进一步简化为一个函数,但我将把它留给您,因为我不知道您这样做的确切目标。

    【讨论】:

    • 此方法有效。但我想知道我们是否可以在不更改其他代码的情况下解决此问题。谢谢。
    猜你喜欢
    • 2022-11-20
    • 2013-09-19
    • 2021-09-30
    • 1970-01-01
    • 1970-01-01
    • 2019-08-26
    • 2017-05-16
    • 2021-11-28
    相关资源
    最近更新 更多