未捕获的类型错误:无法读取 null 的属性“querySelectorAll”

Posted

技术标签:

【中文标题】未捕获的类型错误:无法读取 null 的属性“querySelectorAll”【英文标题】:uncaught typeError: cannot read property 'querySelectorAll' of null 【发布时间】:2015-08-19 19:29:33 【问题描述】:

我正在尝试在网站上将此菜单用于移动设备。 http://tympanus.net/codrops/2013/08/13/multi-level-push-menu/comment-page-8/#comment-466199

我有它的工作,但一个 ie11 用户报告错误,我在控制台中看到以下错误 未捕获的类型错误:无法读取 nullmlPushMenu._init @ mlpushmenu.js:89mlPushMenu @ mlpushmenu.js:67(匿名函数)@(索引)的属性“querySelectorAll”:1062

这里是有问题的js文件的sn-p

function mlPushMenu( el, trigger, options )    
    this.el = el;
    this.trigger = trigger;
    this.options = extend( this.defaults, options );
    // support 3d transforms
    this.support = Modernizr.csstransforms3d;
    if( this.support ) 
        this._init();
    


mlPushMenu.prototype = 
    defaults : 
        // overlap: there will be a gap between open levels
        // cover: the open levels will be on top of any previous open level
        type : 'overlap', // overlap || cover
        // space between each overlaped level
        levelSpacing : 40,
        // classname for the element (if any) that when clicked closes the current level
        backClass : 'mp-back'
    ,
    _init : function() 
        // if menu is open or not
        this.open = false;
        // level depth
        this.level = 0;
        // the moving wrapper
        this.wrapper = document.getElementById( 'mp-pusher' );
        // the mp-level elements
        this.levels = Array.prototype.slice.call( this.el.querySelectorAll( 'div.mp-level' ) );
        // save the depth of each of these mp-level elements
        var self = this;
        this.levels.forEach( function( el, i )  el.setAttribute( 'data-level', getLevelDepth( el, self.el.id, 'mp-level' ) );  );
        // the menu items
        this.menuItems = Array.prototype.slice.call( this.el.querySelectorAll( 'li' ) );
        // if type == "cover" these will serve as hooks to move back to the previous level
        this.levelBack = Array.prototype.slice.call( this.el.querySelectorAll( '.' + this.options.backClass ) );
        // event type (if mobile use touch events)
        this.eventtype = mobilecheck() ? 'touchstart' : 'click';
        // add the class mp-overlap or mp-cover to the main element depending on options.type
        classie.add( this.el, 'mp-' + this.options.type );
        // initialize / bind the necessary events
        this._initEvents();
    ,

特定的第 89 行位于其中间,因此在此处将其拉出以供您定位

this.levels = Array.prototype.slice.call( this.el.querySelectorAll( 'div.mp-level' ) );

然后我在页脚中调用了插件的实例(即索引行 1082

那个调用看起来像这样

<script>
    new mlPushMenu(
        document.getElementById( 'mp-menu' ),
        document.getElementById( 'trigger' ),
         type : 'cover' 
    );
</script>

【问题讨论】:

new mlPushMenu 被调用时,你肯定#mp-menu 存在,对吗?另外,Internet Explorer 处于哪种文档模式?您可以通过按 F12 并在 Emulation 面板中记下所选模式或将 document.documentMode 插入控制台来轻松确定这一点。我怀疑问题是该元素尚未创建,或者 IE 已滑入不支持 querySelectorAll 的早期模式。 其实是相反的方向。当我在边缘运行 ie 和 10 时,它会在控制台中引发错误。当我以 9 或更低的速度运行时,它不会。但在 8 或更低版本中,它确实显示了移动菜单。我在页脚中有新的 mlPushMenu 脚本,它应该已经存在。你将不得不原谅我的无知,JS不是我的驾驶室。 你能把你的网页放到网上直接访问吗?或者,更好的是,将演示/示例上传到不会很快改变的 URL(为了将来可能遇到此问题的其他人)。 所以该网站目前在这里proficientrx.com 并且应该至少保留一年左右。您将不得不模糊代码。该网站是一个真正的黑客工作,但我是新来的,所以对我来说放轻松。我已将其缩小到仅在 I.E. 7 及以下。现在我只需要说服客户忽略这个问题。 是的,我明白你在说什么。所以我所做的不是调用任何 JS 文件,除非 mobile_detect 捡起它并解决它。现在错误消失了。非常感谢您对乔纳森的所有帮助。你很棒! :) 【参考方案1】:

您的桌面网站没有 ID 为“mp-menu”的元素。当您调用 getElementById 方法时,您会收到 null 作为响应。然后将其分配给对象的el 属性。当您尝试调用 querySelectorAll 时,您是在尝试从空值执行此操作。

根据上述问题的 cmets,mp-menu 元素仅存在于 移动网站 上。如果是这种情况,此代码也应该仅在移动设备上加载

【讨论】:

这正是答案,是的!【参考方案2】:

问题是 JS 文件在所有平台、桌面和移动设备上都被调用。而使用 mlPushMenu 的移动菜单仅在移动设备上调用。使其仅在移动设备上调用 JS 文件解决了桌面浏览器的问题。

【讨论】:

以上是关于未捕获的类型错误:无法读取 null 的属性“querySelectorAll”的主要内容,如果未能解决你的问题,请参考以下文章

未捕获的类型错误:无法读取 null 的属性“getContext”

为啥我会收到此错误:未捕获的类型错误:无法读取 null 的属性 'classList'

未捕获的类型错误:在输入单击时无法读取 null 的属性“样式”

如何修复未捕获的类型错误:无法读取 null 的属性“值”

未捕获的类型错误:无法读取 null 的属性“innerHTML”

未捕获的类型错误:无法在方法中读取 null 的属性“classList”