Inconsistent Javascript
Jun. 9th, 2019 11:14 am![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
![[community profile]](https://www.dreamwidth.org/img/silk/identity/community.png)
Code below updated 10 Jun 12:50.
I'm trying to get the (x,y) sizes of two images for use in later calculations.
In FF67, the test page loads, as do the images, but the reported sizes are all zero, however, if I press F5 and reload, the page works perfectly.
In Chrome75, despite loading, the image sizes are consistently zero, and the code crashes after test 3.
Can anyone see what I'm doing wrong?
The initial problem's been sorted by using onload to call routines to get the image sizes after they've loaded. The cookie handling seems to be working okay in FF.
Now I'm fining the main code is chugging along on it's own and looks like it's finishing execution before the onload routines have even been called. Now to find a way to make the code wait for them.
It's still working okay with F5 on FF, but Chrome still isn't seeing the one image's values from the other image's routine.
Okay, using SetTimeout to add a 100ms delay to the execution of the final cookie read seems to have sorted it in FF, but Chrome seems to be acting as if there ain't no cookie. despite it having been written to by two functions, all the values are undefined. :/
Is FF tolerating my buggy code, or is Chrome buggy?
index.html:
/files/images.js:
/files/bomb.png:

/files/eye.png:

In FF67, the test page loads, as do the images, but the reported sizes are all zero, however, if I press F5 and reload, the page works perfectly.
In Chrome75, despite loading, the image sizes are consistently zero, and the code crashes after test 3.
Can anyone see what I'm doing wrong?
The initial problem's been sorted by using onload to call routines to get the image sizes after they've loaded. The cookie handling seems to be working okay in FF.
Now I'm fining the main code is chugging along on it's own and looks like it's finishing execution before the onload routines have even been called. Now to find a way to make the code wait for them.
It's still working okay with F5 on FF, but Chrome still isn't seeing the one image's values from the other image's routine.
Okay, using SetTimeout to add a 100ms delay to the execution of the final cookie read seems to have sorted it in FF, but Chrome seems to be acting as if there ain't no cookie. despite it having been written to by two functions, all the values are undefined. :/
Is FF tolerating my buggy code, or is Chrome buggy?
index.html:
<!DOCTYPE html>
<html>
<head>
<script src= "files/images.js"></script>
<title></title>
</head>
<body>
<div>
<h1 id="page_title"></h1>
<p id="image_init_1"></p>
<p id="image_init_2"></p>
<p></p>
<p id="test1"></p>
<p id="test2"></p>
<p id="test3"></p>
<p id="test4"></p>
<p id="test5"></p>
<p id="test6"></p>
<p id="test7"></p>
<p id="test8"></p>
<p id="test9"></p>
</div>
<div>
<script>
init();
read_cookie();
</script>
</div>
</body>
</html>
/files/images.js:
// images.js
var JS_First_Image= "files/bomb.png", JS_Second_Image= "files/eye.png";
var First_Image_x_1, First_Image_y_1;
var Second_Image_x_1, Second_Image_y_1;
function First_img() {
// Read the cookie if it's there.
var myJSON_1= document.cookie;
document.getElementById("test1").innerHTML= "Read1: "+myJSON_1;
if (myJSON_1 !== "") {
var myObj_1 = JSON.parse(myJSON_1);
var First_Image_x_1= myObj_1.First_Image_x_1;
var First_Image_y_1= myObj_1.First_Image_y_1;
var Second_Image_x_1= myObj_1.Second_Image_x_1;
var Second_Image_y_1= myObj_1.Second_Image_y_1;
}
if (typeof Second_Image_x_1 === "undefined" && typeof Second_Image_y_1 === "undefined") {
var Second_Image_x_1= 0;
var Second_Image_y_1= 0;
}
document.getElementById("test2").innerHTML= "Img1a: "+First_Image_x_1+" "+First_Image_y_1+" "+Second_Image_x_1+" "+Second_Image_y_1;
// Write the cookie
First_Image_x_1= document.getElementById("First_one").naturalWidth;
First_Image_y_1= document.getElementById("First_one").naturalHeight;
var myObj_1= {First_Image_x_1, First_Image_y_1, Second_Image_x_1, Second_Image_y_1};
var myJSON_1= JSON.stringify(myObj_1);
document.cookie= myJSON_1;
document.getElementById("test3").innerHTML= "Img1b: "+First_Image_x_1+" "+First_Image_y_1+" "+Second_Image_x_1+" "+Second_Image_y_1;
}
function Second_img() {
// Read the cookie if it's there.
var myJSON_2= document.cookie;
document.getElementById("test4").innerHTML= "Read2: "+myJSON_2;
if (myJSON_2 !== "") {
var myObj_2 = JSON.parse(myJSON_2);
var First_Image_x_1= myObj_2.First_Image_x_1;
var First_Image_y_1= myObj_2.First_Image_y_1;
var Second_Image_x_1= myObj_2.Second_Image_x_1;
var Second_Image_y_1= myObj_2.Second_Image_y_1;
}
if (typeof First_Image_x_1 === "undefined" && typeof First_Image_y_1 === "undefined") {
var First_Image_x_1= 0;
var First_Image_y_1= 0;
}
document.getElementById("test5").innerHTML= "Img2a: "+First_Image_x_1+" "+First_Image_y_1+" "+Second_Image_x_1+" "+Second_Image_y_1;
// Write the cookie
Second_Image_x_1= document.getElementById("Second_one").naturalWidth;
Second_Image_y_1= document.getElementById("Second_one").naturalHeight;
var myObj_2= {First_Image_x_1, First_Image_y_1, Second_Image_x_1, Second_Image_y_1};
var myJSON_2= JSON.stringify(myObj_2);
document.cookie= myJSON_2;
document.getElementById("test6").innerHTML= "Img2b: "+First_Image_x_1+" "+First_Image_y_1+" "+Second_Image_x_1+" "+Second_Image_y_1;
}
function init() {
// Write the first image invisibly, and get it's size.
document.getElementById("image_init_1").innerHTML= '<img id="First_one" alt="Move along" src="'+JS_First_Image+'" style="width:0px; height:0px;" onload="First_img()">';
// Write the second image invisibly, and get it's size.
document.getElementById("image_init_2").innerHTML= '<img id="Second_one" alt="Nothing to see" src="'+JS_Second_Image+'" style="width:0px; height:0px;" onload="Second_img()">';
setTimeout(read_cookie, 100);
}
function read_cookie() {
document.getElementById("test7").innerHTML= "Check3: "+First_Image_x_1+" "+First_Image_y_1+" "+Second_Image_x_1+" "+Second_Image_y_1;
// Read the cookie if it's there.
var myJSON_3= document.cookie;
document.getElementById("test8").innerHTML= "Read3a: "+myJSON_3;
if (myJSON_3 !== "") {
var myObj_3 = JSON.parse(myJSON_3);
var First_Image_x_1= myObj_3.First_Image_x_1;
var First_Image_y_1= myObj_3.First_Image_y_1;
var Second_Image_x_1= myObj_3.Second_Image_x_1;
var Second_Image_y_1= myObj_3.Second_Image_y_1;
}
document.getElementById("test9").innerHTML= "Read3b: "+First_Image_x_1+" "+First_Image_y_1+" "+Second_Image_x_1+" "+Second_Image_y_1;
}
/files/bomb.png:

/files/eye.png:

no subject
Date: 2019-06-10 07:09 am (UTC)no subject
Date: 2019-06-10 07:46 am (UTC)It seems I was trying to read the values before the images had finished loading, hence the zero values. I'm guessing browser cache was responsible for the F5 success. That bit is now working consistently (and in Chrome) after adding an onload="xxx()" call to another function in the image tags, and getting the values there.
I've now run in to a problem with variable initialisation. Despite the fact that the w3schools site states that redeclared variables don't lose existing values, that doesn't seem to be working when calling different functions; they're appear to be reinitialised or set to whatever is in the declaration block with each new call, but that may be another timing issue
Cookies also seem to be losing data, but I need to check if the data is actually there and I'm managing to overwrite it, or if they're reinitialising too.
no subject
Date: 2019-06-10 02:48 pm (UTC)I think you may be misreading the redeclaring variables note. That just means that if you do something like
var i = 23;
var i;
i will still be 23, not reset to empty. If you do a redeclaration with an explicit value setting, like
var i = 23;
var i = 26;
then i will still get reset to 26.
There's also the issue of scope, where if you call a function and set a variable to a value, then when the function exits that variable will drop out of scope. So when the function is called again the variable will have to get reinitialized. If you don't want that to happen, you can declare the variable at a higher scope, say for the page, and then you can use your page-scoped variable in the function and when the function is called again, the variable should still have the value it was set to before.
Re the cookies, I don't think that you're setting your cookies correctly there.
document.cookie
isn't just a plain variable likemyObj.myValue
; it's an interface to the browser's cookies for the page. So you can't set it to just anything. You need to use at minimum a name/value pair, so something likedocument.cookie="imageValues=" + myJSON_2;
. And then if you follow that up with something likedocument.cookie = "anotherValue=something";
, thendocument.cookie
will actually now beimageValues=whateverjsonitwas; anotherValue=something
. Look at a page like this one at w3schools for more information....While I'm at it, I don't think that your JSON syntax is going to work there. You probably want something more like
var myObj_1= {
First_Image_x_1: First_Image_x_1,
First_Image_y_1: First_Image_y_1,
Second_Image_x_1: Second_Image_x_1,
Second_Image_y_1: Second_Image_y_1
};
var myJSON_1= JSON.stringify(myObj_1);
Hope this helps.
no subject
Date: 2019-06-10 04:11 pm (UTC)Looking at rearranging things to avoid losing it.
The JSON appeared to be working so I compared the two versions (with explicit typo in the new version, just to check it was doing what it looked to be doing):
The two versions output as:
Old JSON: {"First_Image_x_1":49,"First_Image_y_1":50,"Second_Image_x_1":34,"Second_Image_y_1":34}
New JSON: {"First_ImaGe_x_1":49,"First_Image_y_1":50,"Second_Image_x_1":34,"Second_Image_y_1":34}
...so it looks like you can get away without explicit declaration* before stringification despite JSON canon saying it has to be done your way with the name/value pair.
*In FF67 & Chrome73
no subject
Date: 2019-06-10 06:20 pm (UTC)Scope
Date: 2019-06-11 08:20 am (UTC)This works:
(Simple, small, and doesn't need cookies)
/files/images.js:
Output (for both FF & Chrome):
Image1: 49 50 Image2: 34 34