IE9 sees XML nodes at different indexes than other browsers - javascript

Here is a snippet from my attempt at cross-browser functionality:
xmlhttp.open("GET", "/wp-content/testimonials.xml", true);
if (xmlhttp.addEventListener) {
xmlhttp.addEventListener("load", retrieveTestimonial, false);
}
else if (xmlhttp.attachEvent) {
xmlhttp.attachEvent("onload", retrieveTestimonial);
}
xmlhttp.send();
function retrieveTestimonial () {
xmlDoc = xmlhttp.responseXML;
//Get DOM elements ready to be replaced by relevant testimonial info
var testimonial = document.getElementById("foot-testimonial");
var xmlTags = xmlDoc.getElementsByTagName("PROGRAM");
... more
The reason I included this particular block of code is because my script renders just fine in Chrome, Firefox, IE11, Safari, and even the stock Android browser. However, in IE9 I'm getting undefined for some variables that are set in the retrieveTestimonial function. If I try to log any of those variables (xmlTags, etc.) out to the console in IE9 I get 'is undefined'. So, from what I can tell, the function is not being called which suggests to me that the XHR load event is not firing.
EDIT: The function is firing, as I am able to log the variable xmlDoc to the console (object). For some reason, IE9 does not like some of my XML assignments because they are returning undefined. Here is the rest of the function:
for(var i = 0; i < xmlTags.length; i++) {
//If the program name from the URL matches the <WEBTITLE> value
if (progName == xmlTags[i].childNodes[1].childNodes[0].nodeValue) {
// Get each relevant piece of info from the XML file
var progTitle = xmlTags[i].childNodes[3].childNodes[0].nodeValue;
var studentName = xmlTags[i].childNodes[5].childNodes[0].nodeValue;
var textBody = xmlTags[i].childNodes[7].childNodes[0].nodeValue;
break;
}
IE9 does not seem to like seeing nodes at the same index as other browsers, though I haven't a clue as to why.
Is there a known workaround for this or am I just missing something simple? I'd hate to rewrite the script in jQuery, for instance, considering it's working like a charm everywhere else.

Related

Is it possible to cache a XML within a Javascript/HTML, if so how to?

I currently have the following Javascript as part of my HTML
function guide1(i) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
guideload1(this, i);
}
};
xmlhttp.open("GET", "tvguidedata.xml", true);
xmlhttp.send();
}
function guideload1(xml, i) {
var i
var xmlDoc = xml.responseXML;
x = xmlDoc.getElementsByTagName("programme");
for (i = 1; i <x.length; i++)
if (*blah blah blah, the script starts working here, I assume its not necessary posting it in full*)
This script works as intended and so far so good.
However I would like to improve a small part of it for (what I consider) better performance of the overall intend.
Currently I have another script that is calling the above script at an set interval to make sure the data displayed inside my HTML is current (TV Guide airings)
Checking the chrome dev tools, I can see each time the script is running it re-downloads the full xml.
While the XML file is small, I would prefer it to only load/download the xml once and then be able to loop my script with the data being processed from a cached xml.
Is this even possible at all? And if so how?
I already tried my setInterval script to directly call the "guideload1" function instead of "guide1, however then I get an error and the script is not loading data correctly.
Maybe there is a script that first loads the XML into cache, local storage or whatever would be used in this case and any subsequent calls to "guide1" function and/or "guideload1" then take the cached file and don't make any download requested.
And the script that caches the XML, I would most likely set it to only reload/download once after 12 hours.
Any help is appreciated, I should also note that I know almost zero about coding (I got most of my coode by google search and similar) so if an explanation is necessary feel free to phrase it like I'm a baby.
Other information, I believe could be useful:
Cross-Browser compatibility is not required/necessary.
My whole HTML is only opened on Chrome browswer on Windows in kiosk mode.
There is never any user interaction, as the page is displayed to a HDMI-OUT/Modulator and certain sub-HTML elements are reloaded every day at midnight

Uncaught TypeError: Cannot set property 'innerHTML' of null

Working with Ajax... I cannot seem to figure out what is wrong here. The error occurs on the code: objUserID.innerHTML = username;. It thinks the variable username is null. username does have data in it because the following code confirms it: console.log("user: ["+username+"]"); Can anyone figure this out?
function actionBid(bidID,bidA,bidAction){
var XMLHttpRequestObject = false;
if (window.XMLHttpRequest)
{
// code for IE7+, Firefox, Chrome, Opera, Safari
XMLHttpRequestObject = new XMLHttpRequest();
}
else if (window.ActiveXObject)
{
// code for IE6, IE5
XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");
}
if(XMLHttpRequestObject)
{
// ==== GET BID ====
if (bidAction == "getbid"){
var objUserID = document.getElementById("curBidUser"+bidID);
var res = XMLHttpRequestObject.responseText;
var username = res.substring(0,res.indexOf(','));
console.log("user: ["+username+"]");
objUserID.innerHTML = username;
}
}
}
It thinks the variable username is null
False. It is telling you that it cannot access the property innerHTML of null. In other words, that objUserID is null and that you cannot access a property of it.
Put another way, your element does not exist.
If you are having this problem, it might be because you have placed your script tag at the top of the body tag before everything else. You want to place your script tag at the bottom of the body tag.
Actually it was an loading issue check with the follow code.
setTimeout(function(){
xYzFunction();
}, 3000 )
It means that the element or the object is not found. It doesn't exist.
Here is a fiddle: http://jsfiddle.net/afzaal_ahmad_zeeshan/cF6Bh/
You can see, that the code works. But the element's not present for the JavaScript to work on.
Make sure that the element is present. Either you need to make sure the characters are OK or something like that.
document.getElementById("objectId").innerHTML = "Text";
So the remedy to this would be, to change the ID param that you're passing onto the method.
actually this error can be also caused by calling like this document.getElementById("#content-content").innerHTML=output;
instead of like this
document.getElementById("content-content").innerHTML=output;

Illegal invocation with start/noteOn using Web Audio API

So basically I've tested this in Chrome and maybe the order of codes is off or whatever, trying to cover some of the functionality of HTML5 audio using "web audio" due to the range requests bug, for the making of games with looping sound effects and music...
I get an "illegal exception" error. Here's the code:
var url='example.mp3';
var a_result=new Object();
a_result.loaded=false;
a_result.evalstring='';
a_result.loop=false;
a_result.play=function(){
var asrc=a_result.source;
asrc.loop=a_result.loop;
//try{
var playfunc=asrc.start||asrc.noteOn;
playfunc(0);
//}catch(e){
/* do nothing */
//}
}
a_result.pause=function(){
var asrc=a_result.source;
try{
var stopfunc=asrc.stop||asrc.noteOff;
stopfunc(0);
}catch(e){
/* do nothing */
}
}
var asrc=actx.createBufferSource();
asrc.connect(actx.destination);
var req=new XMLHttpRequest();
req.open('GET',url,true);
req.responseType='arraybuffer';
req.onload=function(){
if(a_result.loaded==false){
asrc.buffer=actx.createBuffer(req.response,false);
a_result.source=asrc;
a_result.loaded=true;
}
var cont=a_result;
eval(cont.evalstring);
}
req.onerror = function() {
if(a_result.loaded==false){
a_result.loaded=true;
}
}
try{
req.send(null);
}catch(e){
req.onerror();
}
return a_result;
And then later on after the sound has loaded I do something like:
a_result.play();
And instead of playing it gives the error.
Here is a sound test that uses the above code with the fix suggested below, and it works in Chrome, successfully working around the range requests issue on a crappy web server. Here is another that has issues (throwing some kind of "invalid string" error at asrc.buffer=actx.createBuffer(req.response,false); in Iron and silently screwing up in Chrome).
Here is the code edited according to the suggestions:
var url='example.mp3'
var a_result=new Object();
a_result.loaded=false;
a_result.evalstring='';
a_result.loop=false;
a_result.play=function(){
var asrc=a_result.source;
asrc.loop=a_result.loop;
try{
if(asrc.start){
asrc.start(0);
}else{
asrc.noteOn(0);
}
}catch(e){
/* do nothing */
}
}
a_result.pause=function(){
var asrc=a_result.source;
try{
if(asrc.stop){
asrc.stop(0);
}else{
asrc.noteOff(0);
}
}catch(e){
/* do nothing */
}
}
var asrc=actx.createBufferSource();
asrc.connect(actx.destination);
var req=new XMLHttpRequest();
req.open('GET',url,true);
req.responseType='arraybuffer';
req.onload=function(){
actx.decodeAudioData(req.response,function(buffer){
if(buffer){
if(a_result.loaded==false){
asrc.buffer=buffer;
a_result.source=asrc;
a_result.loaded=true;
}
var cont=a_result;
eval(cont.evalstring);
}
});
}
req.onerror = function() {
if(a_result.loaded==false){
a_result.loaded=true;
}
}
try{
req.send(null);
}catch(e){
req.onerror();
}
return a_result;
It no longer appears to have a syntax error, however, it does not seem to solve the playability issues on Chrome (second test case above updated). Specifically, after a sound is stopped it does not want to play again. -- Apparently because it's in the spec. The buffer has to be applied to a new sound source every time you play.
In your new page, you're calling createBuffer(data, false) on the results of an XMLHTTPRequest. You almost certainly want to be calling decodeAudioData() on those results, instead - createBuffer doesn't have a 2-parameter version, and doesn't match the parameters you're passing even if you're trying to push arbitrary data into a buffer. It appears from a browse of your code that you're pulling down MP3 or Ogg files - you need to decode them.
The play method (either start() or noteOn()) needs to be invoked ON the buffersourcenode object, not disassociated from it. You have a few options:
1) I'd strongly recommend just including my audio context monkeypatch library (https://github.com/cwilso/AudioContext-MonkeyPatch/) and using the new (start()) syntax. no muss, no fuss.
2) You can just use an if statement instead of using playfunc to switch:
if (asrc.start)
asrc.start(0);
else
asrc.noteOn(0);
3) You can bind() the play function to the object and keep your code essentially the same:
var playfunc=asrc.start ? asrc.start.bind(asrc) || asrc.noteOn.bind(asrc);
playfunc(0);
4) You can push the playfunc() method onto the object itself (I think this will work):
asrc.playfunc=asrc.start||asrc.noteOn;
asrc.playfunc(0);

