Javascript not working without alert - javascript

Okay, this one is weird and I'm not entirely sure how to word the Title for this particular question.
I have a javascript function that is supposed to happen when the document is ready.
The first part of the function calls a function that includes some added html pages into the page.
The next part matches the last section of the current url page and finds them in the menu to to give it a selected class, along with the parent of the menu item.
The code works, but only with the
alert(lastpath);
When the alert statement is removed, the lines below no longer function.
$( document ).ready(function() {
w3IncludeHTML();
lastpath=(window.location.pathname).split("/").slice(-1).pop();
alert(lastpath);
$('a[href$="'+lastpath+'"]').attr("class","selected");
$('a[href$="'+lastpath+'"]').parent(".dropdown-content").prev().attr("class","selected");
});
Does anyone know what could be happening here?

The function w3IncludeHTML defined in the w3Data library loads the content asynchronously. It offers no way to get notified when it has finished its job:
function w3IncludeHTML() {
var z, i, a, file, xhttp;
z = document.getElementsByTagName("*");
for (i = 0; i < z.length; i++) {
if (z[i].getAttribute("w3-include-html")) {
a = z[i].cloneNode(false);
file = z[i].getAttribute("w3-include-html");
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
a.removeAttribute("w3-include-html");
a.innerHTML = xhttp.responseText;
z[i].parentNode.replaceChild(a, z[i]);
w3IncludeHTML();
}
}
xhttp.open("GET", file, true);
xhttp.send();
return;
}
}
}
A quick solution would be to alter the above function, and add the following code to your script:
function w3IncludeHTML(callback) {
var z, i, file, xhttp;
z = document.querySelector("[w3-include-html]");
if (!z) {
// notify caller that all is loaded
if (callback) callback();
return;
}
file = z.getAttribute("w3-include-html");
z.removeAttribute("w3-include-html");
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4) {
if (xhttp.status == 200) {
z.innerHTML = xhttp.responseText;
}
w3IncludeHTML(callback);
}
}
xhttp.open("GET", file, true);
xhttp.send();
}
This version will override the function provided by the w3Data library, and improve it. You can now pass a callback function to w3IncludeHTML, in which you can be sure that all content is loaded (unless errors occurred of course):
$( document ).ready(function() {
w3IncludeHTML(function () {
// Everything that depends on loaded content, should be done here:
lastpath=(window.location.pathname).split("/").slice(-1).pop();
// not needed: alert(lastpath);
$('a[href$="'+lastpath+'"]').attr("class","selected");
$('a[href$="'+lastpath+'"]').parent(".dropdown-content").prev().attr("class","selected");
});
});

You use the function from the JS library from w3schools. Just take a look at their code:
function w3IncludeHTML() {
var z, i, a, file, xhttp;
z = document.getElementsByTagName("*");
for (i = 0; i < z.length; i++) {
if (z[i].getAttribute("w3-include-html")) {
a = z[i].cloneNode(false);
file = z[i].getAttribute("w3-include-html");
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
a.removeAttribute("w3-include-html");
a.innerHTML = xhttp.responseText;
z[i].parentNode.replaceChild(a, z[i]);
w3IncludeHTML();
}
}
xhttp.open("GET", file, true);
xhttp.send();
return;
}
}
}
It is using a XMLHttpRequest object, so we are sure it's an asynchronous code. Most likely, after your call to this function, you use lines of code which depend on the success of ajax request. This is, of course, not good (treating asynchronous code as a synchronous code), but the delay provided by alert function makes it work (sometimes ;) !).
Solution: make sure, what does the w3IncludeHTML function do and how to get rid of the synchronous code after its call. Or: try to find a way to detect when the ajax part of this function is completed. Actually, it's right there:
if (xhttp.readyState == 4 && xhttp.status == 200) {
a.removeAttribute("w3-include-html");
a.innerHTML = xhttp.responseText;
z[i].parentNode.replaceChild(a, z[i]);
w3IncludeHTML();
}

Related

Function call not returning control AJAX - PHP - MYSQLI

