webkitmutationobserver在Safari中不起作用?

时间:2012-06-12 00:23:27

标签: javascript safari webkit

我需要监视元素的显示状态。我正在使用以下代码

if WebKitMutationObserver?
    observer = new WebKitMutationObserver observerFunc
    observer.observe el, {attributes:true}
  else
    el.addEventListener "DOMAttrModified",(event)->
      wrapper.style.display = el.style.display
      return

但是这在Safari中不起作用。

此外,在Chrome中的开发人员工具即时窗口中键入“WebKitMutationObserver”会显示输出

function WebKitMutationObserver() { [native code] }

在Safari(v 5.1.7)中,这会给出消息错误     “找不到变量:WebKitMutationObserver”

可能是Safari不支持WebkitMutationObserver吗?如果是这样的话,有没有我可以使用的替代方案呢?

1 个答案:

答案 0 :(得分:1)

最新的Safari(6.0)确实包含WebKitMutationObserver。对于较旧的Safari,当您使用DOMAttrModifiedsetAttribute更改属性时,我们使用的一些代码会伪造removeAttribute事件。请注意,如果浏览器本身在内部更改属性,则此操作无效。

  var win = window;
  var doc = win.document;
  var attrModifiedWorks = false;
  var listener = function () { attrModifiedWorks = true; };
  doc.documentElement.addEventListener("DOMAttrModified", listener, false);
  doc.documentElement.setAttribute("___TEST___", true);
  doc.documentElement.removeAttribute("___TEST___", true);
  doc.documentElement.removeEventListener("DOMAttrModified", listener, false);
  if (!attrModifiedWorks)
  {
    This.DOMAttrModifiedUnsupported = true;

    win.HTMLElement.prototype.__setAttribute = win.HTMLElement.prototype.setAttribute;
    win.HTMLElement.prototype.setAttribute = function fixDOMAttrModifiedSetAttr (attrName, newVal)
    {
      var prevVal = this.getAttribute(attrName);
      this.__setAttribute(attrName, newVal);
      newVal = this.getAttribute(attrName);
      if (newVal != prevVal)
      {
        var evt = doc.createEvent("MutationEvent");
        evt.initMutationEvent
          ( "DOMAttrModified"
          , true
          , false
          , this
          , prevVal || ""
          , newVal || ""
          , attrName
          , (prevVal == null) ? win.MutationEvent.ADDITION : win.MutationEvent.MODIFICATION
          );
        this.dispatchEvent(evt);
      }
    }

    win.HTMLElement.prototype.__removeAttribute = win.HTMLElement.prototype.removeAttribute;
    win.HTMLElement.prototype.removeAttribute = function fixDOMAttrModifiedRemoveAttr (attrName)
    {
      var prevVal = this.getAttribute(attrName);
      this.__removeAttribute(attrName);
      var evt = doc.createEvent("MutationEvent");
      evt.initMutationEvent("DOMAttrModified", true, false, this, prevVal, "", attrName, win.MutationEvent.REMOVAL);
      this.dispatchEvent(evt);
    }
  }
}