In the course of updating some code, I need to replace the anonymous function
element.mousemove(function (event) {.......
with a named function. I tried replacing it with
element.mousemove = moveMouse;
function moveMouse(event) {.......
but this causes the code to fail.
Can anyone please explain to me why the two above code blocks don’t do exactly the same thing (execute the code that follows the anonymous function call, or is contained in the moveMouse function) ?
No error, nothing shows in the error console, the function just does not fire.
The code was working before. All I did was replace the upper block of code above with the lower block, and add the required closing parenthesis at the end of the function (no syntax errors). This caused the code to stop working.
I see!
Firstly, I am so sorry that “mousemove is not a native event” is wrong. I must correct that. mousemove event is one of standard mouse events described by W3C.
Secondly, for your question, it is an issue about how js engine process js code internally.
For your first code block:
element.mousemove(function(event){......})
which is not correct. I don’t know why you can run these correctly. If you wanna bind an mousemove event on element, you can write it like this:
element.onmousemove = function(event){......};
For your second code block:
element.onmousemove = mouseMove;
function mouseMove(event){.......};
When the js engine is entering execution context which is the first step of the process of execution code described by ECMAScript 262 3rd, js engine internally creates VO(Variable Object) which belongs to its own context. VO is used to store some variable declarations including following description said by ECMAScript: 1. formal parameters of function
2. function declaration(function identifier)
3. variable declaration
so, for your second code, VO for global context(implemented as a global object) is like this:
VO = {
mouseMove: func-----mouseMove(just a reference, the actual value(function content) will be updated at code execution stage which is the second stage of the process of execution code)
}
These is only mouseMove in the VO for no other declarations found at the entering execution context stage.
Then the js engine entering the stage of code execution. When it finds this statement: element.onmousemove = mouseMove; js engine will look up the VO for the value of mouseMove(just a reference, the actual value hasn’t been update yet). This is why nothing happens when you mouse the mouse on the element
After that, js engine finds the next statement: function mouseMove(event){…}
the value of mouseMove in VO will updated and points to the actual function content. Which means any statement using mouseMove will get the actual value.
In conclusion, you can correct your second code block like this to make it work:
function mouseMove(event){.....};
element.onmousemove = mouseMove;
Which just change the sequence of the two code lines but it can make the updating of the mouseMove in VO happen before the event binding statement.
so, mouseMove will get the actual correct value.
If you are still in puzzle. You can compare these two code blocks.
1.
Thanks RLM2008.
I check my test page carefully.
I write it like this: element.onmousemove = mouseMove;
var mouseMove = function…
In which, mouseMove is just a simple declaration and the value will be undefined. So, this code won’t work!
But, if I rewrite code like this: element.onmousemove = mouseMove;
function mouseMove(event){…}
This works well! So, “At the entering execution context stage, function declaration meant store the function identifier and the value was just an reference, the actual value would be updated at the code execution stage” as I said before was wrong. function declaration will make the value of function identifier point to the actual function body!
So, according to this theory, gavacho’s code will work as well as RLM2008’s demo!
gavacho, could you please retest your demo to check if this actually doesn’t work well!
Thanks everyone for the input. It is certain that the top block of code works (it was written by a more capable coder than myself). It is also certain that the bottom block of code doesn’t work. I have tested both repeatedly.
I can confirm that the bottom block of code, when using the correct event of onmousemove, certainly does work, because function declarations are created before the code runs. It’s just not a good idea to use a function before it’s declaration, as it leads to other sloppy situations too.
Sample test code:
<html>
<body>
<p id="aparagraph">A paragraph</p>
<script>
var element = document.getElementById('aparagraph');
element.onmousemove = moveMouse;
function moveMouse(event) {
alert(event);
}
</script>
</body>
</html>
element.onmousemove waits for the event to be triggered, whereas element.mousemove directly triggers the event.
It’s the same as element.onclick and element.click