i got a problem with JS:
On line 1 to 4 I take all "a"-Elements from the DOM and get their hrefs.
later I want to reload the URL via AJAX, but the href does not arrive correctly... Whats wrong?
$(document).ready(function(){
$('a').click(function(e){
ajaxReload($(this).attr('href'));
e.preventDefault();
});
});
function ajaxReload(href) {
var xmlhttp = null;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}
// IE
else if (window.ActiveXObject) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET", href, true);
xmlhttp.onreadystatechange = function() {
if(xmlhttp.readyState != 4) {
document.write('loading');
}
if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
alert('hello');
//alert('getting '+xmlhttp.status+' for '+href);
var pureHTML = xmlhttp.responseText;
var ajaxstart = pureHTML.indexOf('<!-- AJAX START -->');
var ajaxend = pureHTML.indexOf('<!-- AJAX END -->');
var ajaxContent = pureHTML.substring(ajaxstart, ajaxend);
var writeContent = document.getElementById('content');
writeContent.innerHTML = ajaxContent;
}
}
xmlhttp.send(null);
}
Sorry if I've misunderstood your code. I think that you simply need to (at least approximately) just remove code as commented below:
//$('a').click = function(href) {
var pureHTML = xmlhttp.responseText;
var ajaxstart = pureHTML.indexOf('<!-- AJAX START -->');
var ajaxend = pureHTML.indexOf('<!-- AJAX END -->');
var ajaxContent = pureHTML.substring(ajaxstart, ajaxend);
$("content").html(ajaxContent);
// ajaxReload(href); //this would cause a loop?
// return false;
//}
To answer your later question - you can change your event propagation handling to:
$(document).ready(function(){
$('a').click(function(e){
ajaxReload($(this).attr('href'));
e.preventDefault();
});
});
And for the further comments, maybe try changing your:
document.write('loading');
To:
$("content").html(xmlhttp.status); //so now you can see the loading status for testing
Related
I want to create a page that refreshes content within a div async alongside providing a user with an anchor to enable direct access to the content within the div. (e.g. www.website.co.uk/#page1)
I've managed to make it so that the content can be updated for 1 page, however, if I add multiple pages it stops working
Additionally - if I was to navigate to the URL website.co.uk/#page1 it wont display #page1.
Can anyone help?
This is my current code:
HTML :
<h5> Test</h5>
<h5> Test2</h5>
JS :
<script type="text/javascript">
var routes = {
'#page1' : '{{site.url}}/page1'
'#page2' : '{{site.url}}/page2'
};
var routeHandler = function( event ) {
var hash = window.location.hash,
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
document.getElementById("div1").innerHTML = xhttp.responseText;
}
};
xhttp.open("GET", routes[hash], true);
xhttp.send();
};
window.addEventListener('hashchange', routeHandler);
window.addEventListener('load', function() {
var hash = window.location.hash;
if (routes.hasOwnProperty(hash)) routehandler();
});
</script>
You made some small js errors.
So here is you fixed code
html:
<h5> Test</h5>
<h5> Test2</h5>
<div id="div1"></div>
javascript:
//change these routs
var routes = {
'#page1': '/page1.html',
'#page2': '/page2.html'
};
var routeHandler = function() {
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
document.getElementById("div1").innerHTML = xhttp.responseText;
}
};
xhttp.open("GET", routes[window.location.hash], true);
xhttp.send();
};
window.addEventListener('hashchange', routeHandler);
window.addEventListener('load', function() {
var hash = window.location.hash;
if (routes.hasOwnProperty(window.location.hash)) routeHandler();
});
You usually use a router-like object for this. Instead of the hyperlink you're using, set the href to the actual page hash Button Title. Then create an event listener for the hashchange on the window object where you will fetch the content.
And finally add a list of webpages you want to be able to navigate to, so you can translate '#page1' to the actual url.
The result is that you can use simple hrefs in your hyperlinks and the current page will be shown in the url bar at the top.
ps: add a check into the hashchange listener for routes that aren't listed, so you can still link to offsite pages as well.
pps: If you want to be able to directly navigate to a page, you'll need to add a manual check of the hash at document load.
// html mockup
Button Title
// js mockup
var routes = {
'#page1' : '{{site.url}}/webpage.html'
};
window.addEventListener('hashchange', function( event ) {
var hash = window.location.hash, // gives you '#page1'
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
document.getElementById("div1").innerHTML = xhttp.responseText;
}
};
xhttp.open("GET", routes[hash], true);
xhttp.send();
});
Updated with a load listener:
// html mockup
Button Title
// js mockup
var routes = {
'#page1' : '{{site.url}}/webpage.html'
};
var routeHandler = function( event ) {
var hash = window.location.hash, // gives you '#page1'
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
document.getElementById("div1").innerHTML = xhttp.responseText;
}
};
xhttp.open("GET", routes[hash], true);
xhttp.send();
};
window.addEventListener('hashchange', routeHandler);
window.addEventListener('load', function() {
var hash = window.location.hash;
if (routes.hasOwnProperty(hash)) routehandler();
});
since you have tagged the question with jquery, iassume you have jQuery available, in this case you could do something like:
$(window).on('hashchange', refreshContent);
function refreshContent() {
$.get(getBaseUrl() + location.hash, function(data) {
$('#div1').html(data);
});
}
But please be aware that there are a lot more sophisticated solutions out there
I given directly on onclick its working. It may help you.
<h5> Test</h5>
<h5> Test2</h5>
<div id="div1"></div>
<script type="text/javascript">
var routes = {
'#page1' : 'page1.html',
'#page2' : 'page2.html'
};
function test(page) {
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
document.getElementById("div1").innerHTML = xhttp.responseText;
}
};
xhttp.open("GET", routes[page], true);
xhttp.send();
}
</script>
I used .html for pages for check. You use your own.
How do I add the slideDown jquery animation when I knew message is loaded? Perhaps I can't with my method for loading... A file takes user input and inserts into database. Another file pulls from database onto chatbox and styles.
Javascript Code:
var form = document.querySelector('form[name="chatbox"]');
form.addEventListener("submit", function (event) {
event.preventDefault();
});
function submitChat() {
if(chatbox.message.value == '') {
alert('Error: Missing Fields.');
return;
}
var message = chatbox.message.value;
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if(xmlhttp.readyState==4&&xmlhttp.status==100) {
document.getElementById('chatlog').innerHTML = xmlhttp.responseText;
}
}
xmlhttp.open('GET','chat.php?message='+message, true);
xmlhttp.send();
chatbox.reset();
}
$(document).ready(function(e) {
$.ajaxSetup({cache:false});
setInterval(function() {$('#chatlog').load('logs.php');}, 200);
});
Please let me know if you need the PHP attached.. Thanks for the help! :)
Just for you to know I'm less than a newbie!
I have the following javascript code:
window.onload = function() {
renderTime();
getsec(myHandler);
countdown('countdown');
...
}
function myHandler(resultado) {
seconds = resultado;
}
function reqListener () {
console.log(this.responseText);
}
function getsec(callback) {
var indice = 1;
var oReq = new XMLHttpRequest();
oReq.onload = function() {
var variarr = JSON.parse(this.responseText);
callback(variarr[0]);
};
oReq.open("GET", "getsec.php?lei="+indice, true);
oReq.send();
}
This works perfectly for me. The intention is to get data from MySQL table through getsec.php every second. As you can see I have function countdown('countdown') that looks like this:
function countdown(element) {
...
interval = setInterval(function() {
...
if( runned == false){ // This condition happens
...
} else {
...
}
}, 1000);
}
I tryed to put function getsec(myHandler) inside function countdown('countdown')
if( runned == false){ // This condition happens
getsec(myHandler);
and I stop getting the information I want.
Can anyone explain me why?
When I run my page only 1 ajax get to work... Im pretty sure it has something to do with the setInterval "property"...
<script>
function encontrarnumero() {
src = "http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js";
var divid = 'u219-4';
if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
document.getElementById(divid).innerHTML = xmlhttp.responseText;
setInterval(encontrarnumero, 1000);
}
};
xmlhttp.open("GET", "numero.php?q=" + q + "&p=" + p + "&w=" + w, true);
xmlhttp.send();
}
window.onload = function () {
encontrarnumero();
};
</script>
<script>
function encontrartiempo() {
src = "http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js";
var divid = 'tiempo';
if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
document.getElementById(divid).innerHTML = xmlhttp.responseText;
setInterval(encontrartiempo, 2000);
}
};
xmlhttp.open("GET", "tiempo.php?q=" + q + "&p=" + p + "&w=" + w, true);
xmlhttp.send();
}
window.onload = function () {
encontrartiempo();
};
</script>
any ideas?? Thanks!!
ps. im sure the problem are not the php files, when I run each ajax by itself they work fine.
Too much repeating code. Things are much simpler if you refactor your code into a single function.
<script>
// Move repeating code to a function
function doAJAX(divid, page) {
if (window.XMLHttpRequest) {
// Use `var` when declaring variables
var xmlhttp = new XMLHttpRequest();
} else {
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
document.getElementById(divid).innerHTML = xmlhttp.responseText;
// Use `setTimeout` if you're going to make recursive calls!
setTimeout(function() {
doAJAX(divid, page)
}, 1000);
}
};
xmlhttp.open("GET", page + "?q=" + q + "&p=" + p + "&w=" + w, true);
xmlhttp.send();
}
// Just one onload handler that calls the function twice,
// passing the different info for each call
window.onload = function () {
doAJAX('u219-4', "numero.php");
doAJAX('tiempo', "tiempo.php");
};
</script>
The problem with your original code was that your were assigining to window.onload twice and the second assignment overwrote the first. Thats why encontrarnumero() was never called.
Note that Crazy Train's answer only makes a single assignment to window.onload.
Lastly, assigning to window.onload like this is not really the best approach. if you want to do something when the window loads, consider using JQuery or using native browser events if you want pure javascript. you can see how JQuery actually does this in this answer
I have the following files: (inc.js is included in my html page)
inc.js
var field = new Worker('ajax.js');
field.addEventListener('message', function(e) {
var data = JSON.parse(e.data);
document.getElementById('fieldToUpdate').innerHTML = data[0];
}, false);
field.postMessage(0);
ajax.js
var xhr = new XMLHttpRequest();
function getData() {
xhr.open('get', 'field.php');
xhr.onreadystatechange = processData;
xhr.send(null);
}
function processData() {
if (xhr.readyState == 4) {
self.postMessage(xhr.responseText);
setTimeout(getData, 5000);
}
}
onmessage = function() {
setTimeout(getData, 5000);
}
My Problem is now, that this Script doesn't make one http request each 5 seconds but it starts as soon as one is finished.