this.attribute is not defined after being constructed - javascript

Hi there I made a very small jquery plugin:
$mandarina = {
mainCnt: $('#main'),
header: $('header.site-header'),
init: function () {
this.onScroll();
},
onScroll: function () {
$(window).scroll(function(e){
var scrollTop = $(window).scrollTop();
if(scrollTop > this.header.height()){
this.mainCnt.addClass('fixed-header');
}else{
this.mainCnt.removeClass('fixed-header');
}
});
}
}
$(function () {
$mandarina.init();
});
But when I scroll I get this error in console:
TypeError: this.header is undefined
[Parar en este error]
if(scrollTop > this.header.height()){
Any idea why?
weird thing is that this.header in the init function it does exist..

Inside the scroll callback, this is the window element rather than your $mandarina object. You need to save a reference to $mandarina via;
onScroll: function () {
var that = this;
$(window).scroll(function(e){
var scrollTop = $(window).scrollTop();
if(scrollTop > that.header.height()){
that.mainCnt.addClass('fixed-header');
}else{
that.mainCnt.removeClass('fixed-header');
}
});
}
... i.e. store the value of this in that, and use that instead of this inside the event handler.

try this
$mandarina = {
mainCnt: $('#main'),
header: $('header.site-header'),
init: function () {
this.onScroll();
},
onScroll: function () {
var $this= $(this);
$(window).scroll(function(e){
var scrollTop = $(window).scrollTop();
if(scrollTop > $this.header.height()){
$this.mainCnt.addClass('fixed-header');
}else{
$this.mainCnt.removeClass('fixed-header');
}
});
}
}
$(function () {
$mandarina.init();
});

this.header.height
you need to remove this

Related

Array of elements becomes undefined within a class when changing with and attempting to do some adjustments

I build an object and gather all elements by class name, then on changing the with I want to do some work on them. When I construct the object it works, but within WidthChecker() when do some work on a width change the become undefined.
class SlickController {
constructor () {
this.$mobileSlicksCarousels;
}
Init() {
this.$mobileSlicksCarousels = document.getElementsByClassName("slick_carousels_mobile-only"); // view in console says this is valid, I see the objects
this.WidthChecker();
}
WidthChecker() {
var width = $(window).width();
$(window).on('resize', function() {
console.log(this.$mobileSlicksCarousels); // they become undefined in here, lost and none of the content afterwords be seen
if ($(this).width() !== width) {
width = $(this).width();
if (width < 491) {
this.$mobileSlicksCarousels.forEach( carousel => {
this.SlickMobile(carousel);
});
} else if (width > 490) {
this.$mobileSlicksCarousels.forEach( carousel => {
this.UnSlickMobile(carousel);
});
}
}
});
}
SlickMobile (toSlick) {
console.log(toSlick);
toSlick.slick();
}
UnSlickMobile (unSlick) {
unSlick.slick('unslick');
}
}
// call and start width checker
slick_Controller.Init();
I assume the issue is when I called $(window).on('resize', function() { because the function doesn't see the parent variables, but I'm not sure how else to approach calling a function directly on resize.
You can store this in a variable before jumping to function or you can bind function but then you lose jquery context and cannot use $(this) expression.
Take a look at the examples
class Test {
constructor () {
this.property = 1;
}
Func() {
var width = $(window).width();
const that = this;
$(window).on('load', function() {
console.log(that.property);
console.log($(this).width());
});
}
Func1() {
var width = $(window).width();
$(window).on('load', (function() {
console.log(this.property);
console.log($(window).width());
}).bind(this));
}
Func2() {
var width = $(window).width();
$(window).on('load', this.OnResize.bind(this));
}
OnResize(event) {
console.log(this.property);
console.log($(event.target).width());
}
}
const test = new Test();
test.Func();
test.Func1();
test.Func2();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Binding a click event (B) after an initial click event (A) causes event B to fire immediately

http://codepen.io/oliecs/pen/womLPJ
var nav = {
init: function () {
console.log('nav init');
$nav = $('nav');
$navIcon = $('.nav-icon');
$navIcon.on('click',function(){
nav.show();
})
},
show: function () {
console.log('nav show');
$nav.addClass('active');
$_DOCUMENT.on('click.navisopen',function(){ //document is a global variable
nav.close();
})
},
close: function () {
console.log('nav close');
$nav.removeClass('active');
$_DOCUMENT.off('.navisopen');
}
};
I feel the pen describes this better than I can. I want to click the nav-icon to open the nav, then any clicks after this will close the nav. However, the close event is fired instantly after the first click, resulting in the nav opening and closing instantly. I don't know how to make this sequential.
Updated js file..Use this code
var ecs= {};
ecs.common = (function($) {
var $_DOCUMENT = $(document),
$_WINDOW = $(window),
$nav = $('nav'),
$navIcon = $('.nav-icon');
var nav = {
init: function () {
console.log('nav init');
$nav = $('nav');
$navIcon = $('.nav-icon');
$navIcon.on('click',function(){
nav.show();
})
},
show: function () {
console.log('nav show');
$nav.addClass('active');
// $_DOCUMENT.on('click.navisopen',function(){
// nav.close();
// })
},
close: function () {
console.log('nav close');
$nav.removeClass('active');
$_DOCUMENT.off('.navisopen');
}
};
//--------------------
// DOM Ready
//--------------------
$(function() {
nav.init();
});
$(document).mouseup(function (e) {
var container = $(".nav-icon");
if (!container.is(e.target) && container.has(e.target).length === 0) {
/* if the target of the click isn't the container && nor a descendant of the container */
$nav.removeClass('active');
}
});
})(jQuery);
You need to
$navIcon.on('click',function(event){
event.stopPropagation();
nav.show();
})
Because the first click is bubbling up the DOM all the way to the document where that event handler is triggered.

jQuery function (Window resized)

Here is my code :
jQuery(document).ready(function (e) {
resized();
jQuery(window).resize(resized);
function resized() {
wd = parseInt(jQuery(window).width());
if (wd >= 992) {
var wrhei = jQuery(document).height();
jQuery('#menu').height(wrhei);
}
}
});
I want to call function when I resize the page without refreshing the page just when I resize function happen
Here is the code / approach, I am using in my project and it works great.
Call the $(window).resize function in the document ready event as shown below,
$(document).ready(function () {
$(window).resize(function () {
Resized();
});
});
function Resized()
{
//your code here
}
You can try :
jQuery(window).on('resize', function(e) {
wd = parseInt(jQuery(window).width());
if (wd >= 992) {
var wrhei = jQuery(document).height();
jQuery('#menu').height(wrhei);
}
});

Jquery resize dynamic update?

I'm trying to get my window resize to work but I have to update the page every time to get it to work. Is there any way that this can update dynamic??
$(document).ready(function() {
var $window = $(window);
function checkWidth() {
var window_size = $window.width();
if(window_size> 1820){
$('.22').addClass('size33');
$('.22').removeClass('size22');
} else {
$('.22').removeClass('size33');
$('.22').addClass('size22');
}
}
// Execute on load
checkWidth();
// Bind event listener
$(window).resize(checkWidth);
});
var div = document.body.selectElementbyId("div id")
window.addEventListener('resize', function() {
var window_size = $window.width();
if(window_size> 1820){
$('.22').addClass('size33');
$('.22').removeClass('size22');
} else {
$('.22').removeClass('size33');
$('.22').addClass('size22');
}
document.getElementbyId("div id").style.width = window_size;
}
}, true);

Call a function when window is resized

How can I call for this(or any) JS function to be run again whenever the Browser window is resized?
<script type="text/javascript">
function setEqualHeight(e) {
var t = 0;
e.each(function () {
currentHeight = $(this).height();
if (currentHeight > t) {
t = currentHeight
}
});
e.height(t)
}
$(document).ready(function () {
setEqualHeight($(".border"))
})
</script>
You can use the window onresize event:
window.onresize = setEqualHeight;
You can subscribe to the window.onresize event (See here)
window.onresize = setEqualHeight;
or
window.addEventListener('resize', setEqualHeight);
This piece of code will add a timer which calls the resize function after 200 milliseconds after the window has been resized. This will reduce the calls of the method.
var globalResizeTimer = null;
$(window).resize(function() {
if(globalResizeTimer != null) window.clearTimeout(globalResizeTimer);
globalResizeTimer = window.setTimeout(function() {
setEqualHeight();
}, 200);
});
You use jquery, so bind it using the .resize() method.
$(window).resize(function () {
setEqualHeight( $('#border') );
});

Categories

Resources