Some problems with Javascript functions and this argument - javascript

I am using colorbox to my popups and...
This works fine.
$(".show_popup").colorbox({inline:true, width:"800px", onOpen: function() {
type = $(this).attr('type);
....
}
But I want use my inner function many times so I want make it a module function.
});
(function ($,a) {
var p = {
showPopup: function (popup_type) {
...
},
bindEvents: function () {
$(".show_popup").colorbox({inline:true, width:"800px", onOpen: p.showPopup($(this).attr('type')) });
}
...
}
a.Popups = p;
})(jQuery);
But this don't work - it is problem with $(this) - and function execute only once after page loading.
(function ($,a) {
var p = {
showPopup: function (popup_type) {
...
},
bindEvents: function () {
$(".show_popup").colorbox({inline:true, width:"800px", onOpen: p.showPopup });
}
...
}
a.Popups = p;
})(jQuery);
And this don't work of course too, but execute many times. So can you help me know what is matter?

The problem with onOpen: p.showPopup($(this).attr('type)) is that it will run the p.showPopup-function at the moment that you bind it to onOpen. What you want is that it runs at the moment the onOpen-event is triggered. Use
onOpen: function() { p.showPopup($(this).attr('type')); }
instead
(edit) assuming that p.showPopup is defined, I can't see it in your code.

Related

How to append methods in JavaScript

I'm working with jQuery, making a WordPress website, and ran into issues because Wordpress doesn't seem to work with the $(window).load(...) event listener, due to which I had to change the code.
Here's the original code in jQuery:
$(window).load(function(){
...
}).resize(function() {
...
});
Hers's what I'd changed it to:
window.addEventListener('load', function() {
...
}).resize(function() {
...
});
However, I get an error in console TypeError: windowAddEventListener is undefined. How can I solve this?
You have two issues:
addEventListener return undefined so you can't do anything after it
in vanilla JavaScript there are no resize function this is only in jQuery.
You will need this:
window.addEventListener('load', function() {
...
});
window.addEventListener('resize', function() {
...
});
and if you want chaining you will need:
const x = {
load: function(fn) {
window.addEventListener('load', fn);
return this;
},
resize: function(fn) {
window.addEventListener('resize', fn);
return this;
}
};
x.load(function() {
}).resize(function() {
});

JavaScript namespace and calling function from two places

I've picked up some JavaScript to work on as follows (very much simplified!)
var namespace = {
init: function (config) {
// do stuff, all ok so far
},
events: function () {
$('#id').on('click', '.class', function (event) {
alert('hello')
}
}};
What I am trying to figure out is how, from the init: block of code, can I call the code in the click event that does alert('hello')?
I realise moving the alert('hello') into a function would help (so I can call the function from init and click), but how would I define the function in this namespace and call it from two places?
What I'm aiming at, and guessing the solution is something like this:
var namespace = {
init: function (config) {
// do stuff
hello
},
hello: function() {
alert('hello');
},
events: function () {
$('#id').on('click', '.class', function (event) {
hello
}
};
I will have to pass event param from click into hello.
I'm still trying to figure out how namespaces work in js... Thanks for any help offered.
Use the this keyword.
var namespace = {
init: function (config) {
// do stuff
this.hello();
},
hello: function() {
alert('hello');
},
events: function () {
$('#id').on('click', '.class', function (event) {
this.hello();
}.bind(this));
}
};
Example of how to use it:
namespace.init();
namespace.events(); // then do a click on the html where you have the class "class"
You can use one of the powerful functionality of Javascript - Closures. Refer the Closures topic in this MDN Documentation.
var namespace = (function(){
function hello(){
alert("hello");
}
return {
init: function (config) {
console.log("called init");
hello();
console.log("called hello from init")
},
events: function () {
$('#but').on('click', function (event) {
hello();
console.log("called hello from events")
});
}
}
})();
namespace.init();
namespace.events();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="but">Click</button>

jQuery - how to call method/prototype function

I am using sticky sidebar to make my sidebar(s) stick: http://github.com/caphun/jquery.stickysidebar/ I also use AJAX to reload the page many times. After a while, the scrolling lags and I presume it is because each time I reload the content without destroying the stickysidebar.
How do I call the destroy function here?
I tried
$('.stickem').stickySidebar.destroy();
and
$('.stickem').stickySidebar("destroy");
but neither worked. Here is the prototype:
$.stickySidebar.prototype = {
init: function() {
// code
},
stickiness: function() {
//code
},
bind: function() { },
destroy: function() {
alert('h');
this.element.unbind("destroyed", this.teardown);
this.teardown();
},
teardown: function() {
console.log('eee');
$.removeData(this.element[0], this.name);
this.element.removeClass(this.name);
this.unbind();
this.element = null;
},
unbind: function() { }
}
That's not how you do jQuery plugins. If you want to call it as $('.stickem').stickySidebar("destroy"); (which is the recommended way), do this:
$.fn.stickySidebar = function(action) {
if (action === 'destroy') {
...
}
};
See http://learn.jquery.com/plugins/basic-plugin-creation/

this works on some functions and not others

Normally when writing jQuery i just use functions. This time I want to give it a little sprinkle of best practice and so I followed a tutorial. The javascript itself seems to be correct but I am having a few problems calling certain functions.
jQuery.noConflict();
(function($j) {
'use strict';
function Site(settings) {
this.windowLoaded = false;
}
Site.prototype = {
constructor: Site,
start: function() {
var me = this;
$j(window).load(function() {
me.windowLoaded = true;
});
this.attach();
},
attach: function() {
this.getPrimaLink();
this.onCloseDialog();
this.triggerDialog();
this.openLink();
},
getPrimaLink: function(){
if($j('#order-data').is(":visible")){
$j( ".content-header" ).append($j( "#findPrimaLink" ));
$j('#findPrimaLink').show();
}
},
onCloseDialog: function(){
$j('#dialog').bind('dialogclose', function(event) {
$j( ".content-header" ).append($j( "#findPrimaLink" ));
$j('#findPrimaLink').show();
});
},
triggerDialog: function(){
$j("[title='Create New Customer']").click(function(){
$j('#findPrimaLink').show();
>>>>> this.openDialog(); <<<<<<
})
},
openLink: function(){
$j('#findPrimaLink').click(function(){
>>> this.openDialog(); <<<<<
});
},
openDialog: function(){
$j( "#dialog" ).dialog({
height: 'auto',
width: 350,
modal: true,
resizable:false,
});
},
};
$j(document).ready(function($j) {
var site = new Site();
site.start();
});
})(jQuery);
Within the start and attach function I am able to call each function by placing 'this' in front of it. But when I try to call openDialog() from openLink() and triggerDialog() I get - Uncaught TypeError: undefined is not a function.
Why is this and what should I do to fix it?
For both functions you're having a problem with, you're trying to use this inside of a jQuery function, so this's scope is to the DOM element, not the Site class.
triggerDialog: function(){
var site = this;
$j("[title='Create New Customer']").click(function(){
$j('#findPrimaLink').show();
site.openDialog();
console.log(this); //remove this for production, but you can see that `this` points to a DOM element
})
},
openLink: function(){
var site = this;
$j('#findPrimaLink').click(function(){
site.openDialog();
});
},
To understand why this happens, you should read about javascript Closures. Here and here.
P.S. you have an extra comma after your openDialog function.
P.P.S. It's also worth noting that this is exactly what're you're doing inside the start method.
var me = this;
$j(window).load(function() {
me.windowLoaded = true;
});

Calling a function (ex. namespace.show) by name

I want to call a function with a namespace based on its name.
Perhaps some background: What I want is, dynamically bind pages via $.mobile.loadPage(inStrUrl, { showLoadMsg: false }); and then, based on the current page, invoke a function within a loaded page. For example: each page has a showFilter function, the Event is attached to a main.html - page which should call the matching function in the current page.
I also tried some solutions, with jquery too, but nothing works for me.
This is my function code:
function namespace() { }
namespace.showFilter = function () {
alert("Test");
}
And want to "invoke" or "call" it via its name.
This is what i tried at least.
$(document).ready(function() {
var fn = window["namespace.showFilter"];
fn();
});
I get error TypeError: fn is not a function
Here is a fiddle http://jsfiddle.net/xBCes/1/
You can call it in the following way:
$(document).ready(function() {
window["namespace"]["showFilter"]();
});
or
$(document).ready(function() {
window["namespace"].showFilter();
});
or
$(document).ready(function() {
window.namespace.showFilter();
});
I found that I had to manually set it to window.
window.namespace = function() { }
window.namespace.showFilter = function () {
alert("Test");
};
$(document).ready(function() {
var fn = window["namespace"]["showFilter"];
fn();
});
http://jsfiddle.net/xBCes/4/
Like this:
$(function() {
window.namespace.showFilter();
});
P.S. I shortened the $(document).ready(...)
function namespace() {}
namespace.showFilter = function () {
alert("Test");
}
$(document).ready(function() {
var fn = namespace.showFilter();
fn();
});
http://jsfiddle.net/xBCes/3/

Categories

Resources