“禁用”使用Angular材料的ngAria

“禁用”使用Angular材料的ngAria

问题描述:

我正在开发一个在SharePoint 2013中托管的Angular应用程序,并且(我认为)运行时遇到ngAria$ariaProvider的问题。“禁用”使用Angular材料的ngAria

问题是,当我点击链接打开<md-dialog>元素作为模式时,UI线程被锁定了大约30-40秒。通过调试,我可以将其追踪到一种方法,该方法包含在Angular Material .js中,名为walkDOM(element)

该应用程序在本地工作正常(无SharePoint),但挂在SharePoint环境内。我认为这种方法是有问题的,因为它在SharePoint中遍历的DOM树明显大于开发中的DOM树。在模态打开事件触发后,将触发walkDOM()方法,并向大多数DOM元素添加aria-hidden="true"值。由于SharePoint具有复杂的DOM结构,我认为这会导致挂断。我能够调试并看到断点连续发射。我还可以看到,这些属性是在挂断后添加的,而不是预先存在的。

我想禁用此遍历,但到目前为止还没有找到一个可接受的方式来这样做。我遵循这个线程,并认识到我可能无法访问我感兴趣的方法:https://github.com/angular/material/issues/600。我知道禁用Aria是不好的做法,但我只是试图阻止导致UI线程被锁定很长一段时间的DOM遍历。我曾尝试下面的代码覆盖/配置晓月成分为角应用程序(在此线程建议后者片段:How do I disable ngAria in ngMaterial?):

angular 
.module('app', ['ui.router', 'ngMaterial', 'ngAria']) 
... 
.config(function ($ariaProvider) { 
    $ariaProvider.config({ 
    ariaValue: true, 
    ariaHidden: false, 
    tabindex: false 
    }); 
}) 
.decorator('$mdAria', function mdAriaDecorator($delegate) { 
    $delegate.expect = angular.noop; 
    $delegate.expectAsync = angular.noop; 
    $delegate.expectWithText = angular.noop; 
    return $delegate; 
}); 

有没有什么方法可以让我做什么,我试图做的?如果可能,我想避免重写应用程序不使用模态。我想过写一个全球性的walkDOM()方法,但没有成功。

任何帮助将不胜感激。谢谢!

编辑:这是一个问题,aria属性被添加到DOM结构的方式和walkDOM()方法的工作方式。这与本问题中解决的路由/模型状态管理无关:How to prevent view redraw when changing route in AngularJS

+0

[walkDom](http://www.javascriptcookbook.com/article/Traversing-DOM-subtrees-with-a-recursive-walk-the -DOM-function /)是Doug(AFAIK)的DOM遍历函数。不要弄乱它,因为它也可能来自其他地方。你有没有参考ngMaterial中实现walkDOM的任何代码? – sabithpocker

+0

@sabithpocker我看着的方法看起来像是专门用于对话的:https://github.com/angular/material/blob/fc7e9b3fc87713c6fde3b82c0df358650ec9aafc/src/components/dialog/dialog.js – awh112

+0

感谢评论@PaulSweatte,但我认为您发布的链接与我遇到的问题不同。我在上面遇到的问题是Angular Material代码以及它如何遍历大型DOM结构的问题。 – awh112

使用吸气剂拦截walkDOM内部的parentNode属性检查。例如:

function getter() 
 
    { 
 
    return document.documentElement; 
 
    } 
 

 
function isNodeOneOf(elem, nodeTypeArray) 
 
    { 
 
    if (nodeTypeArray.indexOf(elem.nodeName) !== -1) 
 
    { 
 
    return true; 
 
    } 
 
    } 
 

 
function walkDOM(element) 
 
    { 
 
    var isHidden; 
 
    var children = element.parentNode.children; 
 

 
    console.log(Date() + element.innerText); 
 
    
 
    while (element.parentNode) 
 
    { 
 
    if (element === document.body) 
 
     { 
 
     console.log(Date()); 
 
     return; 
 
     } 
 
    
 
    
 
    for (var i = 0; i < children.length; i++) 
 
     { 
 
     console.log(Date()); 
 
    // skip over child if it is an ascendant of the dialog 
 
    // or a script or style tag 
 
     if (element !== children[i] && 
 
     !isNodeOneOf(children[i], ['SCRIPT', 'STYLE']) 
 
     ) 
 
     { 
 
     children[i].setAttribute('aria-hidden', isHidden); 
 
     } 
 
     } 
 

 
    walkDOM(element = element.parentNode); 
 
    } 
 
    } 
 

 
Object.defineProperty(HTMLElement.prototype, 'parentNode', 
 
         { get: getter }); 
 

 
walkDOM(document.getElementById("foo"));
<section> 
 
    <p> 
 
    <span> 
 
     <a> 
 
     <strong> 
 
      <span id="foo">Hi</span> 
 
     </strong> 
 
     </a> 
 
    </span> 
 
    </p> 
 
</section>

在上述背景下,getter是:

其用作属性的吸气剂,或未定义如果没有吸气剂的功能。函数返回值将用作属性的值。

参考