6

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.

Siguza
  • 21,155
  • 6
  • 52
  • 89
bpunzalan
  • 378
  • 1
  • 6
  • 24
  • 4
    Something somewhere tries to access the property `classList` of a `null` object, for example `document.geyElementById('nonexisting').classList.add('foo')` would throw this error if there's no element with that ID. – pawel Apr 29 '15 at 11:23
  • the `elem`, that is the one I am looking for. I dont know where it came from. document.documentElement returns my whole html markups. – bpunzalan Apr 29 '15 at 12:07
  • @Aracthor that is the error message – bpunzalan Apr 29 '15 at 12:11
  • After thorough searching for the answer, I stumbled the same problem as me. http://stackoverflow.com/questions/25884754/rails-apllication-elem-is-null-in-classie-js – bpunzalan Apr 29 '15 at 12:24

3 Answers3

11

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;
}
Ercunningham
  • 111
  • 1
  • 3
5

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

  })();
});
Philipp Meissner
  • 5,273
  • 5
  • 34
  • 59
punkbyte
  • 206
  • 2
  • 3
0

Adding my solution here as I was getting the exact same error, but it had nothing to do with the actual Classie plugin.

I was using the script from here to shrink the upper menu on my site on scroll: http://callmenick.com/post/animated-resizing-header-on-scroll.

I added additional elements to the page that needed the .smaller class added to them as they would also move up and shrink when scrolled to move up to the smaller menu. I was adding responsive elements as well that were NOT always defined within the given page. That was the problem, I had tried to use the addClass function in Classie on some responsive elements that actually didn't exist when scrolling, so it would throw a handful of these errors each time the page was scrolled.

So I implemented a check to make sure the responsive elements exist before attempting to add the .smaller class to them.

From:

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");

        }

    }

});

To:

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");
            }

        }

    }

});
tatorface
  • 72
  • 1
  • 8