Understanding Threading in javascript - javascript

I have two div's in my html page
<div id="box1">
</div>
<div id="box2">
</div>
Both of them are absolutely positioned at different positions.
#box1,#box2 {
height: 100px;
width: 100px;
background-color: red;
position: absolute;
}
#box2 {
top :200px;
}
In my Javascript I am animating these two div's as shown below
$(document).ready(function() {
function animateBoxes() {
$("#box1").animate({left : "500px"},5000);
$("#box2").animate({left : "500px"},3000);
}
animateBoxes();
});
When my page loads both the div's start moving at the same time.
My question is if javascript is single threaded how can both the div's move at the same time.
Because the movement of the div's is handled by javascript by two animate functions, one on box1 and other on box2.
How both the animate functions got executed at the same time?

Javascript is single threaded meaning something if is stuck the whole script is stuck...and only way overcome this is spawn worker. To answer your question, Do You Know how animate function of jquery works...it sets timer to call function that updates div's position. So both div get positioned a little bit toward their goal. Timer is provided by javascript and is handled like an event. Javascript has event loop..which is reiterated by browser. Meaning as soon as js is done browser goes through all events and check if they have been fired and then run the function that is associated with them. Here animate function associate itself to timer event and gradually updates div's position, thus looking like it animated. And since it happens in steps the whole js doesn't have to wait for this animation to end to continue executing.
This is how events basically work in js:
browser starts executing the code..
every next action waits till last action is done.
when javascript reaches the code that is attaching function to event, js registers the event, let's say click event. Now it know that button has click event and it has this function.
Now after all code below has been executed browser starts new routine. To check for any event that have been fired.
...looping but no events..
you click button ...it adds that click event has fired to event loop check list.
browser again checks the event loop...it sees the event.
it runs the code for that event and clear it...
suppose you clicked two times...then the code of second event won't start executing till the first is done.
Timer is same but it fires every x amount of time has passed. But as you can see event loops gets stucked executing the function related to the event...the timer is not perfect.
let's say you set timer for 10 ms. And as 9ms had passed you clicked the button starting another event. So your button event starts executing..but it did something really long that took 5 ms.
so your timer actually fires at 14ms.
Take a look at this example: http://jsfiddle.net/82zLC/6/
This will give you idea that animation is divided into chunks which are update step by step...try changing t to 60.

JavaScript can act asynchronous in many situations. .animate() is an example of this. It pretty much has to act asynchronous, in order to not interrupt other page processes. If you are looking for the events to happen one-after-the-other, try looking into callbacks:
$("#box1").animate({left: "500px"},5000, function(){
$("#box2").animate({left: "500px"},5000);
});
When we pass the function to .animate(), it calls the function after it is done with the animation.

Related

Methods to prevent triggering more than one event-functions in javascript

I have two events, one that triggers on touchstart and one that triggers on the custom event longTouch.
events: {
"touchstart .o_slide": "startDragEventHandler",
"longTouch .overview .o_slide": "slidePreview"
},
Basically, I need to make sure, that only one of the events fires at a time, to make sure, that when the users makes a longTouch to preview a slide (the slidePreview function), then the startDragEventHandler can't also be firing.
Problem is, that if the user longTouches to create e preview, but moves the finger just a little bit, then the drag functions will also initiate, messing up the UX.
Can I write code in one of the functions, that makes sure they other function will return before executing the body? Which different methods applies to this problem?

I'm having issues with clearTimeout() on a quotes rotator

