In the code below, my return function inside the other function doesn't get run right away, but the first function is. My goal is to have the whole function running immediately.
var windowCheck = (function () {
var switcher = false;
return function () {
console.log(switcher);
if ($window.innerWidth > 480) {
if (!switcher) {
element.perfectScrollbar({
wheelSpeed: scope.wheelSpeed || 50,
wheelPropagation: $parse(attrs.wheelPropagation)() || false,
minScrollbarLength: $parse(attrs.minScrollbarLength)() || false
});
console.log('Plugin On');
switcher = true;
}
}
else {
if (switcher) {
console.log('Plugin Off');
element.perfectScrollbar('destroy');
switcher = false;
}
}
};
}());
The function does indeed run the first time -- an anonymous function runs and it's result is --
Another function!
This 'second' function is then assigned to the value of windowCheck.
And windowCheck won't run until called.
Simply run it after defining it and avoid all the anonymous function mess:
var windowCheck = function() {
...
}
windowCheck();
The code as you have it now defines the windowCheck function and uses a closure to house a private switcher variable. That is all fine. If you want the function that gets defined to be executed, then you just have to add this to the end of what you already have:
windowCheck();
in order to actually execute it immediately.
Related
As below code, I make an object named "test", and give it properties and method.
The property came from its argument.
And I try to call the method every 2 sec after onload, and the result shows undefined.
But if I only call the method not using setInterval(), like this
window.onload = function() {
giveword.showWord();
}
I'll be able to show the text "Hi".. Why is that?
var giveword = new test("Hi");
function test(word) {
this.word = word;
}
test.prototype.showWord = function() {
document.getElementById("msg_box").innerHTML = this.word;
}
window.onload = function() {
setInterval(giveword.showWord, 2000);
}
Thanks for help...
The reason is because in your test.prototype.showWord function your this object is referring to the context in which the function is called, which is the window object when called from setInterval.
I think what you want to do is use a closure to make the context of showWord() be the giveword instance like this:
var giveword = new test("Hi");
function test(word) {
this.word = word;
}
test.prototype.showWord = function() {
document.getElementById("msg_box").innerHTML = this.word;
}
window.onload = function(){
setInterval(function(){giveword.showWord();}, 2000); // <<-- here's the closure
}
The difference is that with the closure you're telling the setInterval function to call a function within the context as it was when the setInterval was declared. When setInterval was declared there was a variable in scope called giveword that had a method showWord() that returns the value of your initial input. (Closures are hard to explain, and I'm afraid you'd be best served by someone else explaining them if you need more info.)
This solution this now so easy, use an arrow function in setInterval. Here is an example using setInterval inside of an object method.
const mobile = {
make: 'iPhone',
model: 'X',
battery: 10,
charging: false,
charge: function() {
if(this.battery < 100) {
this.charging = true;
console.info('Battery is charging...');
let interval = setInterval(() => {
this.battery = this.battery + 10;
console.info(mobile.battery);
if( this.battery === 100){
this.charging = false;
clearInterval(interval);
console.info('Battery has finished charging.');
}
}, 100);
}
else {
console.info('Battery does not need charging.');
}
}
}
On click on check box, I am initating a autonomous function, by parallel i am adding a bind event ("keyup") to the same function, but it is not working. and i am not able to send the parameter as well.. what is the correct approach to handle this..?
here is my function :
var validateAltName = (function (info) {
var altName = $.trim(altInput.value);
console.log(altName); //only one time i am getting, not on keyup..
if (!altName) {
altInput.select();
return;
}
}());
$(altInput).on("keyup", validateAltName); //is there a way to send parameter?
You are creating a function and immediately invoking it, therefore nothing is actually assigned into the variable validateAltName - it remains undefined since that is the return value of the function.
var validateAltName = (function (info) {
var altName = $.trim(altInput.value);
console.log(altName); //only one time i am getting, not on keyup..
if (!altName) {
altInput.select();
return; // return 'undefined', which gets assigned to validateAltName
}
// if you fall off the end, it also returns 'undefined'
}()); // this _calls_ the function
Remove the surrounding parentheses and the trailing ()
var validateAltName = function (info) { // no opening paren
var altName = $.trim(altInput.value);
console.log(altName); //only one time i am getting, not on keyup..
if (!altName) {
altInput.select();
return;
}
}; // no () parens or closing )
EDIT: If you want to send parameters to this function when the event occurs, you can include an anonymous function in the handler that invokes it:
// instead of
$(altInput).on("keyup", validateAltName); //is there a way to send parameter?
// you can use
$(altInput).on("keyup", function(e) {
// by using .call() instead of direct invocation () you can preserve 'this'
validateAltName.call(this, parm1, parm2);
}); //is there a way to send parameter?
You are executing your function and just storing the result to the variable. Change your code to this
var validateAltName = function (info) {
var altName = $.trim(altInput.value);
console.log(altName); //only one time i am getting, not on keyup..
if (!altName) {
altInput.select();
return;
}
};
var validateAltName = function (info) {
var altName = $.trim(altInput.value);
console.log(altName); //only one time i am getting, not on keyup..
if (!altName) {
altInput.select();
return;
}
};
$(altInput).on("keyup", validateAltName);
The problem is I need to break the function if it is first time running
is there any function available , or I have to do something like the following?
var times = 1
function abc () {
if (times == 1)
break;
else
.....
times++;
}
times = 0;
Thanks.
You can use this pattern:
function abc() {
if (!abc.flag) {
abc.flag = true;
return;
}
// .. rest of the code
}
It's based on the fact that Function is also an object in Javascript.
Basically this is a Memoization pattern. It has disadvantage that the flag property can be overwritten by another code. The advantage is that you don't need to pollute global scope with additional variables.
thg435 proposed much more elegant solution.
It appears to me that you're trying to solve the problem in the wrong place. Can you tell us the whole story?
In the meantime, something like this should do the trick:
function abc() {
abc = function() {
// ...actual work...
}
}
Details depend on how your function is defined (globally, locally, as a method).
var isFirstTime = true;
function abc () {
if (isFirstTime)
{
isFirstTime = false;
return;
}
.....
}
abc(); //returns
abc(); //runs
var firstTime= true
function abc () {
if (firstTime)
{
firstTime = false;
return;
}
else
{
.....
}
}
Try This :
var times = 1;
function abc () {
if (times == 1){}
else{
.....
times == 0;}
}
I have quite a few of these:
function addEventsAndStuff() {
// bla bla
}
addEventsAndStuff();
function sendStuffToServer() {
// send stuff
// get HTML in response
// replace DOM
// add events:
addEventsAndStuff();
}
Re-adding the events is necessary because the DOM has changed, so previously attached events are gone. Since they have to be attached initially as well (duh), they're in a nice function to be DRY.
There's nothing wrong with this set up (or is there?), but can I smooth it a little bit? I'd like to create the addEventsAndStuff() function and immediately call it, so it doesn't look so amateuristic.
Both following respond with a syntax error:
function addEventsAndStuff() {
alert('oele');
}();
(function addEventsAndStuff() {
alert('oele');
})();
Any takers?
There's nothing wrong with the example you posted in your question.. The other way of doing it may look odd, but:
var addEventsAndStuff;
(addEventsAndStuff = function(){
// add events, and ... stuff
})();
There are two ways to define a function in JavaScript. A function declaration:
function foo(){ ... }
and a function expression, which is any way of defining a function other than the above:
var foo = function(){};
(function(){})();
var foo = {bar : function(){}};
...etc
function expressions can be named, but their name is not propagated to the containing scope. Meaning this code is valid:
(function foo(){
foo(); // recursion for some reason
}());
but this isn't:
(function foo(){
...
}());
foo(); // foo does not exist
So in order to name your function and immediately call it, you need to define a local variable, assign your function to it as an expression, then call it.
There is a good shorthand to this (not needing to declare any variables bar the assignment of the function):
var func = (function f(a) { console.log(a); return f; })('Blammo')
There's nothing wrong with this set up (or is there?), but can I smooth it a little bit?
Look at using event delegation instead. That's where you actually watch for the event on a container that doesn't go away, and then use event.target (or event.srcElement on IE) to figure out where the event actually occurred and handle it correctly.
That way, you only attach the handler(s) once, and they just keep working even when you swap out content.
Here's an example of event delegation without using any helper libs:
(function() {
var handlers = {};
if (document.body.addEventListener) {
document.body.addEventListener('click', handleBodyClick, false);
}
else if (document.body.attachEvent) {
document.body.attachEvent('onclick', handleBodyClick);
}
else {
document.body.onclick = handleBodyClick;
}
handlers.button1 = function() {
display("Button One clicked");
return false;
};
handlers.button2 = function() {
display("Button Two clicked");
return false;
};
handlers.outerDiv = function() {
display("Outer div clicked");
return false;
};
handlers.innerDiv1 = function() {
display("Inner div 1 clicked, not cancelling event");
};
handlers.innerDiv2 = function() {
display("Inner div 2 clicked, cancelling event");
return false;
};
function handleBodyClick(event) {
var target, handler;
event = event || window.event;
target = event.target || event.srcElement;
while (target && target !== this) {
if (target.id) {
handler = handlers[target.id];
if (handler) {
if (handler.call(this, event) === false) {
if (event.preventDefault) {
event.preventDefault();
}
return false;
}
}
}
else if (target.tagName === "P") {
display("You clicked the message '" + target.innerHTML + "'");
}
target = target.parentNode;
}
}
function display(msg) {
var p = document.createElement('p');
p.innerHTML = msg;
document.body.appendChild(p);
}
})();
Live example
Note how if you click the messages that get dynamically added to the page, your click gets registered and handled even though there's no code to hook events on the new paragraphs being added. Also note how your handlers are just entries in a map, and you have one handler on the document.body that does all the dispatching. Now, you probably root this in something more targeted than document.body, but you get the idea. Also, in the above we're basically dispatching by id, but you can do matching as complex or simple as you like.
Modern JavaScript libraries like jQuery, Prototype, YUI, Closure, or any of several others should offer event delegation features to smooth over browser differences and handle edge cases cleanly. jQuery certainly does, with both its live and delegate functions, which allow you to specify handlers using a full range of CSS3 selectors (and then some).
For example, here's the equivalent code using jQuery (except I'm sure jQuery handles edge cases the off-the-cuff raw version above doesn't):
(function($) {
$("#button1").live('click', function() {
display("Button One clicked");
return false;
});
$("#button2").live('click', function() {
display("Button Two clicked");
return false;
});
$("#outerDiv").live('click', function() {
display("Outer div clicked");
return false;
});
$("#innerDiv1").live('click', function() {
display("Inner div 1 clicked, not cancelling event");
});
$("#innerDiv2").live('click', function() {
display("Inner div 2 clicked, cancelling event");
return false;
});
$("p").live('click', function() {
display("You clicked the message '" + this.innerHTML + "'");
});
function display(msg) {
$("<p>").html(msg).appendTo(document.body);
}
})(jQuery);
Live copy
Your code contains a typo:
(function addEventsAndStuff() {
alert('oele');
)/*typo here, should be }*/)();
so
(function addEventsAndStuff() {
alert('oele');
})();
works. Cheers!
[edit] based on comment: and this should run and return the function in one go:
var addEventsAndStuff = (
function(){
var addeventsandstuff = function(){
alert('oele');
};
addeventsandstuff();
return addeventsandstuff;
}()
);
You might want to create a helper function like this:
function defineAndRun(name, func) {
window[name] = func;
func();
}
defineAndRun('addEventsAndStuff', function() {
alert('oele');
});
Even simpler with ES6:
var result = ((a, b) => `${a} ${b}`)('Hello','World')
// result = "Hello World"
var result2 = (a => a*2)(5)
// result2 = 10
var result3 = (concat_two = (a, b) => `${a} ${b}`)('Hello','World')
// result3 = "Hello World"
concat_two("My name", "is Foo")
// "My name is Foo"
If you want to create a function and execute immediately -
// this will create as well as execute the function a()
(a=function a() {alert("test");})();
// this will execute the function a() i.e. alert("test")
a();
Try to do like that:
var addEventsAndStuff = (function(){
var func = function(){
alert('ole!');
};
func();
return func;
})();
For my application I went for the easiest way. I just need to fire a function immediately when the page load and use it again also in several other code sections.
function doMyFunctionNow(){
//for example change the color of a div
}
var flag = true;
if(flag){
doMyFunctionNow();
}
My code looks something like:
$(document).ready(function(){
var cont = 0;
function func1(cont)
{
//Some code here
search.setSearchCompleteCallback(this, searchComplete, null);
//Some other code
}
func1(cont);
function searchComplete()
{
//Some code
cont += 1;
if (cont < length ) {
func1(cont);
} else {
// Other code
}
}
});
So what I want to do is delay the execution of func1(cont); inside of the searchComplete() function. The reason for this is that all the code does is to work with the Google search API and PageRank checks and I need to slow down the script so that I won't get banned. (Especially for the requests it makes regarding the PR check).
If I simply use setTimeout() on func1(cont); it says there is no func1() defined, if I try to get the function outside $(document).ready() it sees the function but the Google code won't for for it needs the page completely loaded.
How can I fix setTimeout or how can I pause the script for a number of seconds ?
Thanks!
Write
func1(cont);
as
window.setTimeout(function() {
func1(cont);
}, 1000);
Instead of declaring the function like this:
function func1(cont) {}
declare it like this:
var func1 = function(cont) {}
You'll need to rearrange your code a little:
$(document).ready(function(){
var cont = 0;
var func1;
var searchComplete = function()
{
//Some code
cont += 1;
if (cont < length ) {
func1(cont);
} else {
// Other code
}
}
func1 = function(cont)
{
//Some code here
search.setSearchCompleteCallback(this, searchComplete, null);
//Some other code
}
func1(cont);
});
I'd try something like this. I prefer to declare the vars and functions inside the jquery namespace, but you could equally move the cont variable and the functions outside of the document ready function and have them available globally.
$(document).ready(function(){
$.cont = 0;
$.func1 = function() {
//Some code here
search.setSearchCompleteCallback(this, $.searchComplete, null);
//Some other code
}
$.searchComplete = function() {
//Some code
$.cont += 1;
if (cont < length ) {
setTimeout($.func1,1000);
} else {
// Other code
}
}
setTimeout($.func1,1000); // delay the initial start by 1 second
});
Hopefully I've got your description correct:
document.ready() event fires
Inside document.ready() you want a function to be called after X milliseconds
This function wires up the Google object search.setSearchCompleteCallback() to another function (which it looks like it needs a parent object from the this)
If this is the case, why do you need any of the functions declared inside the document.ready() scope? Can you't simply make all 3 global? e.g.
var search = null; // initialise the google object
var cont = 0;
function timedSearch()
{
search.setSearchCompleteCallback(this, searchComplete, null);
}
function searchComplete()
{
if (++cont < length) // postfix it below if this is wrong
setTimeout(timedSearch,1000);
}
$(document).ready(function()
{
setTimeout(timedSearch,1000);
}
Hit me with the downvotes if I've misunderstood.