Query
Query

Reputation: 719

Onclick not working. Cannot read property 'click' of null

I keep receiving the following error from the browser console when loading my script into my Magento store. All that it is listening for is an onclick event on a div yet I receive this error:

"Uncaught TypeError: Cannot read property 'click' of null."

The script works in JSfiddle so I'm really not quite sure why it isn't working. I've tried enclosing it within a $( document ).ready() as well but I receive the same error.

Code:

var step = 0;
var deviceType = "";
var modelType = "";

function showGen(){
    $('.phoneTypes').css("display", "none");

    if (deviceType == "Samsung"){
      $('.sphoneGens').css("display", "block");
    }
    if (deviceType == "iPhone"){
      $('.iphoneGens').css("display", "block");
    }
    if (deviceType == "iPad"){
      $('.ipadGens').css("display", "block");
    }
}

// Pick Device Type
$('.choicelabel').click(function(){
    deviceType = $(this).children('input').val();
    showGen();
});

//Pick Device Gen
$('.choiceType').click(function(){
    modelType = $(this).children('input').val();
    //$(".iphoneGens").css("display", "none");
    console.log(deviceType);
    console.log(modelType);
    $(this).parents(".row").hide();
});

Any help debugging this issue will be greatly appreciated.

Upvotes: 1

Views: 17228

Answers (2)

vp_arth
vp_arth

Reputation: 14992

TL;DR:

jQuery( document ).ready(function( $ ) {
  // Code using $ as usual goes here.
  // And document is ready too
});

What's the issue?

Prototype.js was loaded after jQuery and was overwrite global $ symbol.

How can we deal with it?

You still have jQuery global to use. Just use it everywhere, where you want to use $.

// Pick Device Type
jQuery('.choicelabel').click(function(){
    deviceType = jQuery(this).children('input').val();
    showGen();
});

//Pick Device Gen
jQuery('.choiceType').click(function(){
    modelType = jQuery(this).children('input').val();
    //jQuery(".iphoneGens").css("display", "none");
    console.log(deviceType);
    console.log(modelType);
    jQuery(this).parents(".row").hide();
});

You can also to define some shorthand for simplify it:

jQ = jQuery;

Common best practice for cases like this is to use IIFE wrap for your code:

;(function($){ // see note-1
  // Use $ here! It's jQuery now
  $(function(){
    // be sure DOM was loaded before work with it(ex: binding events)
  });
})(jQuery);

This adds nothing to global scope and achieves what we need.
You always can inject some other libraries(prototypejs?) with alias what you want to this IIFE.

note-1: Semicolon before IIFE protects javascript from previous expression with missed semicolon to be interpreted as function call.


jQuery itself provides shorthand for this case:

jQuery( document ).ready(function( $ ) {
  // Code using $ as usual goes here.
  // And document is ready too
});

Upvotes: 5

mdickin
mdickin

Reputation: 2385

That site isn't using jQuery, it's using prototypejs

Upvotes: 0

Related Questions