Kenneth .J
Kenneth .J

Reputation: 1433

Uncaught TypeError: Cannot read property 'defaultView' of undefined with a IIFE

I'm working my way through Learning jQuery 4th Edition (PacktPub publishing), trying out one of it's exercises where i have to create new plugin methods called .slideFadeIn() and .slideFadeOut(),combining the opacity animations of .fadeIn() and .fadeOut() with the height animations of .slideDown() and .slideUp().

This is my current code

(function($) {
  $.fn.slides={
    slideIn:function(){
      $(this).fadeIn().slideDown();
    },
    slideOut:function(){
      $(this).fadeOut().slideUp();
    }
  }
})(jQuery);

$('h1').click(function(){
  $(this).slides.slideOut();
});

yet when i click on <h1>, i get the error message,

Uncaught TypeError: Cannot read property 'defaultView' of undefined

I've also tried

(function($) {
  var elem=$(this);
  $.fn.slides={
    slideIn:function(){
      elem.fadeIn().slideDown();
    },
    slideOut:function(){
      elem.fadeOut().slideUp();
    }
  }
})(jQuery);

to see if the error was because $(this) was referring to a different context, but i am still getting the same error

Uncaught TypeError: Cannot read property 'defaultView' of undefined 

EDIT:I've tried editing the code to

$('h1').fadeOut().slideUp();

and it works, so the issue lies with $(this), i just don't see what exactly is the problem with $(this)

Could someone kindly point out my mistake?

Thanks!

Upvotes: 3

Views: 21653

Answers (1)

james emanon
james emanon

Reputation: 11807

The way you are creating your plugin is a little different than I would, as the "this" is the "fn.slides" scope 'this' - thus, it errors out. I was able to solve your issue by passing the context of the "this" you want -- which is the 'h1' by using 'call'. With "call" (and "apply), I can call the function and pass in the 'this' context I want.

(function($) {
  $.fn.slides={
    slideIn:function(){
      $(this).fadeIn().slideDown();
    },
    slideOut:function(){
      $(this).fadeOut().slideUp();
    }
  }
})(jQuery);

$('h1').click(function(){
  $(this).slides.slideOut.call(this);
});

Upvotes: 1

Related Questions