I have checked all the similar questions to this but not found anything that helped... so here goes!
I am writing designing a site for my college project. It simply is an image gallery. I have a counter displayed for each image that increments each time the image is clicked. When the page refreshes the new number is displayed. With me so far?
The problem is that after the database update is completed the return does not complete the rest of the code...
echo "<div class='gridImg'><a href=".$imgpath." data-lightbox='countryside' data-title='".$row['ldesc']."' onclick='"."showUser(&#39".$fname."&#39)'>";
The above line is in a php file and the function in question is showUser, which passes a variable $fname...
function showUser(str) {
if (str === "") {
document.getElementById("txtHint").innerHTML = "";
return;
} else {
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("txtHint").innerHTML =
this.responseText;
}
};
xmlhttp.open("GET","../php/countrysideupdateviews.php?q="+str,true);
xmlhttp.send();
return;
}
}
The above script takes the passed value and hands it over to countrysideupdateviews.php (Sorry if this script is a mess, I am new to AJAX and took it from the W3Schools site.
<?php
$q = $_GET['q'];
$conn=new mysqli('localhost','user','pass','dbname');
$sql="UPDATE countryside SET views = views + 1 WHERE fname = '".$q."'";
$result=$conn->query($sql);
mysqli_close($conn);
?>
The above php file updates the database.
Ok...
So, a user clicks on one of the images on-screen, which opens a lightbox gallery, BUT also updates the view count and then returns control - except that everything works - the update takes place - but the lightbox does not start, instead a static larger image of the one that was clicked is shown. The only way to clear it is to refresh the site, which does reflect the updated counter.
I have added returns to the onclick function call which does return control but the counter is not updated. Where am I going wrong? Bear in mind please I am still learning and I hope this makes sense :)
The argument to onclick must be a function. showUser("foo") is not a function. You're also missing event.preventDefault() which prevents the click action from opening the link.
Change your showUser to
function showUser(str) {
return function(event) {
if (str === "") {
document.getElementById("txtHint").innerHTML = "";
} else {
if (window.XMLHttpRequest) {
var xmlhttp = new XMLHttpRequest();
}
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("txtHint").innerHTML = this.responseText;
}
};
xmlhttp.open("GET","../php/countrysideupdateviews.php?q="+str,true);
xmlhttp.send();
}
event.preventDefault();
};
}
Ok, after playing around with #apaatsio's answer I got it working, this is what the function now looks like...
function showUser(str) {
if (str === "") {
document.getElementById("txtHint").innerHTML = "";
return;
} else {
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
}
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("txtHint").innerHTML = this.responseText;
}
};
xmlhttp.open("GET","../php/countrysideupdateviews.php?q="+str,true);
xmlhttp.send();
event.preventDefault();
}
}
It looks like preventing the click opening the link worked just fine - thanks :)

setInterval runs continuously in Firefox on Android

I have a short snippet of Javascript which I want to poll a server every couple of seconds and update the DOM.
function updateCard() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
card = JSON.parse(this.responseText);
document.getElementById("season").innerHTML = card.season;
}
};
xhttp.open("GET", "/curr_card/", true);
xhttp.send();
}
window.onload = updateCard;
window.setInterval(updateCard,2000);
On most browsers that's what happens. There are a few one-off calls to updateCard, but on the whole the server shows ~1/2 connection per second per client.
However, when I access the page in Firefox on Android (49.0) the browser starts continuously polling /curr_card/, tens of times a second.
I've seen people suggest replacing the setInterval line with window.setInterval(function() {updateCard();},2000);, this doesn't help.
I'm pretty new to Javascript and AJAX, so have no idea why this is happening. Is it a bug in FF? I can post more code if requested.
Thanks in advance.
After testing and discussing in OP's comments, we concluded this must be an issue specific to Firefox on the OP's HTC M7, as it could not be reproduced on the same version Firefox on a Galaxy S7.
That may happen not only with Firefox on some device.
It may happen when response has not finished because of servers late answer but it sends another request and so on...
What if to do like this:
function updateCard(before, after) {
if(before) {
before();
}
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
card = JSON.parse(this.responseText);
document.getElementById("season").innerHTML = card.season;
}
if(after) {
after();
}
};
xhttp.open("GET", "/curr_card/", true);
xhttp.send();
}
window.onload = updateCard;
var updateCardRunning = false;
setInterval(function() {
if(updateCardRunning === true) {
console.log('postponing to next schedule');
return;
}
updateCard(
function() {updateCardRunning = true;},
function() {updateCardRunning = false;}
);
}, 2000);
or:
function updateCard() {
var xhttp = new XMLHttpRequest();
window.xhttp = xhttp;
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
card = JSON.parse(this.responseText);
document.getElementById("season").innerHTML = card.season;
}
};
xhttp.open("GET", "/curr_card/", true);
xhttp.send();
}
window.onload = updateCard;
setInterval(function() {
if(window.xhttp) {
window.xhttp.abort();
}
updateCard();
}, 2000);

