“禁用”使用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。
使用吸气剂拦截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
是:
其用作属性的吸气剂,或未定义如果没有吸气剂的功能。函数返回值将用作属性的值。
参考
[walkDom](http://www.javascriptcookbook.com/article/Traversing-DOM-subtrees-with-a-recursive-walk-the -DOM-function /)是Doug(AFAIK)的DOM遍历函数。不要弄乱它,因为它也可能来自其他地方。你有没有参考ngMaterial中实现walkDOM的任何代码? – sabithpocker
@sabithpocker我看着的方法看起来像是专门用于对话的:https://github.com/angular/material/blob/fc7e9b3fc87713c6fde3b82c0df358650ec9aafc/src/components/dialog/dialog.js – awh112
感谢评论@PaulSweatte,但我认为您发布的链接与我遇到的问题不同。我在上面遇到的问题是Angular Material代码以及它如何遍历大型DOM结构的问题。 – awh112