A function inside javascript if condition is not getting called - javascript

I am new to Js and trying to develop program which can move object in zig zag format across canvas, i wrote this function but it not getting called when i run program. If anyone can check out my code it would be really helpful, thanks also like to mention that all previous functions in code are working fine but this specific function is not getting called program run until If condition but skip the function part. Also i am not looking to work with Jquery or CSS right now
if (rightPos) {
function myInterval3() {
console.log('hello');
var eLeftPos1 = e.offsetLeft;
//console.log(e.offsetLeft);
e.style.left = (eLeftPos1 + s) + 'px';
//console.log(e.style.left);
}
}
var e = document.getElementById("aDiv");
var s = 1;
function myInterval() {
var eLeftPos = e.offsetLeft;
//console.log(e.offsetLeft);
e.style.left = (eLeftPos + s) + 'px';
//console.log(e.style.left);
leftPos = (eLeftPos + s) >= 300
if (leftPos) {
function myInterval1() {
console.log(leftPos)
var eTopPos = e.offsetTop;
//console.log(e.offsetLeft);
e.style.top = (eTopPos + s) + 'px';
//console.log(e.style.top);
topPos = (eTopPos + s) >= 100
if (topPos) {
clearInterval(internal1)
}
if (topPos) {
function myInterval2() {
var eRightPos = e.offsetLeft;
//console.log(eRightPos)
e.style.left = (eRightPos - 9) + 'px'
/*console.log(e.style.left)*/
rightPos = (eRightPos - 9) <= 20
if (rightPos) {
clearInterval(interal2)
}
}
var interal2 = setInterval(myInterval2, 10)
}
}
var internal1 = setInterval(myInterval1, 100);
if (rightPos) {
function myInterval3() {
console.log('hello');
var eLeftPos1 = e.offsetLeft;
//console.log(e.offsetLeft);
e.style.left = (eLeftPos1 + s) + 'px';
//console.log(e.style.left);
}
}
}
if ((eLeftPos + s) >= 300) {
clearInterval(internal)
}
}
var internal = setInterval(myInterval, 100);

