未定义的ReferenceError MutationObserver未定义

时间:2014-07-21 13:55:18

标签: javascript jquery jquery-mobile knockout.js jquery-mobile-collapsible

我正在使用JQuery mobile expandable listKnockout.js组合的网页。我编写的机制允许构建ViewModel树结构并将其绑定到可扩展列表。由于某些treenode可能很大,我使用了koncokout :if绑定,因此节点在扩展之前不会被渲染(在第一页上加载完整模型,但只渲染了20条记录)。当孩子的孩子仍然打开并且模型不同步时(在重新开放的父节点上,孩子的孩子将根据他们从未被关闭的模型被隐藏),有时我遇到父节点被关闭的问题。因此,如果节点被蒸发,我已经使用MutationObservable来处理这些情况。从DOM树到该节点的所有子节点的模型设置为关闭。

function ShowChildren(data, element) {
   if (data.IsExpanded != undefined) {
      data.IsExpanded(!data.IsExpanded());
      if (data.IsExpanded()) {
         var childContentElements = $(element).parent().find('.ui-collapsible-content');
         childContentElements.attr('data-bind','visible : $parent.IsExpanded != undefined && $parent.IsExpanded()');
         AttachVisibilityChangedEventHandler({ targets: childContentElements, eventHandler: VisibilityChangedEventHandler });
         $.each(childContentElements, function (i, item) { item.addEventListener('DOMNodeRemovedFromDocument', TreeNodeClosedEventHandler); });
         $("[data-role='none']").attr('data-role','collapsible');
         $("[data-role='collapsible-set'][data-onthemovedatasourceid='bcAccount']").trigger('create');
         OnCollapsibleSetCreateJQueryMobileUI(element);
         $.each($.grep($(element).parent().parent().find(">[data-role='collapsible']").find(">.ui-collapsible-content:not(.ui-collapsible-content-collapsed)").siblings(), function (item) { return element != item; }), function (i, item) { $(item).find('>a').click(); });
      }
   }
}

function OnCollapsibleSetCreateJQueryMobileUI(element) {
   $(element).parent().parent().parent().parent().find('>h3>a').removeClass('ui-corner-bottom');
   $(element).parent().find('>.ui-collapsible-content').removeClass('ui-corner-bottom');
}

function ColapseAllSiblings(parent, id) {
   if (parent.Children != undefined) {
       for (var i = 0; i < parent.Children.length; i++) {
           if (parent.Children[i]['Id'] != id) {
               if (parent.Children[i].IsExpanded != undefined && parent.Children[i].IsExpanded()) {
                   parent.Children[i].IsExpanded(false);
                   ColapseAllChildren(parent.Children[i]);
                }
           }
       }
   }
}

function ColapseAllChildren(data) {
   if (data.Children != undefined) {
       for (var i = 0; i < data.Children.length; i++) {
           if (data.Children[i].IsExpanded != undefined && data.Children[i].IsExpanded()) {
               data.Children[i].IsExpanded(false);
               ColapseAllChildren(data.Children[i]);
           }
       }
   }
}

function AttachVisibilityChangedEventHandler(options) {
   var targets = options.targets ? options.targets : $(options.selector);
   $.each(targets, function (i, target) {
       target.addEventListener('visibilityChanged', options.eventHandler, false);
       PageObj.VisibilityObserver.observe(target, { attributes: true, attributeFilter: ['class'], childList: false, attributeOldValue: true });
   });
}

function VisibilityChangedEventHandler() {
   var knockoutContext = ko.contextFor(this);
   if (!$(this).is(':visible')){
       if (knockoutContext.$parents.length > 2) {
           ColapseAllChildren(knockoutContext.$data);
       } else {
           ColapseAllChildren(knockoutContext.$parents[0]);
       }
    } else {
        if (knockoutContext.$parents.length > 2) {
           var recordId = typeof knockoutContext.$data.Id == 'function' ? knockoutContext.$data['Id']() : knockoutContext.$data['Id'];
           if (knockoutContext.$parents.length > 3) {
               ColapseAllSiblings(knockoutContext.$parents[0], recordId);
           } else {
               ColapseAllSiblings(knockoutContext.$parents[1], recordId);
           }
       }
   }
}

$(onTheMove.PageDataRoles).on('OnRender', function () {
   $('.AppletBase >.ui-collapsible-content').attr('data-bind','visible : $parent.IsExpanded != undefined && $parent.IsExpanded()');
      PageObj.VisibilityObserver = new MutationObserver(function (mutations) {
          var clone = $(mutations[0].target).clone();
          clone.removeClass();
          for (var i = 0; i < mutations.length; i++) {
              clone.addClass(mutations[i].oldValue);
          }
          $(document.body).append(clone);
          var cloneVisibility = $(clone).is(":visible");
          $(clone).remove();
          if (cloneVisibility != $(mutations[0].target).is(":visible")) {
              var visibilityChangedEvent = document.createEvent('Event');
              visibilityChangedEvent.initEvent('visibilityChanged', false, true);
              mutations[0].target.dispatchEvent(visibilityChangedEvent);
          }
      });
      AttachVisibilityChangedEventHandler({ selector: '.ui-collapsible-content', eventHandler: VisibilityChangedEventHandler });
});

function TreeNodeClosedEventHandler(e) {
   ColapseAllChildren(ko.contextFor(e.target).$data);
}

这一切都适用于所有主流浏览器的所有最新版本,因此项目继续实施此机制。直到我们选择了不支持Android Browser 4的{​​{1}}提交的三星,这是一个必须&#39;}我们的一位客户。
我可以采用什么替代机制代替MutationObservable所以我不需要重写整个事情?或任何其他不需要完全重写的解决方案。

0 个答案:

没有答案