Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Cannot read property 'classList' of null" when using classList.add

I am having this error, but since I am not familiar with the code. It came from a theme in startbootstrap (Creative). The file is

classie.js

code:

/*!
 * 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 );

the error is in:

elem.classList.add( c );

I am not familiar with the code written. I include this file together with other js files. And it seems that the other js file needs the variable classie.

EDITED:

HERE IS THE ERROR IN CONSOLE:

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

ALSO, I have an error in 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

Somewhere in here:

/**
 * @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');
              }
            }
          });
        }
      });
    }
  };

Error in:

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

Need help. Thanks.

like image 209
bpunzalan Avatar asked Apr 29 '15 11:04

bpunzalan


2 Answers

I ran into the same issue today but for a different theme and wanted to post my resolution to help others in the future.

The issue is with cbpAnimatedHeader.js file. That file defines the "scrollPage" function, which calls upon the "classie" function. That is why you are initially seeing that the error is with the classie.js file. In the scrollPage function, the variable "header" is used:

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

However, header is not being defined in a way that the scrollPage function can read it. To fix the error, you can either define header globally or within the scrollPage function. I chose to just copy the variable definition into the function. Here's the final result in 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;
}
like image 54
Ercunningham Avatar answered Nov 15 '22 00:11

Ercunningham


I realized that my issue was I moved the cbpAnimatedHeader.js file from the bottom of the body to the head. Because of this, header was null because the html hadn't rendered yet.

Instead of adding the header lookup to the scrollPage function I wrapped the whole thing in a jQuery document ready.

$(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();

  })();
});
like image 39
punkbyte Avatar answered Nov 14 '22 23:11

punkbyte