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>
Related
I'm using jquery and in my app.js file I have tow main functions:
$(document).ready(function (){});
$(window).on("load", function (){});
my code looks like this:
$(function () {
// code
// code
function myFunction(){
// code
}
});
$(window).on("load", function () {
// I want to use myFunction() here but I cant because it's not accessible from here
myFunction();
});
is there a way to do this?
window.lib = {
onWindowLoad: function () {
...
},
onDocReady: function() {
...
},
evenmore: {
nested: function(){
...
}
}
}
$(window).on("load", function () {
lib.onWindowLoad();
});
There would be many other ways to do so.
In case, if you need to read something somewhere, that's here
I have a code like this:
function myfunc () {
alert('executed');
}
$('.classname').on('click' function () {
myfunc();
});
I want to run myfunc once. I mean I don't want to execute it every time when user clicks on .classname element. I guess I need to warp function-calling into a condition. Something like this:
if ( /* that function never executed so far */ ) {
myfunc();
}
How can I do that?
The simplest way with jQuery is to use .one
function myfunc() {
alert('executed');
}
$('.classname').one('click', function() {
myfunc();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="classname">click here!</button>
You should remove the event listener in the function you're calling:
function myfunc () {
alert('executed');
$('.classname').off('click', myfunc);
}
$('.classname').on('click', myfunc);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='classname'>Click Me</div>
Don't set a global variable like the other posts describe - there's no need for that and then you're still doing an unnecessary function call. This ensures the function is never called again and the event isn't being listed for.
$( document ).ready(function() {
var hasBeenExecuted = false;
function myfunc () {
alert('executed');
hasBeenExecuted = true;
}
$('.classname').on('click' function () {
if(!hasBeenExecuted){
myfunc();
}
});
});
var functionWasRun = false;
function myfunc () {
functionWasRun = true;
alert('executed');
}
$(document).ready(function() {
$('.classname').on('click', function () {
if (!functionWasRun) {
myfunc();
}
});
});
I would suggest, as an alternative to a global variable, assigning a property to the function.
function myfunc () {
alert('executed');
myfunc.executed = true;
}
$('.classname').on('click', function () {
if(!myfunc.executed) {
myfunc();
}
});
This has the advantage of working the same way while not polluting the global scope unnecessarily. However, if skyline3000's answer works for you, you should use that instead as it's cleaner and more sensible overall.
In this code, only the "test" in added to the class "team-member", probably because the second this is the function and not the element.
How can I do something of the main element(class) "team-member" inside a function ?
$(document).ready(function () {
$('.team-member').SimpleSlider();
});
(function ($) {
$.fn.SimpleSlider = function (options) {
Initial();
$(this).addClass("test");
function Initial() {
$(this).addClass("test2");
};
}(jQuery));
I found a solution, pass "this" as a parameter
$.fn.SimpleSlider = function (options) {
Initial(this);
$(this).addClass("test");
function Initial(obj) {
$(obj).addClass("test2");
}
I'm trying to improve my code overall, although the following code does work, I want to avoid using _this (to me a hacky way of doing it ), and start using either .call/.apply or .bind to set the context of this on the following example.
Here is the code and the link to jsfiddler link.
(function (window, $) {
'use strict';
var ButtonEffect, button;
Function Constructor
ButtonEffect = function (elem) {
this.button = $( elem );
};
//Prototype Chain
ButtonEffect.prototype = {
addEffect : function (ref) {
return $(this.button, ref).addClass('custom-effect-1');
},
btnObserver : function () {
//Don't want to use this approach
var _this = this;
this.button.on({
click : function () {
//Want to call addEffect without using _this/that #hack
_this.addEffect($(this));
}
});
}
};
button = new ButtonEffect('.my-button');
button.btnObserver();
(window, window.jQuery));
Here is another Solution i came up with link
Seems more appropriate to use the built in jQuery methods for passing data to the event handler, that way this still references the element inside the handler
(function (window, $) {
'use strict';
var ButtonEffect, button;
ButtonEffect = function (elem) {
this.button = $( elem );
};
ButtonEffect.prototype = {
addEffect : function (ref) {
return $(this.button, ref).addClass('custom-effect-1');
},
btnObserver : function () {
this.button.on( {
click : function (e) {
e.data.scope.addEffect($(this));
}
}, {scope: this});
}
};
button = new ButtonEffect('.my-button');
button.btnObserver();
}(window, window.jQuery));
FIDDLE
You can change your code like this:
btnObserver : function () {
this.button.on({
click : function (ev) {
this.addEffect($(ev.currentTarget));
}.bind(this)
});
}
ev.currentTarget is usually the same as what this would be if bind is not used. And bind makes it so that the value of this inside your event handler is the same as the scope in which bind executes. I have a fiddle.
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.