“使用classList.add时,无法读取null的属性'classList'

时间:2015-04-29 11:16:42

标签: javascript twitter-bootstrap classiejs

我遇到此错误,但由于我不熟悉代码。它来自startbootstrap(Creative)中的主题。该文件是

  

classie.js

代码:

/*!
 * classie - class helper functions
 * from bonzo https://github.com/ded/bonzo
 * 
 * classie.has( elem, 'my-class' ) -> true/false
 * classie.add( elem, 'my-new-class' )
 * classie.remove( elem, 'my-unwanted-class' )
 * classie.toggle( elem, 'my-class' )
 */

/*jshint browser: true, strict: true, undef: true */
/*global define: false */

( function( window ) {

'use strict';

// class helper functions from bonzo https://github.com/ded/bonzo

function classReg( className ) {
  return new RegExp("(^|\\s+)" + className + "(\\s+|$)");
}

// classList support for class management
// altho to be fair, the api sucks because it won't accept multiple classes at once
var hasClass, addClass, removeClass;

if ( 'classList' in document.documentElement ) {
  hasClass = function( elem, c ) {
    return elem.classList.contains( c );
  };
  addClass = function( elem, c ) {
    elem.classList.add( c );
  };
  removeClass = function( elem, c ) {
    elem.classList.remove( c );
  };
}
else {
  hasClass = function( elem, c ) {
    return classReg( c ).test( elem.className );
  };
  addClass = function( elem, c ) {
    if ( !hasClass( elem, c ) ) {
      elem.className = elem.className + ' ' + c;
    }
  };
  removeClass = function( elem, c ) {
    elem.className = elem.className.replace( classReg( c ), ' ' );
  };
}

function toggleClass( elem, c ) {
  var fn = hasClass( elem, c ) ? removeClass : addClass;
  fn( elem, c );
}

var classie = {
  // full names
  hasClass: hasClass,
  addClass: addClass,
  removeClass: removeClass,
  toggleClass: toggleClass,
  // short names
  has: hasClass,
  add: addClass,
  remove: removeClass,
  toggle: toggleClass
};

// transport
if ( typeof define === 'function' && define.amd ) {
  // AMD
  define( classie );
} else {
  // browser global
  window.classie = classie;
}

})( window );

错误发生在:

  

elem.classList.add(c);

我不熟悉编写的代码。我将此文件与其他js文件一起包含在内。并且似乎其他js文件需要变量 classie

编辑:

这是控制台的错误:

Uncaught TypeError: Cannot read property 'classList' of null
  addClass @ classie.js?nngrmm:33
  scrollPage @ cbpAnimatedHeader.js?nngrmm:30

另外,我在bootstrap.js中有错误。

Uncaught TypeError: $(...).find(...).once is not a function
  Drupal.behaviors.bootstrap.attach @ bootstrap.js?nngrmm:16
  (anonymous function) @ drupal.js?nngrmm:76
  x.extend.each @ jquery.min.js?v=1.10.2:4
  Drupal.attachBehaviors @ drupal.js?nngrmm:74
  (anonymous function) @ drupal.js?nngrmm:412
  x.Callbacks.c @ jquery.min.js?v=1.10.2:4
  x.Callbacks.p.fireWith @ jquery.min.js?v=1.10.2:4
  x.extend.ready @ jquery.min.js?v=1.10.2:4
  q @ jquery.min.js?v=1.10.2:4

在这里的某个地方:

/**
 * @file
 * bootstrap.js
 *
 * Provides general enhancements and fixes to Bootstrap's JS files.
 */

var Drupal = Drupal || {};

(function($, Drupal){
  "use strict";

  Drupal.behaviors.bootstrap = {
    attach: function(context) {
      // Provide some Bootstrap tab/Drupal integration.
      $(context).find('.tabbable').once('bootstrap-tabs', function () {
        var $wrapper = $(this);
        var $tabs = $wrapper.find('.nav-tabs');
        var $content = $wrapper.find('.tab-content');
        var borderRadius = parseInt($content.css('borderBottomRightRadius'), 10);
        var bootstrapTabResize = function() {
          if ($wrapper.hasClass('tabs-left') || $wrapper.hasClass('tabs-right')) {
            $content.css('min-height', $tabs.outerHeight());
          }
        };
        // Add min-height on content for left and right tabs.
        bootstrapTabResize();
        // Detect tab switch.
        if ($wrapper.hasClass('tabs-left') || $wrapper.hasClass('tabs-right')) {
          $tabs.on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
            bootstrapTabResize();
            if ($wrapper.hasClass('tabs-left')) {
              if ($(e.target).parent().is(':first-child')) {
                $content.css('borderTopLeftRadius', '0');
              }
              else {
                $content.css('borderTopLeftRadius', borderRadius + 'px');
              }
            }
            else {
              if ($(e.target).parent().is(':first-child')) {
                $content.css('borderTopRightRadius', '0');
              }
              else {
                $content.css('borderTopRightRadius', borderRadius + 'px');
              }
            }
          });
        }
      });
    }
  };

