Javascript works in FF / IE but not Chrome / Safari - javascript

I'm working on a Drupal 6 module where I use jquery (and more specifically, the $.ajax method) to retrieve a RSS feed from Yahoo's weather API. I decided against using the JFeed library because I need access to the elements with "yweather" prefix (and I couldn't find a way of accessing them via JFeed). I decided to use the $.ajax method and parse the XML response instead. The JavaScript code below works fine in Firefox and IE but does not work in Safari (or Chrome FWIW):
function parseXml(xml) {
var atmosphere = xml.getElementsByTagName("yweather:atmosphere");
var humidity = atmosphere[0].getAttribute("humidity");
$('#weatherFeed').html("Humidity: " + humidity);
$('#weatherFeed').append(
"<div style=\"text-align: center;margin-left: auto; margin-right: auto;\">" +
city + ", " + state + "</div>");
}
function getData(){
$.ajax({
type: 'GET',
url: 'proxy.php?url=http://weather.yahooapis.com/forecastrss&p=94041',
dataType: 'xml',
success: function(xml) {
parseXml(xml);
}
});
}
if(Drupal.jsEnabled) {
$(function() {
getData();
setInterval("getData()", 30000);
});
}
When I check the error console in Safari I see the following error message: TypeError: Result of expression 'atmosphere[0]' [undefined] is not an object. Is there an issue with using getElementsByTagName in Safari? Should I be accessing the object that's returned by getElementsByTagName differently?

Maybe just treating the the XML as data and using jQuery selectors to pull out what you want would work.
$(xml).find("yweather:atmosphere").attr("humidity") - you might need to use filter instead of find - what do you think?

I had the exact same problem, but came across the answer here:
http://reference.sitepoint.com/javascript/Document/getElementsByTagName
It has to do with the yweather namespace. Use getElementByTagNameNS function instead.
var atmosphere = xml.getElementsByTagName("yweather:atmosphere");
becomes
var atmosphere = xml.getElementsByTagNameNS("http://xml.weather.yahoo.com/ns/rss/1.0","atmosphere");
function reference:
http://reference.sitepoint.com/javascript/Document/getElementsByTagNameNS

Have you tried atmosphere[1] instead of 0 for Chrome and Safari?

Related

Alternatives for jQuery .html() method?

I am currently developing a single page application, using phonegap. What i am trying to realize is to initially parse a xml file and store the content for further usage.
At the moment everything works fine but there is one major problem:
Within my xml file there is a a tag which contains html formatted text content. For example:
<textfield> <h1>Title</h1> Content </textfield>
What i currently do is to load my xml file via jQuery ajax call and then use the html() method to retrieve my textfield html:
this.description = $(Obj).find("textfield").html();
On Google Chrome, Firefox and Android this works fine. The html is stored an can later be appended to my objects. However on Safari and therefore on Iphone devices the html() does not work. Now i am looking for a workaround. I certainly do not want to use text() because my formatting will be ignored.
EDIT: My ajax call:
$.ajax({
type: "GET",
url: Controller.baseURL+"/"+name+".xml",
async: false,
timeout:3000,
dataType: "xml",
success: function (data) {
alert("succ");
xml = data;
},
error: function () {
alert('error!');
}
});
Maybe someone can help me.
Thanks in advance
var parser = new DOMParser();
var parsed = parser.parseFromString(yourXMLStringLoadedViaAjax, 'text/xml');
var textfieldConetent = parsed.querySelector('textfield').innerHTML;
After a few hours of search I finally found my answer here:
https://stackoverflow.com/a/25789924/3566334
It seems that
In IE 9, 10 and 11, Safari 7.0 and Opera 12, the nodes in doc have neither an innerHTML field nor an xml field
I followed the advice of using XML Serializer and it works like a charm!

How to write RIGHT a javascript if foler exist command [duplicate]

This question already has an answer here:
how to make Correctly a javascript if exist (folder) command?
(1 answer)
Closed 8 years ago.
Hello stackoverflow users
I have been trying for some time to design a script.
In this script I will look for commands with an if query whether a folder exists.
I do this by using a variable make so shall he find the path using the variable.
So as follows "backgrounds /" + variable;
Here's my script:
var mapname = "dolls";
$.get( "backgrounds/" + mapname )
.done(function() {
var eld = mapname ;
}).fail(function() {
var eld = "default";
})
I'm using JQuery version 1.3.2.
I get the following error in the JS Console
Uncaught TypeError: Object #<XMLHttpRequest> has no method 'done'
does anyone know how I write this code right?
thanks ahead...
Your code will attempt to do a GET-request to the URL you specified, which doesn't necessarily mean that it is a folder. If you try this on your local machine without a web server and provide a folder name, the browser will look for "index.html" or "index.htm" in that folder. If it finds one, it will succeed, which is not really what you're after..
About actual filebrowsing. Javascript does not allow file browsing for security purposes.
JQuery 1.3 ajax GET request would look something like this
var mapname = "dolls";
var eld;
jQuery.ajax({
type: "GET",
url: "backgrounds/" + mapname,
success: function(response) {
eld = mapname;
},
error: function(msg) {
eld = "default";
}
});
Here's the Fiddle

is there an alternative method to json.parser for ie [duplicate]

This question already has answers here:
what is the json data format ie understands?
(2 answers)
Closed 9 years ago.
I am using ie8 and so does everybody else. I need to make this script work for ie8. I cannot make json.parser work on IE. I tryied some of the recommendations that I saw here like json2.js modify html file etc. It does not seem to be working. Is there an alternative to this method? I really need this working and cannot figure out.
get_cpu.php outputs the data as this:
[1230000000,23]
This is my function. It works on chrome, firefox but not IE.
$(document).ready(function() {
function request_cpu_Data() {
$.ajax({
url: 'get_cpu.php',
success: function(data) {
alert(data.length);
var myObj = JSON.parse(data);
var point = cpu_chart.series[0].points[0];
var newVal=myObj[1];
myDate=myObj[0];
point.update(newVal);
setTimeout(request_cpu_Data, 1000000);
},
cache: false
});
}
It possibly throws an exception because it cannot parse the data that your server returns.
I suspect IE8's implementation cannot parse JSON arrays.
You can try this, for example: https://github.com/douglascrockford/JSON-js/blob/master/json2.js

Memory Leak When Pulling JSON from WEB

I've spent days on this and hit it from every angle I can think of. I'm working on a simple windows 7 gadget. This script will pull JSON data from a remote web server and put it on the page. I'm using jQuery 1.6.2 for the $.getJSON. Script consumes more memory each loop.
var count = 1;
$(document).ready(function () {
updateView();
});
function updateView(){
$("#junk").html(count);
count++;
$.getJSON( URL + "&callback=?", populateView);
setTimeout( updateView, 1000 );
}
function populateView(status) {
$("#debug").html(status.queue.mbleft + " MB Remaining<br>" + status.queue.mb + " MB Total");
}
Any help would be greatly appreciated....Thank you!
EDIT: Add JSON data sample
?({"queue":{"active_lang":"en","paused":true,"session":"39ad74939e89e6408f98998adfbae1e2","restart_req":false,"power_options":true,"slots":[{"status":"Queued","index":0,"eta":"unknown","missing":0,"avg_age":"2d","script":"None","msgid":"","verbosity":"","mb":"8949.88","sizeleft":"976 MB","filename":"TestFile#1","priority":"Normal","cat":"*","mbleft":"975.75","timeleft":"0:00:00","percentage":"89","nzo_id":"-n3c6z","unpackopts":"3","size":"8.7 GB"}],"speed":"0 ","helpuri":"","size":"8.7 GB","uptime":"2d","refresh_rate":"","limit":0,"isverbose":false,"start":0,"version":"0.6.5","new_rel_url":"","diskspacetotal2":"931.51","color_scheme":"gold","diskspacetotal1":"931.51","nt":true,"status":"Paused","last_warning":"","have_warnings":"0","cache_art":"0","sizeleft":"976 MB","finishaction":null,"paused_all":false,"cache_size":"0 B","finish":0,"new_release":"","pause_int":"0","mbleft":"975.75","diskspace1":"668.52","scripts":[],"categories":["*"],"darwin":false,"timeleft":"0:00:00","mb":"8949.88","noofslots":1,"nbDetails":false,"eta":"unknown","quota":"","loadavg":"","cache_max":"0","kbpersec":"0.00","speedlimit":"","webdir":"","queue_details":"0","diskspace2":"668.52"}})
EDIT 2: Stripped code down to this and it still leaks. I think that eliminates traversing the DOM as a contributor.
$(document).ready(function () {
setInterval(updateView, 1000);
});
function updateView(){
$.getJSON( URL + "&callback=?", populateView);
}
function populateView(status) {
}
EDIT 3: It's not jQuery. I removed jQuery and did it with straight js. Still leaks.
function init(){
setInterval(updateView, 1000);
}
function updateView(){
var xhr = new XMLHttpRequest();
xhr.open("GET", URL, false);
xhr.setRequestHeader( "If-Modified-Since", "0");
xhr.send('');
}
So...if it's not jQuery, not just in IE (Chrome too). What the heck?! Ideas?
Thank you!
Edit 2:
If it's actually taskmanager showing the leak here, then I think the next step is to investigate IE, as I believe that IE is then engine used to host Windows Widgets.
If you can recreate your script in a little html file you can run this tool and have a look if it's IE that's doing it:
http://blogs.msdn.com/b/gpde/archive/2009/08/03/javascript-memory-leak-detector-v2.aspx
Also, are you running IE8 or 9 ?
Edit:
Based on the JSON string in the Op; basically the problem is misleading here.
the bit of javascript posted is working perfectly fine.
The Server producing the JSON is the one that's showing a difference in memory usage, I would investigate the website/endpoint that's creating that JSON and seeing what the issue is.
Just had a thought,
$.getJSON is just a shorthand function for jQuery's $.ajax call.
I wonder if it makes a different if you change your code to use $.ajax but specifically add the cache mechanism to it:
$.ajax({
url: URL + "&callback=?",
dataType: 'json',
cache: false,
success: populateView
});
That might stop it trying to store it in memory perhaps, and depending on your browser, it might be showing more memory because you just haven't had your garbage collected, so to speak.
I have the feeling that the setTimeout function within the updateView is causing this behaviour. To test this you can modify your code to:
$(document).ready(function () {
setInterval(updateView, 1000);
});
function updateView(){
$("#junk").html(count);
count++;
$.getJSON( URL + "&callback=?", populateView);
}
function populateView(status) {
$("#debug").html(status.queue.mbleft + " MB Remaining<br>" + status.queue.mb + " MB Total");
}
EDIT: The setInterval function will execute the passed in function over and over every x miliseconds. Here to the docs.
EDIT 2:
Another performance loose (Although it might not be critical to the issue) is that you are traversing the DOM every second to find the $('#debug') element. You could store that and pass it in as:
$(document).ready(function () {
var debug = $('#debug');
var junk = $('#junk') ;
setInterval(function(){updateView(debug, junk)}, 1000);
});
function updateView(debug, junk){
junk.html(count);
count++;
$.getJSON( URL + "&callback=?", function(status){populateView(status,debug)});
}
function populateView(status) {
debug.html(status.queue.mbleft + " MB Remaining<br>" + status.queue.mb + " MB Total");
}
Edit 3: I have changed the code above because I forgot to take in the response from the server. Assuming that queue is a property of the returned JSON then the code should be as above.
Edit 4: This is a very interesting issue. Another approach then. Lets assume then that there is still some client side scripts that are clogging the memory. What could this be? As far as is I understand the only two things left are the setInterval and the $.getJSON function. The $.getJSON function is a simple ajax request wrapper which fires a request and waits for the response from the server. The setInterval function is a bit more peculiar one because it will set up timers, fire functions, etc.
I think if you manage to mimic this on your server or even just refresh this webpage in your browser every second/5 secs you you will be able to see whether it is the client or the server that processes your request.
Found this thread trying to find the underlying reason to this problem because I also had a similar problem recently although my memory would increase about 1Mb per minute... I pretty much isolated it to json parsing. Run the ajax command with type: 'text', and you should see that the memory gets cleaned up.
I found a library json_parse.js which recursively parses the json data using the JS engine (not eval). I manually parse the text data to json in the success callback and this works well.

jquery append not working in IE/Firefox

I have the following HTML and subsequent jQuery which appends the related HTML elements after the JSON request has been retrieved.
This implementation works in Google Chrome + Android browser + Safari, but is not populating the data in Firefox or Internet Explorer 9.
** Works in Chrome, Android browser, Firefox 4 ... does not work in Firefox 3.x and IE.
Static HTML:
<header class=line>
<div class="unit size3of4">
<h2 class="fullname"></h2>
<h4 class="nickname"></h4>
</div>
</header>
The jQuery code:
<script>
function load_user_info() {
var content_url = 'rest.api.url.com';
$.getJSON(content_url, {id:'11xx1122xx11'}, function(data){
console.log(data);
$.each(data, function(key, value) {
if (key == "fullname") {$('.fullname').append(value);}
else if (key == "nickname") {$('.nickname').append(value);}
});
});
}
load_user_info();
</script>
Slightly confused about the behavior between browsers. I can guarantee the JSON request is returning two variables: fullname & nickname and have confirmed this
In Firefox using the FireBug plugin I see the results of console.log(data).
In Chrome I see the results of the console.log(data) and the successful display of the fullname & nickname in the HTML after the JSON request.
Using jQuery 1.6.1 if it helps ...
JSON Output:
{"fullname":"johnny fartburger", "nickname":"jf"}
I'm slightly perplexed by what you're doing. I think the following code:
$.each(data, function (key, value) {
if (key == "fullname") {
$('.fullname').append(value);
} else if (key == "nickname") {
$('.nickname').append(value);
}
});
could be more easily represented by this:
$('.fullname').append(data.fullname);
$('.nickname').append(data.nickname);
I don't know if this will solve your problem, but it would certainly be an improvement.
The resulting problem was from the actual JSON data not being retrieved in IE. Hours and hours of search turned up the problem was that XDomainRequest is not natively supported by jQuery, specifically in a $.getJSON request
http://bugs.jquery.com/ticket/8283
In the end, I wrote a try {} catch {} statement that checks to see if $.browser.msie and if it is, do not use $.getJSON to retrieve the results, rather:
if ($.browser.msie) {
var xdr = new XDomainRequest();
xdr.open('GET', url);
xdr.onload = function() {
var data = $.parseJSON(this.responseText);
show_data(data);
}
xdr.send();
} else {
$.getJSON(url, function(data){
show_data(data);
});
}
So ... conclusion append does work in IE (7/8/9) and Firefox (3/4) but not when the AJAX results aren't being returned. Thanks everyone for your help and insight.
.append(value) is not very safe (for example if value="div").
You should use .html(value)
And what does data contain? I think .append is used to append elements. If data is plain text, that might not work (haven't tried it actually). Chrome uses a different engine and may convert the text to a textnode in the DOM.
Use .text() or .html() to set the contents of an element.
as an alternative with appendTo, try to use .text() too
.append() takes a HTML string as a parameter to append to the existing content. You probably want to replace the element's text, use .text() or .html() instead, depending on the contents of the value variable.

Categories