I'm using this Codrops Blueprint to create a quotes rotator. I modified the rotator to have a next button, powered by the code below:
_startRotator: function() {
if (this.support) {
this._startProgress();
}
var timeout = setTimeout($.proxy(function() {
if (this.support) {
this._resetProgress();
}
this._next();
this._startRotator();
}, this), this.options.interval);
$(".testimonial-next").click($.proxy(function() {
clearTimeout(timeout);
if (this.support) {
this._resetProgress();
}
this._next();
this._startRotator();
}, this));
},
I added the .click function below the setTimeout function, and added the var to the setTimeout function.
When .testimonial-next is clicked, the rotator's timer is reset and the code in the timer is instantly executed. As far as I can tell, the timer restarts itself, so I shouldn't have to add code to do this.
On the website where this is put to use (see the "Testimonials" section), however, there seems to be a problem. There should be five quotes, in the order of Kim, Lynn, Shannon, Jennifer, and Chris. If the timer runs without being interrupted, everything works as expected. If the Next button is clicked, certain quotes seem to be skipped. Other times, the quotes stop rotating or randomly rotate at a high speed.
What am I doing wrong?
Your button click handler is attached again and again to the button, making a click result in several executions of the same code.
To solve this you can best move that piece of code out of the _startRotator function and move it somewhere where it will only be executed once.
That way, when you click, there will be only one handler that gets executed.
Less nice, but also a solution, would be to keep the code where it is, but always first remove any existing click handler, before you attach it again:
$(".testimonial-next").off('click').on('click', $.proxy(function() {
// etc...
But this is really an ugly solution. Try to move the code.

Code impact inside click event?

element.onclick = function() {
myFunction();
};
function myFunction() {
// 100, 500 or 1000 lines of code
}
Does and if yes, how does code inside the click event impacts the weight of click event?
PS! Im interested in code impact in event listener overall, not just a function like in my example. What if there was 500 lines of code instead of function?
Does it matter how big is myFunction() code?
Does it get processed before click event is triggered?
I do not mean the impact on the moment it's pressed but before this: if event is attached to element.
Im asking this because I need to attach the same click event to many elements and the code inside is pretty big. Event delegation is not an option in my situation. An example:
for(i = 0; i < 500; i++) {
//Just for the sake of this example
var element = document.createElement('div');
element.onclick = function() {
myFunction();
};
}
function myFunction() {
// 100, 500 or 1000 lines of code
}
Based on this example, should I be thinking about or worried about the size of myFunction()?
You function will be processed by the JavaScript runtime when it reads in the file. It will be invoked when you call it in the callback. The time for the callback to invoke the function will be no different if the function is 10 lines or 1000 lines.
Edit:
You may notice the execution time of the function change, as the amount of code increases, but invocation shouldn't change. Things that change invocation speed are looking up nested functions in objects: obj1.obj2.obj3.obj4.obj5.func() would be slower than a top-level func() definition (shouldn't be drastically different if it is not nested deep in large objects).
First, Javascript is a single threaded ecosystem.
There is a big eventloop which executes one event after another.
In case your onclick takes ages, you might see the prominent "A script is not responding"
The processing happens when you click it.
The "big event loop" reads the click event and calls all your event handlers for it. So the clicking triggers all the click event handlers being processed. (for the elements that are under your click area)
In case your problem is a not responding script, you could try WebWorkers. I never played with those, as it´s rather new.
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers
Regarding your 500 elements with the same click handler... You can only click one item at a time, no?
Maybe try
event.stopPropagation();

Javascript Double moving game problome

In my game, when you die a game over screen but for some reason when you click main menu, then level one again, and move to the left or right it double moves him? Every time you click start I made it so that it resets it again just in case maybe that is why? here is the function that i think might be causing the problome?
$('#yes').click(function() {
$("#levelOne").css('margin-top', '-1520px');
$("#player").css('border', 'solid 1px green')
$("#player").css('margin-left', '223px');
$('#levelComplete').hide();
$('#levelOne').animate({
'margin-top': '+=1520px'
}, speed);
handleCollisions()
$('#startLevel1').hide();
});
link: http://jsfiddle.net/8h7n2oca/20/
Any thing helps, thanks
When the game resets, sounds like an event is being re-bound to your player (resulting in 2 duplicate events bound to your player) Make sure to unbind all relevant events on gameover / be careful in rebinding.
Thanks for the fiddle, I took at a look at your code. When you start the game, you call the function levelOne(), inside this function the following code runs:
document.addEventListener('keydown', function (evt) { /* your logic */ }
This code is binding an event listener on the keydown event to the document. When you call levelOne() after the game ends, this code runs again. Now you have two listeners bound to the document. So when you go to move your player, the code is fired twice.
Abstracting your game set up logic to a separate function to be run once on page load as suggested by GameAlchemist sounds like a good approach to prevent duplicate bindings and optimize your code.

onmouseover and onmouseout functions containing intervals not executing correctly

I am doing some experimentation with JavaScript and I have a list of 4 items displayed horizontally, with each list item having an onmouseover and onmouseout event assigned.
The onmouseover event for each item executes a function which increases the height of the item over time using an interval.
the outmouseover event for each item executes a function which then reduces the height of the item to its default value over time using another interval.
It is working in the following scenario:
When I trigger the onmouseover for a list item the height increases as expected, and when I take the mouse off the list item the height then decreases as expected.
The problem is however, it doesn't seem to work in the following scenario:
When I trigger the onmouseover for a list item the height increases as expected, however if I trigger another onmouseover event for another list item before the item has returned to its original size, the onmouseout function for the previous list item does not finish executing.
Sorry if I am lacking any detail, evidently I am incredibly bad at explaining things.... So I have a link to the source code and a site where you can test the code to see what is happening.
Maybe I do not have as much of a knowledge of javascript as I thought, so while a solution or fix would be amazing, I am also happy to accept any advice or some kind of explanation as to why this could be happening.
I thought initially that multiple interval timers could not execute simultaneously, until after some research I found they can. So now I am thinking if it is a conflict between the onmouseover and onmouseout events.
Any advice, guidance or a solution would be extremely appreciated!
Source:
https://docs.google.com/open?id=0B6XLOOGyKVdWVkpSUklmMVI5QUk
Testing Site:
http://www.play-hookey.com/htmltest/
(just copy the contents of that google document and paste into the html text area in the site to see what I am talking about)
Your code:
icon.onmouseover = function(){ enlarge(this, icon.ID); };
icon.onmouseout = function(){ reduce(this, icon.ID); };
Correct code:
icon.onmouseover = function(){ enlarge(this, this.ID); };
icon.onmouseout = function(){ reduce(this, this.ID); };
What happened: you bindded an event with a function and passed variables to it. After each for loop, you redefined that function variable (so at the end, your icon.ID=3). That means that all on event called functions where using same icon.ID=3.
I hope that make sense...

Categories

Resources