错误:

  

$(context).find('。tabbable')。once('bootstrap-tabs',function(){

需要帮助。感谢。

3 个答案:

答案 0 :(得分:11)

我今天遇到了同样的问题,但针对不同的主题,我想发布我的决议,以帮助其他人。

问题在于cbpAnimatedHeader.js文件。该文件定义了“scrollPage”函数,该函数调用“classie”函数。这就是为什么你最初看到错误是与classie.js文件。在scrollPage函数中,使用变量“header”:

if ( sy >= changeHeaderOn ) {
        classie.add(header, 'navbar-shrink' );
    }
    else {
        classie.remove(header, 'navbar-shrink' );
    }

但是,标题没有以scrollPage函数可以读取的方式定义。要修复错误,您可以全局定义标头,也可以在scrollPage函数中定义标头。我选择只将变量定义复制到函数中。以下是 cbpAnimatedHeader.js 中的最终结果:

function scrollPage() {
    var sy = scrollY(),
    header = document.querySelector( '.navbar-fixed-top' );
    if ( sy >= changeHeaderOn ) {
        classie.add(header, 'navbar-shrink' );
    }
    else {
        classie.remove(header, 'navbar-shrink' );
    }
    didScroll = false;
}

答案 1 :(得分:5)

我意识到我的问题是我将cbpAnimatedHeader.js文件从正文的底部移到了头部。因此,标题为null,因为html尚未呈现。

我没有将标题查找添加到scrollPage函数中,而是将整个事件包装在jQuery文档中。

$(function(){
  var cbpAnimatedHeader = (function() {

      var docElem = document.documentElement,
          header = document.querySelector( '.navbar-fixed-top' ),
          didScroll = false,
          changeHeaderOn = 300;

      function init() {
          window.addEventListener( 'scroll', function( event ) {
              if( !didScroll ) {
                  didScroll = true;
                  setTimeout( scrollPage, 250 );
              }
          }, false );
      }

      function scrollPage() {
          var sy = scrollY();
          header = document.querySelector( '.navbar-fixed-top' );
          if ( sy >= changeHeaderOn ) {
              classie.add( header, 'navbar-shrink' );
          }
          else {
              classie.remove( header, 'navbar-shrink' );
          }
          didScroll = false;
      }

      function scrollY() {
          return window.pageYOffset || docElem.scrollTop;
      }

      init();

  })();
});

答案 2 :(得分:0)

在此处添加我的解决方案,因为我得到完全相同的错误,但它与实际的Classie插件无关。

我正在使用此处的脚本缩小我网站上方的菜单滚动:http://callmenick.com/post/animated-resizing-header-on-scroll

我在页面中添加了需要添加.smaller类的其他元素,因为它们在向上滚动以向上移动到较小的菜单时也会向上移动和缩小。我还添加了响应元素,并不总是在给定页面中定义。这就是问题所在,我曾尝试在Classie中使用addClass函数来处理滚动时实际上不存在的一些响应元素,因此每次滚动页面时都会抛出一些错误。

因此,在尝试向其添加.smaller类之前,我实施了检查以确保响应元素存在。

自:

window.addEventListener('scroll', function(e){  
    var header = document.querySelector("header");
    var responsive_element = document.querySelector(".responsive_element"); // responsive, not always on the page

    var distanceY = window.pageYOffset || document.documentElement.scrollTop,
        shrinkOn = 160;

    if (distanceY > shrinkOn) {

        classie.addClass(header,"smaller");
        classie.addClass(responsive_element,"smaller");

    } else {

        if (classie.has(header,"smaller")) {

            classie.removeClass(header,"smaller");
            classie.removeClass(responsive_element,"smaller");

        }

    }

});

要:

window.addEventListener('scroll', function(e){

    var responsive = false; // to find out if we have those missing elements on the page
    var header = document.querySelector("header"); // always exists

    var distanceY = window.pageYOffset || document.documentElement.scrollTop,
        shrinkOn = 160;

    if (document.querySelector(".responsive_element") != null) {    
    responsive = true; // if we are in mobile mode
    }

    // only deal with the mobile element if it exists
    if (responsive) {
    var responsive_element = document.querySelector(".responsive_element");
    } 


    if (distanceY > shrinkOn) {

        classie.addClass(header,"smaller");

        // only add the smaller class if the element exists
        if (responsive) {
        classie.addClass(responsive_element,"smaller");
        }


    } else {

        if (classie.has(header,"smaller")) {

            classie.removeClass(header,"smaller");

            // only remove the smaller class if the element exists
            if (responsive) {
            classie.removeClass(responsive_element,"smaller");
            }

        }

    }

});