call JS function only once - javascript

I'm working with the following function which runs fine but I only want to call it once - currently every time I use scroll, the function id triggered and as a result my animated charts get re-built.
window.onscroll = function() {
new Chart(document.getElementById("doughnut").getContext("2d")).Doughnut(doughnutData);
new Chart(document.getElementById("line").getContext("2d")).Line(lineChartData);
new Chart(document.getElementById("radar").getContext("2d")).Radar(radarChartData);
}
thanks!!!!

var isNotScrolled = true;
window.onscroll = function() {
if(isNotScrolled)
{
new Chart(document.getElementById("doughnut").getContext("2d")).Doughnut(doughnutData);
new Chart(document.getElementById("line").getContext("2d")).Line(lineChartData);
new Chart(document.getElementById("radar").getContext("2d")).Radar(radarChartData);
isNotScrolled = false;
}
}
You may also consider using jQuery with waypoint plugin, that may help you doing exactly what you want.

Related

open window and run function on that window

I'd like to open a new window, this window has a list of objects, and these objects should be filtered based on a selection from the previous window. I figured I can filter the list through a function, but how do I run said function?
This is what I am able to do:
var popup = window.open('pageURL');
$(popup.document).ready(function() {
// this is where function should be
popup.alert('HelloWorld');
});
But how do I change the alert to a function?
If I have a function on my other app , function test() { alert('HelloWorld'};
How do I run this function from my first app?
Swapping popup.alert('HelloWorld'); with popup.test(); did not work.
You need the reference to the window opened to call functions in the new window, like:
var oNewWindow = window.open("new.window.url", "mywindow");
oNewWindow.onload = function(){oNewWindow.window.newWindowFunction();};
I ended up with this solution
var popup = window.open('http://s234-0057/actiontracker/SiteAssets/Avvik/html/app.aspx');
var readyStateCheckInterval = setInterval(function() {
if (popup.document.readyState === "complete") {
clearInterval(readyStateCheckInterval);
popup.test();
}
}, 50);
Where I check if the popup window is ready, and when it is, cancel check and run function. Solution is from top answer on this question, by #this.lau_
You can write it like this:
function myFunction(){
alert('HelloWorld');
}
var popup = window.open('pageURL');
$(popup.document).ready(function() {
popup.eval(myFunction + "");
popup.myFunction();
});
myFunction in file that contains this code will run in page with pageURL address.

Issue with variables scope in Js/Jquery

Having issue with - what I supposed to be - basics scope fundamentals.
I am using Javascript with Require JS structure, here are where the issue occurs:
function GameManager() {
//This is the constructor of gamemanager.js file
this.body = $('body');
this.game = $('#game');
}
GameManager.prototype.createGame = function() {
//Code
//this line works
this.body.append(//Some HTML);
}
GameManager.prototype.showGame = function() {
//Code
//this line does not work wtf
this.game.removeClass("display-none");
//and this one does work.
$("#game").removeClass("display-none");
}
I am using this.body succefully so I want to use the same way for this.game but it doesnt work. I can manage to make it work by using directly $("#game") but it's making jquery running through the DOM everytime so not really optimized...
I certainly am missing some basics points here, can someone explain ?
Thanks
This is working for me. I can remove display-none class from div without a problem. It wont display however. You need to change css. this.body.css("display","block"); for example.
window.onload = function() {
function GameManager() {
//This is the constructor of gamemanager.js file
this.body = $('body');
this.game = $('#game');
}
GameManager.prototype.createGame = function() {
//Code
//this line works
this.body.append();
}
GameManager.prototype.showGame = function() {
//Code
this.body.css("display", "block");
//this line does not work wtf
this.game.removeClass("display-none");
//and this one does work.
//$("#game").removeClass("display-none");
}
var myGame = new GameManager();
myGame.showGame();
}

setInterval() not firing

I am trying to run some code endlessly. I want to use the setInterval() method for that. The problem I am having with my program is that it is not getting executed at all. I tried to find the error using the browser's console but it does not say any error. I checked all the methods that are called before setInterval() are exectued properly. Here is the basic code :-
"use strict";
var Main = {
//properties
initialize:
setInterval(this.gameLoop, 15);
},
gameLoop: function(){
}
//other methods
}
window.addEventListener("load", Main.initialize, false);
The problem is that this is referencing the window object instead of the main object. See this Fiddle
Solution 1
Change the setInterval to:
setInterval(Main.gameLoop, 15);
Solution 2
Change the load event to:
window.addEventListener("load", function() { Main.initialise.call(Main); }, false);
Object Way
function Main() {
// The constructor
}
Main.prototype.initialise = function() {
setInterval(function() {
this.gameLoop();
}, 15);
}
Main.prototype.gameLoop = function() {
// Do gameloop stuff
}
var main = new Main();
window.addEventListener("load", function() {
main.initialise();
}, false);
Please note, I'm using initialise instead of initialize because its how I spell it (Just in case you direct copy paste and wonder why its not working for some bits)

escape from setInterval at end of game level

I'm writing a game using HTML5 canvas and Javascript. I'm using setInterval to animate the game and check for events at regular intervals. I've written multiple levels for the game, but I can't seem to escape the setInterval when a given level ends in order to start the next one. The code accurately detects when a level is won or lost and successfully clears the interval and renders the button, but the button does not fire.
Adding a button was my latest idea. I've also tried removing the canvas using jQuery and inserting a new one. I've also tried using clearRect on the canvas but it doesn't fire either.
Given that I can't return a value from setInterval, what are my options, if any? Is there another way to accomplish the same thing? Is there a separate error with my code that I've overlooked? Thanks!
Game.prototype.win = function(int) {
clearInterval(int);
var content = "<p style='color:white;'>You win</p><br><button id='next-level'>Next Level</button></menu>"
$('#controls').append(content)
};
Game.prototype.lose = function(int) {
clearInterval(int);
var content = "<p style='color:white;'>You Lose</p><br><button id='next-level'>Start Over?</button></menu>"
$('#controls').append(content)
};
Game.prototype.run = funtion () {
$('#start').click( function () {
$('#controls').empty();
var waveOne = new window.CrystalQuest.Wave(this.X_DIM, this.Y_DIM, this, Game.WAVE_ONE)
var game = this
var int = setInterval( function () {
if (waveOne.step() === "lost" ) {
game.lose(int);
} else if (waveOne.step() === "won") {
game.win(int);
}
waveOne.draw(this.ctx)
}, 20)
this.bindKeyHandlers(waveOne);
}.bind(this));
$('#next-level').click( function () {
$('#controls').empty();
...more code...
});
};
To stop a setInterval() you have to store the returned value from the original call to setInterval() in some persistent location and then call clearInterval() on that value.
Because you declared your interval with var as in var int, it was local only to that method and was not available anywhere else in the code.
There are a number of ways to do that in your code. I would probably suggest storing it as an instance variable like this:
Game.prototype.run = funtion () {
$('#start').click( function () {
$('#controls').empty();
var waveOne = new window.CrystalQuest.Wave(this.X_DIM, this.Y_DIM, this, Game.WAVE_ONE)
var game = this;
this.stop();
this.interval = setInterval( function () {
if (waveOne.step() === "lost" ) {
game.lose(int);
} else if (waveOne.step() === "won") {
game.win(int);
}
waveOne.draw(this.ctx)
}, 20)
this.bindKeyHandlers(waveOne);
}.bind(this));
$('#next-level').click( function () {
$('#controls').empty();
...more code...
});
};
Then, you can make a method that will stop the interval like this:
Game.prototype.stop = function() {
if (this.interval) {
clearInterval(this.interval);
this.interval = null;
}
}
And, change your other methods like this:
Game.prototype.win = function(int) {
this.stop();
var content = "<p style='color:white;'>You win</p><br><button id='next-level'>Next Level</button></menu>"
$('#controls').append(content)
};
Game.prototype.lose = function(int) {
this.stop();
var content = "<p style='color:white;'>You Lose</p><br><button id='next-level'>Start Over?</button></menu>"
$('#controls').append(content)
};
For your event handling issues, if you are destroying and recreating a button, then you will lose any event handlers that were attached to any DOM elements that got replaced.
You have two choices for how to fix it:
After you create the new DOM elements, you can again set the event handlers on the new DOM elements.
You can use "delegated event handling". This attaches the event handlers to a parent DOM object that is itself not replaced. The click event bubbles up to the parent and is handled there. The child can be replaced as many times as you want and the event handler will still work.
See these references for how to use delegated event handling with jQuery:
Does jQuery.on() work for elements that are added after the event handler is created?
jQuery .live() vs .on() method for adding a click event after loading dynamic html
JQuery Event Handlers - What's the "Best" method

Switching from GridView to ListView when Windows Store app is snapped

I am trying to change the layout of my listView control from "GridView" to "ListView" when application gets snapped. Of course, it should return to "GridView" in any other state. I wrote some code, but it doesn't work, so I wonder why...
This is the code I've written:
var viewState = Windows.UI.ViewManagement.ApplicationView;
var list = document.getElementById("messageDisplay").winControl;
if (viewState == Windows.UI.ViewManagement.ApplicationViewState.snapped) {
list.layout = new WinJS.UI.ListLayout();
}
else
{
list.layout = new WinJS.UI.GridLayout();
}
As taken from here simply listen for the resize event and make the changes to your listview's layout property.
I can't tell wher ein your code you are calling the similar code, so here is the entire method you'll need
window.addEventListener("resize", function (e) {
var currentViewState = Windows.UI.ViewManagement.ApplicationView.value;
var snapped = Windows.UI.ViewManagement.ApplicationViewState.snapped;
if (currentViewState === snapped) {
that.listView.layout = new WinJS.UI.ListLayout();
}
else if (lastViewState === snapped && currentViewState !== snapped) {
that.listView.layout = new WinJS.UI.GridLayout();
}
lastViewState = currentViewState;
});
Try invoking list.forceLayout() it saved my life many times... ;-)

Categories

Resources