2016-09-16 67 views
2

我正在開發一個在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

回答

0

使用吸氣劑攔截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是:

其用作屬性的吸氣劑,或未定義如果沒有吸氣劑的功能。函數返回值將用作屬性的值。

參考