What causes a function to "freeze" in javascript?

Say in window.onload function i call a bunch of other methods:
function window.onload(){
method1();
alert("test1");
method2();
alert("test2");
}
So my test1 method is working fine, i get the alert "test1", but then it appears that my code is "freezing" on method2, so the alert "test2" is not being called.
Here is what my test2 method looks like
function method2(){
alert("testing");
var xhr = new XMLHttpRequest();
xhr.open("GET", "url that i want to call from", true);
xhr.onload = function() {
if (xhr.status==200) {
alert(xhr.responseText);
alert("yay");
}
else{
alert("Aww");
}
}
xhr.send();
}
what i dont understand is why i dont even get the alert "testing", if my code is freezing somewhere why doesnt it at least run the first line in the method?
Can anyone explain why this occurs in javascript?
thanks
I have always hooked into to the 'on ready state change' event.
<h2>AJAX</h2>
<button type="button" onclick="loadDoc()">Request data</button>
<p id="demo"></p>
<script>
$(document).ready(function () {
loadDoc();
});
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (xhttp.readyState == 4 && xhttp.status == 200) {
document.getElementById("demo").innerHTML = xhttp.responseText;
alert("yay");
}
};
xhttp.open("GET", "demo", true);
xhttp.send();
}
</script>
http://www.w3schools.com/ajax/ajax_xmlhttprequest_send.asp
From the information you provided, I am guessing that you are running into browser security issues ...
I would recommend using jquery to handle the job for you. the $(document).ready function in jquery has always worked awesomely for me in the years I have been using the framework.
If you can't use jquery, then you need to have the user click on a button in order to initiate the http request you desire.
Also, if you need to perform the 'Awww' action you can append it to the if statement but I would recommend using if else based on xhttp.readyState values or your 'Awww' will repeat often.

Ajax - browser lag when updating content

I'm trying to update a status page live.
I'm using Ajax to update the page. The update is set to update every 3 seconds. But whenever the update is being called the browser freeze at least for a second or two.
<script type="text/javascript">
window.onload = updateStatus;
function updateStatus() {
updateinfo();
setTimeout(updateStatus, 3000);
}
function getJson(theUrl, update) {
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
update(xmlhttp.responseText);
}
}
xmlhttp.open("GET", theUrl, false);
xmlhttp.send();
}
function updateinfo() {
getJson('backend/status', function(update) {
var jsono = JSON.parse(update);
document.getElementById('name').innerHTML = jsono.name;
document.getElementById('online').innerHTML += jsono.online;
document.getElementById('ip').innerHTML = jsono.ip + ':';
document.getElementById('ip').innerHTML += jsono.port;
document.getElementById('memory').innerHTML = jsono.memory + " MB";
});
}
</script>
If someone can give me tips on improving this. To make it less laggy or make it go away.
2) I have been thinking about using JQuery. Should I make the move? Pros and Cons? Also how is JQuery performance wise comparing to just JavaScript ?
You are letting the AJAX request run synchronously - which you never ever need to so, since that prevents it from being AJAX in the first place, because the A stands for asynchron.
Change the third parameter of the xmlhttp.open call to true (or just leave it out, since that is the default).

Javascript Not Executing In Dynamically Loading Content (AHAH)

I'm dynamically loading content into a div when the user clicks a link using this code:
function ahah(url, target) {
document.getElementById(target).innerHTML = 'Opening form...';
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
} else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
}
if (req != undefined) {
req.onreadystatechange = function() {ahahDone(url, target);};
req.open("GET", url, true);
req.send("");
}
}
function ahahDone(url, target) {
if (req.readyState == 4) { // only if req is "loaded"
if (req.status == 200) { // only if "OK"
document.getElementById(target).innerHTML = req.responseText;
} else {
document.getElementById(target).innerHTML=" AHAH Error:\n"+ req.status + "\n" +req.statusText;
}
}
}
function load(name, div) {
ahah(name,div);
return false;
}
This works fine, however I can't get any javascript to work in this new content, such as a jquery datapicker, or even just a document.write hello world. The js in there in the code, just not working. I've loaded the content directly in a browser and it works fine.
I'm at loss, any ideas greatly appreciated!
If you are using jquery anyways, might as well try using jquery.ajax().
You could include whatever scripts you need in the <head> and then call your datepicker or w/e in the callback function of your jquery ajax call.

Categories