I have these lines in my html head section
<script type="text/javascript" src="../behaviour/location.js"></script>
<script type="text/javascript" src="../behaviour/ajax.js"></script>
When I use either in isolation, the code in the external files executes as expected.
However, when I use both, I find that neither works correctly. What do I need to do to fix this?
location.js
// JavaScript Document
function addLoadEvent (func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function () {
oldonload();
func;
}
}
}
//county changer
function countyUpdate (message) {
var name = message.getAttribute("name");
var check = message.checked;
var countyId = message.getAttribute("id");
var countyId = countyId.split("_")[1];
var innerpost = document.getElementById("innerpost_"+countyId);
var checks = innerpost.getElementsByTagName("input");
for (var i = 0; i< checks.length; i++) {
if (checks[i].checked == true && check == true) {
checks[i].checked = false;
}
}
}
//postcode changer
function postcodeUpdate (message) {
var parent = message.parentNode.parentNode.getAttribute("id").split("_")[1];
var county = "county_"+parent;
var checkbox = document.getElementById(county);
var checked = message.checked;
if (checked == true) {
checkbox.checked = false;
}
}
//get a dynamic list of al postcode checkboxes
function getCounties () {
var county = document.getElementsByTagName("input");
for (var i = 0; i< county.length; i++) {
var check = county[i].getAttribute("type");
if (check == "checkbox") {
var name = county[i].getAttribute("name");
var parent = county[i].parentNode.parentNode.getAttribute("id");
var parent = parent.split("_")[0];
//action for county
if (parent != "innerpost") {
county[i].onclick = function() { countyUpdate(this); };
}//if
//action for postcode
if (parent == "innerpost") {
county[i].onclick = function() { postcodeUpdate (this); };
}//if
}//if
}//for
}//function
addLoadEvent (getCounties);
ajax.js
function loadXMLDoc()
{
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("myDiv").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","cart.php",true);
xmlhttp.send();
}
And this is the inline code to activate the second file:
<button type="button" onclick="loadXMLDoc()">Change Content</button>
When I try using both files together, I don't seem to be able to use any functions (not even simple alerts wrapped in a function).
This would happen if the scripts conflict with each other.
Please show us the scripts and the error messages.
When I use either in isolation, the
code in the external files executes as
expected.
However, when I use both, I find that
neither works correctly. What do I
need to do to fix this?
It sounds like you have a conflict somewhere in the two files. Like a function that is named the same or a variable etc.
Having not seen the files you could:
1. Track down the naming conflict (if that is what it is) and change one.
2. Encapsulate the code in the files in different objects and access the methods/properties etc. through there.
My bet is that you're getting a mess out of that window.onload= juggling. I suggest you use the standard window.addEventListener() interface (check for its existance and use window.attachEvent() when the standard interface is missing if you want to support IE too). This should also guarantee that the onload functions get executed in the same order as the scripts that set them. Something like:
if (window.addEventListener) {
window.addEventListener('load', somefunc, false);
} else if (window.attachEvent) {
window.attachEvent('onload', somefunc);
} // else, no way to add multiple onload handlers
Related
I am creating a landing page which should exist in two languages. The texts that should be shown are in two JSON files, called accordingly "ru.json" and "en.json". When a user clicks on the "Change language" button, the following function is executed:
function changeLang(){
if (userLang == 'ru') {
userLang = 'en';
document.cookie = 'language=en';
}
else {
userLang = 'ru';
document.cookie = 'language=ru';
}
var translate = new Translate();
var attributeName = 'data-tag';
translate.init(attributeName, userLang);
translate.process();
}
Where Translate() is the following:
function Translate() {
//initialization
this.init = function(attribute, lng){
this.attribute = attribute;
if (lng !== 'en' && lng !== 'ru') {
this.lng = 'en'
}
else {
this.lng = lng;
}
};
//translate
this.process = function(){
_self = this;
var xrhFile = new XMLHttpRequest();
//load content data
xrhFile.open("GET", "./resources/js/"+this.lng+".json", false);
xrhFile.onreadystatechange = function ()
{
if(xrhFile.readyState === 4)
{
if(xrhFile.status === 200 || xrhFile.status == 0)
{
var LngObject = JSON.parse(xrhFile.responseText);
var allDom = document.getElementsByTagName("*");
for(var i =0; i < allDom.length; i++){
var elem = allDom[i];
var key = elem.getAttribute(_self.attribute);
if(key != null) {
elem.innerHTML = LngObject[key] ;
}
}
}
}
};
xrhFile.send();
}
Everything works fine, however, when a user opens the page for the first time, if his Internet connection is bad, he just sees the elements of the page without text. It is just 1-2 seconds, but still annoying.
The question is, is there any way to check the text has loaded and display the page elements only on this condition?
You can use $(document).ready() in this way
$(document).ready(function(){
//your code here;
})
You can use the JavaScript pure load event in this way
window.addEventListener('load', function () {
//your code right here;
}, false);
Source: Here
translate.process() is asynchronous code which needs to make a call to a server and wait for its response. What it means is that, when you call this function, it goes in the background to go do its own thing while the rest of the page continues loading. That is why the user sees the page while this function is still running.
One minimal way I can think around this is by adding this to your css files in the head tag.
body { display: none }
And then, under this.process function, after the for loop ends, add
document.body.style.display = 'block'
If you want to suppori IE8:
document.onreadystatechange = function () {
if (document.readyState == "interactive") {
// run some code.
}
}
Put the code you want to execute when the user initially loads the page in a DOMContentLoaded event handler like below:
document.addEventListener('DOMContentLoaded', function() {
console.log('Whereas code execution in here will be deffered until the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading.');
});
console.log('This will log immediatley');
It's important to note that DOMContentLoaded is different than the load event
I am facing very strange thing with AJAX and Unobtrusive JavaScript that I have two pages
ajaxcontent.php
index.php
index.php has
<div id="cont"></div>
<input type="button" id="a" value="load plz.">
<script type="text/javascript">
document.getElementById('a').onclick = function () {
if (window.XMLHttpRequest) {
ari = new XMLHttpRequest();
} else {
ari = new ActiveXObject("Microsoft.XMLHTTP")
}
ari.onreadystatechange = function () {
if (ari.readyState == 4 && ari.status == 200) {
document.getElementById('cont').innerHTML = ari.responseText;
}
}
ari.open("GET","button.php",true);
ari.send();
}
document.getElementById('b').onclick = function () {
alert('a');
}
</script>
And ajaxcontent.php has only
<input type="button" id="b"/>
and the problem is unobtrusive Javascript is not working.
After laoding of ajaxcontent when i click on button it doesn't show alert pop up.
i have tried that i added
document.getElementById('b').onclick = function () {
alert('a');
}
this code on ajaxcontent.php but it still not working.
THe only way to make it work that i have to add inline javascript as
<input type="button" id="b" onclick="hi();"/>
and replace this function with
document.getElementById('b').onclick = function () {
alert('a');
}
with
function hi() {
alert('a');
}
so please help me that how to use unobtrusive js here and please don't give jQuery based answer thanks
First of all document.getElementById('b') can only find an element that is in the DOM at the time you call this function.
Because the element with the id b is in the data you request in the click event, the function will not find any element. You most likely should have seen an error in the console like cannot set property onclick of undefined.
AJAX requests are async by default (and you should not make them sync because this will block the window of the browser).
So you need to place the document.getElementById('b').onclick = ... in the onreadystatechange check right after the document.getElementById('cont').innerHTML = ari.responseText;
Here a simple example how to generalize your request:
function doAjaxRequest(url, complete, error) {
var ari; //<<<< you should define your variables using var otherwise it is set in the global scope
if (window.XMLHttpRequest) {
ari = new XMLHttpRequest();
} else {
ari = new ActiveXObject('Microsoft.XMLHTTP');
}
ari.onreadystatechange = function() {
if (ari.readyState === 4) {
if (ari.status === 200) {
// if complete callback is passed, then call it if request was successful
if (typeof complete === 'function') {
complete(ari.responseText);
}
} else {
// if error callback is passed then call it if request was not successful
if (typeof error === 'function') {
error(ari.status, ari.statusText);
}
}
}
}
ari.open('GET', url, true);
ari.send(null);
}
document.getElementById('a').onclick = function() {
doAjaxRequest('button.php', function( data ) {
document.getElementById('cont').innerHTML = data;
document.getElementById('b').onclick = function() {
alert('a');
}
}, function(errorCode, errorMessage) {
//do something on error
});
}
The onclick event attaches to elements currently in the DOM when the function is triggered. Because the button in ajaxcontent.php is added to the DOM after the function was called, no event is attached.
To rectify this, you can add a snippet inside ari.onreadystatechange to detatch events then attach the event again.
ari.onreadystatechange = function () {
if (ari.readyState == 4 && ari.status == 200) {
document.getElementById('cont').innerHTML = ari.responseText;
// remove events
document.getElementById('b').onclick = null;
// attach events
document.getElementById('b').onclick = function() {
alert('a');
}
}
}
It's important to remove events because it may (although i was using jQuery when i learnt by mistake) cause double execution.
If you add javascript code inside ajaxcontent.php, that code will not be executed unless you extend your ari.onreadystatechange function to scan for javascript and execute it. The way I do this, is I put my javascript in AJAX requested pages in a input with class 'ajax-js' and scan for those input boxes and execute the code one by one, removing the class as I go.
I am creating a blackjack game using html, js, ajax and php. When the Player first loads the game, a prompt appears on the page asking for the name, and this goes to a name.php which checks to see if the user name is in the database. If not, it adds it. In either case, it will place the player's name and bank total on the screen. This part of my code was working fine until I added the next part of the code.
When the user clicks on the "hit" button, hit.php is called, which for now should just be pulling 1 card from the deck table (will fully implement hit later on) and placing it within the "player" div on the screen. However, now that I have 2 ajax calls, nothing whatsoever is happening, including the original prompt for the player name.
Is the 2nd call somehow interfering with the 1st call?
Any suggestions as to how I should treat the ajax calls would be greatly appreciated.
var username;
var playerName = "";
var playerBank = 0;
var playerCard;
var playerHandValue = 0;
var dealerHandValue = 0;
var randomCardNumber;
function checkName() {
username = prompt("Welcome to Blackjack.\n Please enter your username");
if(document.getElementById('playerName').value == null) {
ajaxName();
}
click();
}
function printName() {
return playerName;
}
function printBank() {
return playerBank;
}
function ajaxName() {
var uName = username;
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttpN=new XMLHttpRequest();
}
else {// code for IE6, IE5
xmlhttpN=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttpN.onreadystatechange=function() {
if (xmlhttpN.readyState==4 && xmlhttpN.status==200) {
var elements = xmlhttpN.responseText.split("|");
playerName = elements[0];
playerBank = elements[1];
document.getElementById('playerName').innerHTML = printName();
alert(playerName);
document.getElementById('playerBank').innerHTML = printBank();
}
}
xmlhttpN.open("POST","name.php",true);
xmlhttpN.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xmlhttpN.send("player="+username);
}
function click() {
document.getElementById('hit').onclick = function(){ ajaxButton(this);};
document.getElementById('stand').onclick = function(){ ajaxButton(this);};
document.getElementById('raiseBet').onclick = function(){ ajaxButton(this);};
document.getElementById('newGame').onclick = function(){ ajaxButton(this);};
}
function ajaxButton(buttonClicked) {
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttpB=new XMLHttpRequest();
}
else {// code for IE6, IE5
xmlhttpB=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function() {
if (xmlhttpB.readyState==4 && xmlhttpB.status==200) {
var elements = xmlhttpB.responseText;
if(buttonClicked.innerHTML == "HIT") {
randomCardNumber = randNumber(1,52);
playerCard = elements[0];
document.getElementById('player').innerHTML = displayCard();
xmlhttpB.open("POST","hit.php",true);
xmlhttpB.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xmlhttpB.send("card_id="+randomCardNumber);
}
}
if(buttonClicked.innerHTML == "STAND") {
alert("stand");
}
if(buttonClicked.innerHTML == "RAISE BET") {
alert("raise bet");
}
if(buttonClicked.innerHTML == "NEW GAME") {
alert("new game");
}
}
No JavaScript errors reported in your browser, and the prompt isn't coming up at all, and nothing happens when you click hit? It sounds as though perhaps you aren't calling the checkName() or click() functions at all. Have you refactored those into methods recently when they weren't previously?
It seems to me that checkName should occur as soon as the page loads, so if it doesn't already, try putting a call to it in a script block at the bottom of the page.
I'm trying to have a div refresh after a callback using ajax functions. Basically, I want /includes/view_game/achievements.inc.php to be reloaded in the div #achievements_tab. The callback (I didn't include it in codes below) works well and triggers the AchievementRefresh function found below (the opacity of the div changes to 0.5, but it remains like this and the refresh is not made).
Those two functions are used for another similar ajax refresh on my site that works well. So I tried to modify the code, but since it's for a slightly different purpose, maybe I have the wrong approach.
function AjaxPost(url, success_function) {
xmlHttp = GetXmlHttpObject();
if (xmlHttp == null) {
alert("Your browser doesn't support AJAX. You should upgrade it!")
return
}
xmlHttp.onreadystatechange = success_function;
xmlHttp.open("POST", url, true);
xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
}
This AjaxPost function is used in the other function below:
function AchievementRefresh() {
div('achievements_tab').style.opacity = 0.5;
div('highscore_pages').innerHTML = '<img src="'+site_url+'/images/loader.gif" />';
AjaxPost(site_url+"/includes/view_game/achievements.inc.php?", '',
function () {
div('achievements_tab').innerHTML = xmlHttp.responseText;
div('achievements_tab').style.opacity = 1;
}
)
}
Use load
$('#achievements_tab').load('/includes/view_game/achievements.inc.php');
See: http://api.jquery.com/load/
Edit
E.g.
function AchievementRefresh() {
$('#achievements_tab').css('opacity', 0.5);
$('#highscore_pages').html('<img src="'+site_url+'/images/loader.gif" />');
$('#achievements_tab').load('/includes/view_game/achievements.inc.php')
.success(function() {
$('#achievements_tab').css('opacity', 1);
});
}
Try this.
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
if(xmlhttp.status == 200) {
div('achievements_tab').innerHTML = xmlHttp.responseText;
div('achievements_tab').style.opacity = 1;
}
}
};`
Name and id is example.
Also, some changes:
AjaxPost(site_url+"/includes/view_game/achievements.inc.php");
var params= 'name'+encodeURIComponent(name)+'&id='+encodeURIComponent(id)
Parameters shouldn't be in URL.
xmlhttp.send(params);
I have a bunch of divs with weird id and each of them contains a video. They're actually video embed codes but they're not usual to me. Here's one example:
<div id="evp-1fae4e37639894816f03591bc7009c68-wrap" class="evp-video-wrap"></div><script type="text/javascript" src="http://domain.com/evp/framework.php?div_id=evp-1fae4e37639894816f03591bc7009c68&id=cmVsYXRpb25zaGlwLW1hcmtldGluZy0xLmZsdg%3D%3D&v=1278525356"></script><script type="text/javascript">_evpInit('cmVsYXRpb25zaGlwLW1hcmtldGluZy0xLmZsdg==');</script>
What I want to do is create a video playlist. As a part of that, I created list using divs also which use the onclick attribute to trigger my JS function to switch between videos. Here's how it looks:
<div class="vid-list" onclick="switchvideo('http://domain.com/html-vids/headline-vids/second-vid.html', 2)"><p>This a video tutorial for blah blah blah.</p></div>
The problem is, each time I switch to another video the div id of the embed code changes also because otherwise it won't work. So I need to change that before loading the video script inside the div. I tried to achieve that using the following JS function:
function switchvideo(url, vidnumber)
{
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
xmlhttp.open("GET",url,false);
xmlhttp.send(null);
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("GET",url,false);
xmlhttp.send();
}
var div_node = document.getElementByClass('evp-video-wrap');
if ( vidnumber == 2 ) {
div_node.id = 'evp-78c0b7c4f6d3377954825f145734fd5c-wrap';
}
document.getElementById(div_node.id).innerHTML=xmlhttp.responseText;
}
Apparently it's not working. I suspect the problem are the lines in bold above. I tried to get the element by 'class' and its id by using 'div_node.id'. I am assuming that by doing 'document.getElementByClass', I am getting the reference to that element so I could use it to manipulate its other attributes. But I am not sure... Could anyone pls enlighten me??
There is no getElementByClass() method. There is a getElementByClassName() but it's not available in every browser.
Here is one you can use:
// http://www.dustindiaz.com/getelementsbyclass/
function getElementsByClass(searchClass, node, tag) {
var classElements = new Array();
if (node == null) node = document;
if (tag == null) tag = '*';
var els = node.getElementsByTagName(tag);
var elsLen = els.length;
var pattern = new RegExp("(^|\\s)" + searchClass + "(\\s|$)");
for (i = 0, j = 0; i < elsLen; i++) {
if (pattern.test(els[i].className)) {
classElements[j] = els[i];
j++;
}
}
return classElements;
}
Then you can call it as
getElementByClass('evp-video-wrap');
Your ajax is a bit tricky, but here is a more general one:
function getXmlHttpObject() {
var xmlHttp;
try {
// Firefox, Opera 8.0+, Safari
xmlHttp = new XMLHttpRequest();
} catch (e) {
// Internet Explorer
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
}
if (!xmlHttp) {
alert("Your browser does not support AJAX!");
}
return xmlHttp;
}
function ajax(url, onSuccess, onError) {
var xmlHttp = getXmlHttpObject();
xmlHttp.onreadystatechange = function() {
if (this.readyState === 4) {
// onSuccess
if (this.status === 200 && typeof onSuccess == 'function') {
onSuccess(this.responseText);
}
// onError
else if(typeof onError == 'function') {
onError();
}
}
};
xmlHttp.open("GET", url, true);
xmlHttp.send(null);
return xmlHttp;
}
Finally your code becomes:
function switchvideo(url, vidnumber) {
var div_node = getElementByClass('evp-video-wrap')[0];
// make a call to the url, and execute the
// callback when the response is available
ajax(url, function( responseText ){
if (vidnumber == 2) {
div_node.id = 'evp-78c0b7c4f6d3377954825f145734fd5c-wrap';
}
document.getElementById(div_node.id).innerHTML = responseText;
});
}
You can see the whole code [here]
getElementByClass isn't a standard method. Is it possible for you to use a framework for this? jQuery has a nice mechanism to search for an element by class, as do the other frameworks. It also makes it much easier to do the AJAX bits in a cross-browser supported way.
function switchvideo(url, vidnumber)
{
$.get(url, function(data) {
var div_node = $('.evp-video-wrap');
if (vidnumber == 2) {
div_node.attr('id', 'evp-78c0b7c4f6d3377954825f145734fd5c-wrap');
}
div_node.html( data );
});
}
An alternative would be to write your own getElementByClass or specific code to search for a DIV by class. Note: I assume you're only interested in the first match.
function getDivByClass( klass )
{
var regex = new RegExp( '(^|\\s+)' + klass + '(\\s+|$)' );
for (div in document.getElementsByTagName('div')) {
if (regex.text( div.className)) {
return div;
}
}
return null;
}