Essentially i have three different classes that can be applied to an element on my page. Each holds a different background image and i want to use JQuery to find out which class is currently there and the remove that class and replace it with another. and then set a timer on it to run the function every 5000ms
this is what my code looks like
$(document).ready(
function(){
var toggleImage = function(){
if($(".home").hasClass("home1")){
$(".home").removeClass("home1").addClass("home2") }
elseif($(".home").hasClass("home2")){
$(".home").removeClass("home2").addClass("home3")
}
elseif($(".home").hasClass("home3")){
$(".home").removeClass("home3").addClass("home1")
}
}
setInterval(toggleImage(), 5000);
});
The class of home will always be there and im just trying to add and remove the other classes on the element. Im coming from PHP so im thinking maybe my syntax could be off.
You have to pass a function to setInterval. Currently you are calling toggleImage and pass its return value, which is undefined.
Don't call the function:
setInterval(toggleImage, 5000);
At least in Firefox you would have gotten a runtime error:
Error: useless setInterval call (missing quotes around argument?)
Im coming from PHP so im thinking maybe my syntax could be off.
You are right, elseif should be else if. This is a syntax error and you should have seen it in the console as well.
Learn how to debug JavaScript to find syntax and runtime errors on your own.
You want to pass setInterval a function. Calling toggleImage() runs the function and ends up passing setInterval the result. The correct syntax should be:
setInterval(toggleImage, 5000);
Related
There is a widget in the POS(point of sale) called PaymentScreenWidget and inside that there's a customer_changed method which is called when the customer is changed.
Suppose that I want to call a method after this method is called then how can I do this without interfering with this code?
Interfering with this code leaves a lot of trouble in many case so are there any ways to achieve this?
I want to append some text to it but since there are many module who try to change those code or override it I want to avoid doing it and try to call my method after that method has been called.
You'll have to do some code instrumentation.
For example,
let old_customer_changed = customer_changed;
customer_changed = function(){
// my awesome code
old_customer_changed();
}
You'll have to implement similar thing in whatever modules you are using.
This question already has an answer here:
JavaScript setTimeOut doesn't seem to work like I expect
(1 answer)
Closed 4 years ago.
Relative newcomer to JS trying to keep my code class-oriented for the sake of best practice. I found a piece of code here for a text cycling effect I wanted to employ on a project. Using the code as-is within my main App.js worked fine. I then attempted to make it class/module oriented for later possible recycling, but thus far I've hit a brick wall. Passing console logs instead I've noticed that my attempts to use SetInterval, both within the class and in my App.js file calling the class into my HTML, don't seem to work, never properly looping more than once outside of isolating it.
Here's the current state of my code, possibly far removed from what I was doing previously, but it should give an idea where my head's at.
TextCycle.js:
import $ from 'jquery';
class TextCycle{
constructor(){
this.cycledText = $('.cycled-text');
this.i = 0;
}
cycle(){
//this.cycledText.removeClass('cycled-text--active');
//this.cycledText.eq(this.i).addClass('cycled-text--active');
this.i++;
console.log(this.i);
}
}
export default TextCycle;
App.js:
import TextCycle from './components/TextCycle';
var textCycle = new TextCycle();
setInterval(textCycle.cycle(), 3000);
Given I have a working version this isn't a critical issue, but given the point was practicing this sort of JS organization and modularization due to how I was taught, any insight on making this work is immensely helpful!
There is a problem with the way you're using setInterval() , along with your call to .cycle().
In short, you will want to update your code that calls setInterval so that cycle() is only called during the callback. Something like this would do:
setInterval(function() { textCycle.cycle() }, 3000);
One of the reasons your current code fails is that, textCycle.cycle() is called immediately, during this line:
setInterval(textCycle.cycle(), 3000); // Notice the () after cycle?
// That's causing the cycle
// method to be called immediately
By placing this in a callback function, as shown above, this does a few things:
it ensures that cycle() is invoked from the correct context (ie the context of your textCycle object. That basically means that when your use this inside of cycle(), then this will be the textCycle object, rather than the global object
it ensures that the cycle() method only gets invoked during the setInterval "callback", which is called on your set internal, rather than being called immediately
Hope this helps!
At one line of my code I have something like that:
...
while(!$scope.isMyTurn(privilege)){}
I will run next line of codes
However as usual it blocks my browser. I have to wait until get true to run next line of codes. I don't want to block my browser and other functionalities should work because(some of other fired events will change the situation of my turn) User should continue whatever he does.
This is for refreshing a graphic until my turn is come.
You should be doing it something like :
$scope.$watch("isMyTurn(privilege)",function(val){
if(val){
//I will run next line of codes
}
});
instead of what you are attempting to do..
Note that in this scenario, privilege should also be a scope variable something like
$scope.privilege
If you dont want it to be a scope variable just dont pass it as an argument. but directly access it inside the function..
Hope this helps..
Consider using the $scope.$watch function.
Look under ($watch):
http://docs.angularjs.org/api/ng.$rootScope.Scope
I don't know about angularJS but in normal JavaScript you could use setTimeout
function whenReady()
{
if ($scope.isMyTurn(privilege)){
I will run next line of codes
}
else
{
window.setTimeout(whenReady, 1000);
}
}
window.setTimeout(whenReady, 1000);
I am learning javascript, and am trying to adjust the following:
$('#myform').change(function() {
if ($('#sv_I4b').attr('checked')||$('#sv_I4c').attr('checked')){
$('#sv_I5').removeClass('hidden');
} else {
$('#sv_I5').addClass('hidden');
}
});
To be a a function with a name that I can call on different events, such as page load etc.
I don't yet fully understand each element, but I know that:
if ($('#sv_I4b').attr('checked')||$('#sv_I4c').attr('checked')){
$('#sv_I5').removeClass('hidden');
} else {
$('#sv_I5').addClass('hidden');
}
is the core "logic" of the function: if (condition) {then this} else {that}
and more or less understand what is happening there. Which leaves the bounding javascript (is there better terminology than that?):
$('#myform').change(function() {...});
My Questions (are the following true etc):
The dollar I think denotes that it is jQuery
The id my form obviously
pertains the script to events within that form (namespace?)
.change seems to be, a trigger that listens to ... any change taking place
within #myform? so every time a change happens within #myform this
runs? That seems inefficient
function() I don't yet understand what
an anonymous or empty function does, just defines what is contained
in {} as a function?
My goal: to be able to have something like
function myfunction()
{
if ($('#sv_I4b').attr('checked')||$('#sv_I4c').attr('checked')){
$('#sv_I5').removeClass('hidden');
} else {
$('#sv_I5').addClass('hidden');
}
}
and then
$(function() {myfunction});
so I can call that function on page load, but I don't wan't to loose the functionality the .change syntax is providing me (that it changes as the user interacts with the elements on the page also.
Apologies for the general and cumbersome levels of ignorance
You guessed how to define the function correctly — that is,
function myfunction()
{
if ($('#sv_I4b').attr('checked')||$('#sv_I4c').attr('checked')){
$('#sv_I5').removeClass('hidden');
} else {
$('#sv_I5').addClass('hidden');
}
}
works just fine. However, this:
$(function() {myfunction});
Should be written as:
$(myfunction); // Run on page load.
$('#myform').change(myfunction); // ...and also run it when the form changes.
However, that second line won't actually work until the page has loaded unless the form exists at the time the script runs, so you may want to change it to this:
$(function() { // On page load, run this anonymous function:
myfunction(); // Run the function now (where now, at this point, is page load).
$('#myform').change(myfunction); // ...as well as when the form changes.
});
$ is shorthand notation for jQuery, and essentially namespaces any functions to the jQuery framework.
my_form is a DOM selector. $('#my_form') wraps the matched DOM element up as a jQuery object, adding all sorts of useful methods and properties.
.change() is an event listener which, as you guessed, watches for change events on that jQuery object. It is a little inefficient - take a look .on() instead.
the most useful behaviour an anonymous function (closure) is to create private scope, something that javascript doesn't otherwise provide.
Is there a way to include a javascript file only once or declare a function only once? The issue I am having is that I have an HTML module that contains a javascript include. Well this module is loaded in a loop, and therefore that file is loaded multiple times. I've worked out most of the kinks, but what bothers me is that I know the same function is getting created multiple times, and this look can be as many as 30 iterations. To me, I don't like the fact that the same function is getting created over and over. Should I care? Is there a way I can prevent this? I know I can detect when a function exists, can I put the function declaration in between an if statement?
Update
I've tried out one of the suggestions:
if(typeof btnSendInvite_click != 'function')
{
function btnSendInvite_click()
{
alert("#invite_guest_" + $(this).attr("event_id"));
return false;
}
}
but that doesn't work. I've also tried
if(!btnSendInvite_click)
{
function btnSendInvite_click()
{
alert("#invite_guest_" + $(this).attr("event_id"));
return false;
}
}
but it doesn't work. What happens is that I have this line:
$(document).ready(function()
{
$(".btnSendInvite").bind("click", btnSendInvite_click);
});
and when the button gets clicked, that functions is executed six times, which is the amount of times that the file was included which tells me that the function is being created multiple times... I think.
Update
So after a lot of struggling, this problem is turning into something different than what I thought. The bind is being called multiple times, so it's getting bound multiple times, and therefore calling the function multiple times. I guess my next question is, is there a way to bind a function to a control only once? I've tried the jquery "one" already and it doesn't work.
Yes, you can (run on jsfiddle).
if (!window.myFunction) {
window.myFunction = function() {
//...
}
}
Edit: In your case it would be:
if (!window.btnSendInvite_click) {
window.btnSendInvite_click = function() {
alert("#invite_guest_" + $(this).attr("event_id"));
return false;
}
}
The call to bind() also has to be somewhere in that conditional block.
Note: The following variant won't work, at least not on all browsers:
if (!window.myFunction) {
function myFunction() {
//...
}
}
Edit 2: For your update:
Declare a variable when you call bind.
if (window.iBoundThatStuff!=true) {
iBoundThatStuff=true;
//call bind() here
}
Having JS included in a loop is ridiculous. Move your JS out of the loop.
JS can tell if function was defined but fixing bad server side loop in JS is definitively a bad practice.
Yes you should worry about not including your script file several times and not to declare the function several times...
For the first part, you may want to look into changing your html structure so the js file is only included once (even though js files are cached by the browser, and the second time may not actually go to the server -- depending of several factors... there's still a penalty)
Now as for declaring your function only once, remember that functions are also object (1st class citizens) in js, so you can test if a function is already define as if you were testing an object.... if(!window.myFunc) { window.myFunc = function(){} }...
You may want to look a bit into functions and scoping in js.. here are some links
http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/
http://www.yuiblog.com/blog/2010/02/24/video-crockonjs-3/
http://www.slideshare.net/douglascrockford/crockford-on-javascript-act-iii-function-the-ultimate