You've defined a function named myInterval3, but you're not calling it. When you write
function myInterval3() { ... }
That defines a function named myInterval3, but that's all that it does. To actually have the code inside the function run, you need to call it.
myInterval3()
To have the function called on a repeating interval, use setInterval (like you have for your other functions:
setInterval(myInterval3, 100)

Related

How do I make A and B run in parallel?

How do I make A and B run in parallel?
async function runAsync(funcName)
{
console.log(' Start=' + funcName.name);
funcName();
console.log(' End===' + funcName.name)
};
function A()
{
var nowDateTime = Date.now();
var i = 0;
while( Date.now() < nowDateTime + 1000)
i++;
console.log(' A i= ' + i) ;
}
function B()
{
var nowDateTime = Date.now();
var i = 0;
while( Date.now() < nowDateTime + 1000)
i++;
console.log(' B i= ' + i) ;
}
runAsync(A);
runAsync(B);
The console shows that A starts first and B starts after A:
Start=A
A i= 6515045
End===A
Start=B
B i= 6678877
End===B
Note:
I am trying to use async for Chrome/Firefox, and keep the JS code compatible with IE11.
This C# code generates the proxy function runAsync:
if (isEI())
Current.Response.Write(" function runAsync(funcName){ setImmediate(funcName); }; ");
else
Current.Response.Write(" async function runAsync(funcName){ funcName(); } ");
https://jsfiddle.net/NickU/n2huzfxj/28/
Update.
My goal was to parse information and prepare (indexing and adding triggers) for an immediate response after user input. While the user is viewing the information, the background function has 3-10 seconds to execute, and the background function should not block UI and mouse and keyboard responses. Here is the solution for all browsers, including IE11.
Created a new Plugin to simulate parallel execution of funcRun during idle times.
Example of an original code:
$("input[name$='xxx'],...").each( function(){runForThis(this)}, ticksToRun );
The updated code using the Plugin:
$(document).zParallel({
name: "Example",
selectorToRun: "input[name$='xxx'],...",
funcRun: runForThis
});
Plugin.
(function ($)
{
// Plugin zParallel
function zParallel(options)
{
var self = this;
self.defaults = {
selectorToRun: null,
funcRun: null,
afterEnd: null,
lengthToRun: 0,
iterScheduled: 0,
ticksToRun: 50,
showDebugInfo: true
};
self.opts = $.extend({}, self.defaults, options);
}
zParallel.prototype = {
init: function ()
{
var self = this;
var selector = $(self.opts.selectorToRun);
self.lengthToRun = selector.length;
if (self.lengthToRun > 0)
{
self.arrayOfThis = new Array;
selector.each(function ()
{
self.arrayOfThis.push(this);
});
self.arrayOfThis.reverse();
self.opts.iterScheduled = 0;
self.whenStarted = Date.now();
self.run();
return true;
}
else
{
this.out('zParallel: selector is empty');
return false;
}
},
run: function ()
{
var self = this;
var nextTicks = Date.now() + self.opts.ticksToRun;
var _debug = self.opts.showDebugInfo;
if (self.opts.iterScheduled === 0)
{
nextTicks -= (self.opts.ticksToRun + 1); // Goto to Scheduling run
}
var count = 0;
var comOut = "";
while ((self.lengthToRun = self.arrayOfThis.length) > 0)
{
var curTicks = Date.now();
if (_debug)
{
comOut = self.opts.name + " |" + (curTicks - self.whenStarted)/1000 + "s| ";
if (self.opts.iterScheduled === 0)
this.out("START " + comOut + " remaining #" + self.lengthToRun);
}
if (curTicks > nextTicks)
{
self.opts.iterScheduled++;
if ('requestIdleCallback' in window)
{
if (_debug)
this.out(comOut + "requestIdleCallback , remaining #" + self.lengthToRun + " executed: #" + count);
window.requestIdleCallback(function () { self.run() }, { timeout: 1000 });
} else
{
if (_debug)
this.out(comOut + "setTimeout, remaining #" + self.lengthToRun + " executed: #" + count);
setTimeout(function (self) { self.run()}, 10, self);
}
return true;
}
var nexThis = self.arrayOfThis.pop();
self.opts.funcRun(nexThis);
count++;
}
if (self.opts.afterEnd!== null)
self.opts.afterEnd();
if (_debug)
this.out("END " + comOut + " executed: #" + count);
return true;
},
out: function (str)
{
if (typeof console !== 'undefined')
console.log(str);
}
};
$.fn.zParallel = function (options)
{
var rev = new zParallel(options);
rev.init();
};
})(jQuery);
// Examples.
(function ($)
{
var tab1 = $('#tbl1');
for (i = 0; i < 1000; i++)
$("<tr>"+
"<td>#" + i + "</td>"+
"<td><input id='a_" + i + "' value='" + i + "' >"+
"</td><td><input id='b_" + i + "' value='" + i + "' ></td></tr>")
.appendTo(tab1);
$(document).zParallel({
name: "A",
selectorToRun: "input[id^='a_']",
funcRun: function (nextThis)
{
var $this = $(nextThis);
var nowDateTime = Date.now();
var i = 0;
while( Date.now() < nowDateTime + 2)
i++;
$this.val( i );
if (i > 100)
$this.css('color', 'green').css('font-weight', 'bold');
else
$this.css('color', 'blue');
}
});
$(document).zParallel({
name: "B",
selectorToRun: "input[id^='b_']",
funcRun: function (nextThis)
{
var $this = $(nextThis);
var nowDateTime = Date.now();
var i = 0;
while( Date.now() < nowDateTime + 2)
i++;
$this.val( i );
if (i > 100)
$this.css('background', '#BBFFBB');
else
$this.css('background', '#FFBBBB');
}
});
})(jQuery);
https://jsfiddle.net/NickU/1xt8L7co/59/
The two example functions simply execute synchronously one after the other on the same "thread" (JS effectively has only one thread available to such scripts).
The use of async is irrelevant here because no truly asynchronous operation is occurring in function A - it is simply a busy while loop - so it completes in full before execution can move to anything else.
If function A had called an actual asynchronous operation (such as a HTTP request - not simply a synchronous operation wrapped in an async function), then function B may have a chance to start up (in which case B would complete entirely before the execution returned to A, because B is also only contains a synchronous, busy while loop).
Parallel processing can be achieved with WebWorkers which allowing running on background threads (actual separate threads).

Calling functions from within functions JS

I'm writing a small battleships game, and I'm refactoring my code using Javascript Objects, a tool that I am not very familiar with. I would like to be able to call a function from within a function using objects, and I cannot seem to work out how to do this. The code is here:
<script>
var xPos;
var yPos;
var boatGrid = {
selectPos : function() {
console.log("it works"); //want to try calling function addNumber() here
for (boatNum = 1; boatNum < 4; boatNum++) {
xPos = Math.floor(Math.random() * 8);
yPos = Math.floor(Math.random() * 10 + 1);
}
},
buildBoat : function() {
console.log("this works too");
for (boatLen = 1; boatLen < 4; boatLen++) {
xPos = xPos++;
boatPos = "cell_" + xPos + "_" + yPos;
}
},
addNumber : function() {
document.getElementById("test2").innerHTML = "hello"; //debug line
}
}
The addNum() function is there as a debug.
You are almost there.
In your case boatGrid is an object and addNumber is one of it's method. so use this.addNumber()
var xPos;
var yPos;
var boatGrid = {
selectPos : function() {
console.log("it works"); //want to try calling function addNumber() here
this.addNumber(); // Changed here
for (boatNum = 1; boatNum < 4; boatNum++) {
xPos = Math.floor(Math.random() * 8);
yPos = Math.floor(Math.random() * 10 + 1);
}
},
buildBoat : function() {
console.log("this works too");
for (boatLen = 1; boatLen < 4; boatLen++) {
xPos = xPos++;
boatPos = "cell_" + xPos + "_" + yPos;
}
},
addNumber : function() {
//document.getElementById("test2").innerHTML = "hello"; //debug line
document.write('<pre>Add Number called</pre>')
}
}
boatGrid.selectPos();
jsfiddle
Use
this.addNumber();
Your code should look like this
selectPos : function() {
console.log("it works");
this.addNumber(); //want to try calling function addNumber() here
for (boatNum = 1; boatNum < 4; boatNum++) {
xPos = Math.floor(Math.random() * 8);
yPos = Math.floor(Math.random() * 10 + 1);
}
},
If you want to call boatGrid.selectPos() and call the addNumber function within the selectPos function, just add this.addNumber(); within the selectPos function.
selectPos : function() {
console.log("it works");
this.addNumber(); // <---- boatGrid calls addNumber()
for (boatNum = 1; boatNum < 4; boatNum++) {
xPos = Math.floor(Math.random() * 8);
yPos = Math.floor(Math.random() * 10 + 1);
}
}
When used within an object function, this refers to the object calling the function.
So to go with my original example, boatGrid calls selectPos, so this within the selectPos function refers to boatGrid.
So then this.addNumber() will have that boatGrid object call its addNumber function.

Javascript src Variable Not Detected by Script

The script file and the jsfile reside together on an Apache homepage server.
In the head section of index.html we have
<script type="text/javascript" src="someurl/jsfile.js"></script/>
And in the scriptfile we refer to jsfile by
function init_disp() {array_len = jsfile.length...
Running the scriptfile with or without someurl produces an "'jsfile' is undefined" error. Is there a problem here, or if the server software is blocking the script, does it do it by nulling the variables?
Using IE11 with enhance protect and 64 bit enhance protect, 64 bit Java.
Edit: The entire scriptfile (not my own) is this:
addEvent(window,"load",init_disp);
addEvent(document,"click",show_init);
// function to add an event listener
function addEvent(o,e,f) {
if (o.addEventListener) {
o.addEventListener(e,f,false);
return true;
}
else if (o.attachEvent) {
return o.attachEvent("on"+e,f);
}
else {
return false;
}
}
// integer "random()"
function rand (n)
{
return (Math.floor( Math.random ()*n));
}
// BEGIN customization settings
var char_pause = 60; // pause on each character, milliseconds
var quote_pause = 8000; // pause to show complete quote, milliseconds
// END customization settings
var quoteindex;
var quote,attribution;
var pos;
var box;
var array_len;
var quote_len,attrib_len;
var interval = null;
var busy;
var cursor_span = "<span class=\"quotefont quotecursor\">";
var hide_span = "<span class=\"quotefont hidecolor\">"
var attr_div = "<p></p><div class=\"quotefont attrib\">";
function init_disp() {
array_len = jsfile.length;
box = document.getElementById("quotebox");
quoteindex = rand(array_len);
show_init();
}
function show_init() {
busy = false;
clearInterval(interval);
quote_array = jsfile[quoteindex].split("\t");
quote = quote_array[0];
attribution = quote_array[1];
quote_len = quote.length;
attrib_len = attribution.length;
quoteindex = (quoteindex+1) % array_len;
pos = 0;
interval = setInterval('show_quote()',char_pause);
}
function show_quote() {
pos++;
if(!busy) {
busy = true;
if(pos <= quote_len) {
box.innerHTML = quote.substring(0,pos) +
cursor_span +
quote.substring(pos,pos+1) +
"</span>" +
hide_span +
quote.substring(pos+1) +
"</span>";
}
busy = false;
}
if(pos > quote_len) {
pos = 0;
clearInterval(interval);
interval = setInterval('show_attr()',char_pause);
}
}
function show_attr() {
pos++;
if(!busy) {
busy = true;
if(pos <= attrib_len) {
var attr = attribution.substring(0,pos);
box.innerHTML = quote + attr_div + attr + "</div>";
}
busy = false;
}
if(pos > attrib_len) {
clearInterval(interval);
interval = setInterval('show_init()',quote_pause);
}
}
When you load a Javascript file using <script> tag, that file gets executed, not loaded as a Javascript object.

Wait until setInterval() is done

I would like to add a small dice-rolling effect to my Javascript code. I think a good way is to use the setInterval() method. My idea was the following code (just for testing):
function roleDice() {
var i = Math.floor((Math.random() * 25) + 5);
var j = i;
var test = setInterval(function() {
i--;
document.getElementById("dice").src = "./images/dice/dice" + Math.floor((Math.random() * 6) + 1) + ".png";
if (i < 1) {
clearInterval(test);
}
}, 50);
}
Now I would like to wait for the setInterval until it is done. So I added a setTimeout.
setTimeout(function(){alert("test")}, (j + 1) * 50);
This code works quite okay.
But in my main code the roleDice() function returns a value. Now I don’t know how I could handle that... I can’t return from the setTimeout(). If I add a return to the end of the function, the return will rise too fast. Does anyone have an idea, of how I could fix that?
Edit
Hmm, okay I understand what the callback does and I think I know how it works but I have still the problem. I think it’s more of an "interface" problem...
Here is my code:
function startAnimation(playername, callback) {
var i = Math.floor((Math.random() * 25) + 5);
var int = setInterval(function() {
i--;
var number = Math.floor((Math.random() * 6) + 1);
document.getElementById("dice").src = "./images/dice/dice" + number + ".png";
if(i < 1) {
clearInterval(int);
number = Math.floor((Math.random() * 6) + 1);
addText(playername + " rolled " + number);
document.getElementById("dice").src = "./images/dice/dice" + number + ".png";
callback(number);
}
}, 50);
}
function rnd(playername) {
var callback = function(value){
return value; // I knew thats pointless...
};
startAnimation(playername, callback);
}
The function rnd() should wait and return the value… I’m a little bit confused. At the moment I have no clue how to going on... The code wait for the var callback... but how I could combine it with the return? I would like to run the animation and return after that the last number with rnd() to another function.
You stumbled into the pitfall most people hit at some point when they get in touch with asynchronous programming.
You cannot "wait" for an timeout/interval to finish - trying to do so would not work or block the whole page/browser. Any code that should run after the delay needs to be called from the callback you passed to setInterval when it's "done".
function rollDice(callback) {
var i = Math.floor((Math.random() * 25) + 5);
var j = i;
var test = setInterval(function() {
i--;
var value = Math.floor((Math.random() * 6) + 1);
document.getElementById("dice").src = "./images/dice/dice" + value + ".png";
if(i < 1) {
clearInterval(test);
callback(value);
}
}, 50);
}
You then use it like this:
rollDice(function(value) {
// code that should run when the dice has been rolled
});
You can now use Promises and async/await
Like callbacks, you can use Promises to pass a function that is called when the program is done running. If you use reject you can also handle errors with Promises.
function rollDice() {
return new Promise((resolve, reject) => {
const dice = document.getElementById('dice');
let numberOfRollsLeft = Math.floor(Math.random() * 25 + 5);
const intervalId = setInterval(() => {
const diceValue = Math.floor(Math.random() * 6 + 1);
// Display the dice's face for the new value
dice.src = `./images/dice/dice${diceValue}.png`;
// If we're done, stop rolling and return the dice's value
if (--numberOfRollsLeft < 1) {
clearInterval(intervalId);
resolve(diceValue);
}
}, 50);
});
}
Then, you can use the .then() method to run a callback when the promise resolves with your diceValue.
rollDice().then((diceValue) => {
// display the dice's value to the user via the DOM
})
Or, if you're in an async function, you can use the await keyword.
async function takeTurn() {
// ...
const diceValue = await rollDice()
// ...
}
Orginally your code was all sequential. Here is a basic dice game where two players roll one and they see who has a bigger number. [If a tie, second person wins!]
function roleDice() {
return Math.floor(Math.random() * 6) + 1;
}
function game(){
var player1 = roleDice(),
player2 = roleDice(),
p1Win = player1 > player2;
alert( "Player " + (p1Win ? "1":"2") + " wins!" );
}
game();
The code above is really simple since it just flows. When you put in a asynchronous method like that rolling the die, you need to break up things into chunks to do processing.
function roleDice(callback) {
var i = Math.floor((Math.random() * 25) + 5);
var j = i;
var test = setInterval(function(){
i--;
var die = Math.floor((Math.random() * 6) + 1);
document.getElementById("dice").src = "./images/dice/dice" + die + ".png";
if(i < 1) {
clearInterval(test);
callback(die); //Return the die value back to a function to process it
}
}, 50);
}
function game(){
var gameInfo = { //defaults
"p1" : null,
"p2" : null
},
playerRolls = function (playerNumber) { //Start off the rolling
var callbackFnc = function(value){ //Create a callback that will
playerFinishes(playerNumber, value);
};
roleDice( callbackFnc );
},
playerFinishes = function (playerNumber, value) { //called via the callback that role dice fires
gameInfo["p" + playerNumber] = value;
if (gameInfo.p1 !== null && gameInfo.p2 !== null ) { //checks to see if both rolls were completed, if so finish game
giveResult();
}
},
giveResult = function(){ //called when both rolls are done
var p1Win = gameInfo.p1 > gameInfo.p2;
alert( "Player " + (p1Win ? "1":"2") + " wins!" );
};
playerRolls("1"); //start player 1
playerRolls("2"); //start player 2
}
game();
The above code could be better in more of an OOP type of way, but it works.
There are a few issues for the above solutions to work. Running the program doesn't (at least not in my preferred browser) show any images, so these has to be loaded before running the game.
Also, by experience I find the best way to initiate the callback method in cases like preloading N images or having N players throw a dice is to let each timeout function do a countdown to zero and at that point execute the callback. This works like a charm and does not rely on how many items needing to be processed.
<html><head><script>
var game = function(images){
var nbPlayers = 2, winnerValue = -1, winnerPlayer = -1;
var rollDice = function(player,callbackFinish){
var playerDice = document.getElementById("dice"+player);
var facesToShow = Math.floor((Math.random() * 25) + 5);
var intervalID = setInterval(function(){
var face = Math.floor(Math.random() * 6);
playerDice.src = images[face].src;
if (--facesToShow<=0) {
clearInterval(intervalID);
if (face>winnerValue){winnerValue=face;winnerPlayer=player}
if (--nbPlayers<=0) finish();
}
}, 50);
}
var finish = function(){
alert("Player "+winnerPlayer+" wins!");
}
setTimeout(function(){rollDice(0)},10);
setTimeout(function(){rollDice(1)},10);
}
var preloadImages = function(images,callback){
var preloads = [], imagesToLoad = images.length;
for (var i=0;i<images.length;++i){
var img=new Image();
preloads.push(img);
img.onload=function(){if(--imagesToLoad<=0)callback(preloads)}
img.src = images[i];
}
}
preloadImages(["dice1.png","dice2.png","dice3.png","dice4.png","dice5.png","dice6.png"],game);
</script></head><body>
<img src="" id="dice0" /><img src="" id="dice1" /></body></html>
To achieve that goal, using vanilla setInterval function is simply impossible. However, there is better alternative to it: setIntervalAsync.
setIntervalAsync offers the same functionality as setInterval, but it guarantees that the function will never executed more than once in a given interval.
npm i set-interval-async
Example:
setIntervalAsync(
() => {
console.log('Hello')
return doSomeWork().then(
() => console.log('Bye')
)
},
1000
)
Example with Promises & setIntervals.. this is how I created a 'flat' chain of functions that wait until the other is completed...
The below snippet uses a library called RobotJS (here it returns a color at a specific pixel on screen) to wait for a button to change color with setInterval, after which it resolves and allows the code in the main loop to continue running.
So we have a mainChain async function, in which we run functions that we declare below. This makes it clean to scale, by just putting all your await someFunctions(); one after each other:
async function mainChain() {
await waitForColorChange('91baf1', 1400, 923)
console.log('this is run after the above finishes')
}
async function waitForColorChange(colorBeforeChange, pixelColorX, pixelColorY) {
return new Promise((resolve, reject) => {
let myInterval = setInterval(() => {
let colorOfNextBtn = robot.getPixelColor(pixelColorX, pixelColorY)
if (colorOfNextBtn == colorBeforeChange) {
console.log('waiting for color change')
} else {
console.log('color has changed')
clearInterval(myInterval);
resolve();
}
}, 1000)
})
}
//Start the main function
mainChain()

Magento - this javascript file doesn't merge correctly

i have a magento 1.6.2 webshop.
I would like to merge the javascript files for optimizing my loadingspeeds.
But when i select merge in the settings my Custom Menu extensions doesn't work anymore.
I guess there is something wrong in the code.
I have tried to contact the developer, but i don't get a reaction ...
This extension is for the navigation menu at the top (with images)
Here is the code of the custommenu.js file:
function wpShowMenuPopup(objMenu, popupId)
{
objMenu = $(objMenu.id); var popup = $(popupId); if (!popup) return;
popup.style.display = 'block';
objMenu.addClassName('active');
var popupWidth = CUSTOMMENU_POPUP_WIDTH;
if (!popupWidth) popupWidth = popup.getWidth();
var pos = wpPopupPos(objMenu, popupWidth);
popup.style.top = pos.top + 'px';
popup.style.left = pos.left + 'px';
if (CUSTOMMENU_POPUP_WIDTH) popup.style.width = CUSTOMMENU_POPUP_WIDTH + 'px';
}
function wpPopupPos(objMenu, w)
{
var pos = objMenu.cumulativeOffset();
var wraper = $('custommenu');
var posWraper = wraper.cumulativeOffset();
var wWraper = wraper.getWidth() - CUSTOMMENU_POPUP_RIGHT_OFFSET_MIN;
var xTop = pos.top - posWraper.top + CUSTOMMENU_POPUP_TOP_OFFSET;
var xLeft = pos.left - posWraper.left;
if ((xLeft + w) > wWraper) xLeft = wWraper - w;
return {'top': xTop, 'left': xLeft};
}
function wpHideMenuPopup(element, event, popupId, menuId)
{
element = $(element.id); var popup = $(popupId); if (!popup) return;
var current_mouse_target = null;
if (event.toElement)
{
current_mouse_target = event.toElement;
}
else if (event.relatedTarget)
{
current_mouse_target = event.relatedTarget;
}
if (!wpIsChildOf(element, current_mouse_target) && element != current_mouse_target)
{
if (!wpIsChildOf(popup, current_mouse_target) && popup != current_mouse_target)
{
popup.style.display = 'none';
$(menuId).removeClassName('active');
}
}
}
function wpIsChildOf(parent, child)
{
if (child != null)
{
while (child.parentNode)
{
if ((child = child.parentNode) == parent)
{
return true;
}
}
}
return false;
}
You can see it working on my webshop: www.liefstoereigenwijs.nl
Can anyone see if there is something wrong in the code?
Or has a other solution for my problem?
problem is automatically solved in 1.7.0.2
End each
function xx(x)
{
...
}
with a ; at the end!
So:
function xx(x)
{
...
};

Categories