IE 10 + jQuery - Not able to use "append" function

I am running an HTML 5 application using the KendoUI framework. Once of the screens deal with XML data that needs to be parsed and processed.
This screen needs to be shown as a popup and that data is shown in a grid inside this popup. To do this, I am calling a function on clicking the "show-popup" button inside which I have the following piece of code :
var tTranslationXML = XMLFromString(_SelectedCategoryValueRecord.DisplayTextTranslation);
.
.
.
// other stuff but nothing that changes "tTranslationXML"
.
.
if (_SelectedCategoryValueRecord.DisplayTextTranslation) // and there are values in the translation field
{
var $language = $(tTranslationXML).find('Language');
var $oldTranslation = $($language).find("en-US");
if ($oldTranslation.length == 0)
$oldTranslation = $($language).find(GetCorrectedCase("en-US"));
if ($oldTranslation.length == 0) {
var $newTranslation = $.createElementNS("en-US").text(_UpdatedDisplayText);
$language.append($newTranslation);
}
}
And if you are wondering what "XMLFromString" is, its nothing but a simple helper to parse the XML data from a string variable
function XMLFromString(pXMLString)
{
if (!pXMLString)
pXMLString = "<Language></Language>";
if (window.ActiveXObject) {
var oXML = new ActiveXObject("Microsoft.XMLDOM");
oXML.loadXML(pXMLString);
return oXML;
} else {
return (new DOMParser()).parseFromString(pXMLString, "text/xml");
}
}
My issue is that this works fine on Chrome and Firefox but I get an error in IE10 when this particular line executes -
"$language.append($newTranslation);"
I am basically trying to append a new translation value to the contents of my variable here.
The error is as follows :
SCRIPT13: Type mismatch
jquery-1.8.3.min.js, line 2 character 71981
Any ideas on how to solve this?
Sorry for the delayed response.
I figured out that the issue was to avoid using the method "createElementNS" and instead use the "createElement" method when creating the parent node. Subsequent appendages to this node do not throw up any issues. However there will issues when you append to a node that was originally created using "createElementNS".
This seems specific to IE10 because the NS method worked fine on chrome, FF and Safari.
Thank you all for the tips and ideas.

How do I get HTML Markup for createRange() in Firefox

I am currently using code similar to this:
try {
// IE ONLY
var theElement = "myElementName";
window.frames[theElement].focus();
var selection = window.frames[theElement].document.selection.createRange();
alert ( selection.htmlText );
} catch(e) {
var selection = window.frames[theElement].document.getSelection();
alert ( selection );
}
As you can see, I am accessing a node from an iframe (no fun already). I am definitely in new territory here, so am sure there are more issues to arise, but right now, I am trying to get Firefox to give me the same result as IE.
In IE, I can access the HTML code of the selection by using the (apparently IE-only) htmlText property of the object returned by createRange(). What I am looking for is the Firefox equivalent to that (or a function that I can use to give me the same result).
Anyone know how to do this?
This works in Firefox 2 and later (untested in earlier versions):
var selection = window.frames[theElement].getSelection();
var range = selection.getRangeAt(0);
var div = document.createElement("div");
div.appendChild(range.cloneContents());
alert(div.innerHTML);

Categories

Resources