Cannot display js script in ie using querySelectorAll in XMLdom - javascript

So I have been searching everywhere, tried everything, but still, my script doesn't display in IE!! Any version! It displays in FF and Chrome beautifully, but ie, AAAAAARGH!! I changed the doctype to <!DOCTYPE html>, I added the <meta http-equiv="X-UA-Compatible" content="IE=edge" /> tag to my head, checked that my browser wasn't in quirks mode, or compat mode and just running in standards mode, deleted my cookies, history and reset my ie settings, checked my security settings and still nothing! What else am I missing? I am looking for that "missing link" that will FINALLY display my script in ie. Any ideas or help will be greatly appreciated.
SITUATION: I am using an html template to display and XML file using js.
JS:
var xmlhttp, xmlDoc, y
var xmlhttp = new XMLHttpRequest();
if (window.XMLHttpRequest)
{
xmlhttp = new XMLHttpRequest(); // code for IE7+, Firefox, Chrome, Opera, Safari
}
else if (window.ActiveXObject)
{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); // code for IE6, IE5
}
xmlhttp.open("GET", "/localfile/xmlfilename.xml", false);
xmlhttp.send();
var xmlDoc = xmlhttp.responseXML;
var y = xmlDoc.querySelectorAll(".class1, .class2");
document.write("<ul id='feed' data-role='listview' data-inset='true'>");
for (i=0;i<y.length;i++)
{
document.write("<li><strong>"+y[i].getElementsByTagName("title")[0].childNodes[0].nodeValue+"</strong><br>"+y[i].getElementsByTagName("pubDate")[0].childNodes[0].nodeValue+"<br>"+y[i].getElementsByTagName("description")[0].childNodes[0].nodeValue+"</li>");
}
document.write("</ul>");
XML:
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<item class="class1">
<title>Update's Title</title>
<pubDate>28 Oct 2015</pubDate>
<description><![CDATA[Whatever the update is with some links.]]></description>
</item>
<item class="class2">
<title>Another Update Title</title>
<pubDate>1 Oct 2015</pubDate>
<description><![CDATA[Some more html tags in the !cdata.]]></description>
</item>
</channel>
</rss>
Like I said, I am using an html template and using js to render my XML data. It displays very nicely in Chrome and FF, but not in ie 5+ or edge. The beauty of it all is that I don't get any errors in either browser, except for the Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/ in both FF and Chrome, and get no errors in ie. I know JQuery has some cool methods, but would rather stick with js to display my content. Sorry for the frustration, but WTH am I doing wrong??

First of all, try to do the ajax stuff using jQuery.
If it works, you will know that the problem is the ajax code ...

After rechecking my ajax, I was searching for an alternative method for both getElementsByClassName and querySelectorAll, when I read an article about the XMLDocument Object: http://help.dottoro.com/ljbcjfot.php & read that neither was supported by ie. Ugh, gonna have to rewrite the script all over again, for the 3rd time, but using jQuery. It makes sense that ie's error console kept telling me that querySelectorAll method was not supported. rolling eyes Thanks for the help Guilherme.

FINALLY FOUND THE ANSWER!! My ajax works well when I loaded the entire xml document. However, when I added the parameters to filter and only display xml nodes with the specific classes instead of the entire document, getElementsbyClassName and querySelectorAll were not working in ie and later read that neither was supported by ie n-e version: http://help.dottoro.com/ljbcjfot.php. I researched for a long time trying out new solutions, and everything in js. I took your advice to use jquery to upload my doc and began using the parameters & methods to only display the nodes with specific classes, and it was cross browser compatible. In case anyone needs it:
jquery code
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js"></script>
</head>
<body>
<ul id="feed"></ul>
<script>
$.ajax({
type: 'GET',
url: '/file/rssfeed.xml',
dataType: 'xml',
success: function(xml){
$(xml).find("item.class1, item.class2").each(function(){
var title = $(this).find('title').text();
var date = $(this).find('pubDate').text();
var description = $(this).find('description').text();
$('#feed').append('<li><strong>'+title+'</strong><br>'+date+'<br>'+description+'</li>');
});
}
});
</script>
</body>
I added a ul tag in the html with the id="feed" and the lis fell in place for each post. Originally, I used the js to upload the xml document and display all the nodes in the html template, but had to use jquery to filter and display only the xml nodes with separate classes (item.class1, item.class2). The original js/ajax script, without the parameters, is cross browser compatible, and the jquery script I'm using now, filters and displays in Chrome, FF & IE!! Yay!! Take that ie!!

Related

Dynamically Inject JavaScript Modules in Edge Browser

I created a little demo here: https://codepen.io/min-width/pen/LYVVLwK
But just in case that gets lost in time, here is the JavaScript from that page (it's constructing a script tag with a type of "module" and injecting it into the page):
let value = `<script type="module">
let element = document.createElement("p");
element.appendChild(document.createTextNode("The JavaScript executed."));
document.querySelector("body").appendChild(element);
</scr` + `ipt>`;
let compiled =
document.createRange().createContextualFragment(value),
body = document.querySelector('body');
body.appendChild(compiled);
When working, it should say "The JavaScript executed" in the body of the page. This works fine in most browsers (and I accept that it doesn't work in IE since IE doesn't support modules at all).
My issue is that this does not work in Edge, even though Edge does have support for JavaScript modules: https://caniuse.com/#feat=es6-module
Edge just doesn't seem to like when modules are injected dynamically. Is there some client-side workaround for this? I currently have it working with a server-side check for "Edge" in the user agent (in which case I render the module immediately in the HTML rather than injecting it with JavaScript), but that doesn't feel like an optimal solution.
In case you are wondering, my use case is that I preload some JavaScript modules, then I inject them into the page when the user first interacts with the page (a page speed optimization that PageSpeed Insights seems to like).
Edit: Since somebody asked, here is the Edge version number info (from the settings):
It shows Edge 44 and EdgeHTML 18.
I tried to modify your code and it works with MS Edge 44 version.
<!DOCTYPE html>
<html>
<head>
<title>Demo page</title>
</head>
<body>
<script>
let se =document.createElement('script');
se.setAttribute('type', 'module');
se.innerHTML='var para = document.createElement("P"); para.appendChild (document.createTextNode("The JavaScript executed.")); document.querySelector("body").appendChild(para);';
let body = document.querySelector('body');
body.append(se);
</script>
</body>
</html>
Output in Edge browser:

Memory leak in IE: Due to ajax call using .load()

I am loading entire data of .html files in a div via ajax call. The html page contains link,script tags required for HTC(html component) to bind with the elements on page.
The structure of the page is like:
I am using jQuery to load HTML pages like this
<body>
<input type="radio" class="openpage" id="0001">
<input type="radio" class="openpage" id="0002">
<input type="radio" class="openpage" id="0003">
<input type="radio" class="openpage" id="0004">
<div id="loadPage"></div>
<script>
$(document).ready(function(){
$(".openpage").on("click",function(){
$("#loadPage").load($(this).attr("id")+".html",function(){
//load a page with many htc bindings and external references
//trigger some onload functions which are not called automatically in IE
//confirmed this is in chrome
});
});
})
</script>
</body>
The problem with this is that IE memory keeps pilling up as radio buttons are clicked to load pages and after loading few pages browsers stops responding.
I can see the memory going up in task manager.
The application runs in IE 5,6,7,8,9 and in quirks mode in IE10. I tried to replicate the same scenario in chrome and it showed no problem. So I think it is IE specific memory management related problem.
I read many articles but I was not convinced.I also read this question on SO but it suggests to load only some part of page which is not acceptable in my case.This article seems relevant but I am not sure what exactly causes memory leak in my case.
The entire body above is actually in a iframe . So as a workaround I reload the
frame with the main page containing after 8 clicks of radio button.
I have tried to clear stuffs before each load using:
$("#loadPages").empty();
$("#loadPages").find("*").off();
$.ajaxSetup({ cache: false });
But nothing works.So I doubt whether jquery can clear events registered through htc.
1) It would be great if you explain the reason of memory leak in this case.
2) And in general why memory leak can occur in a browser after loading many resources. This does not happen in modern browsers but why it occurred in older browsers.
3) Is there a way to release browsers memory without refreshing the frame.
4)Is there a way to check what all resources are residing in a browsers memory.
You have a couple of workflows:
Replace existing DOM structures by dynamically loaded structures.
Wire in additional event handling after load.
From here:
When removing/replacing DOM nodes, events are still bound
By being bound to event handlers, the DOM nodes may not be able to clear
DOM nodes persist in memory, detached from the UI, but still leaking memory.
Your options are:
Make certain to clear all events on existing structures before clearing those nodes from the DOM, and allowing the new content to load.
Have several nodes for display, and load each only one time.
Check if a node exists, and simply detach it, rather than try to replace it.
IE has separate COM channels for the JavaScript and the Rendering engine, this means that sometimes, particularly with event binding. Objects/state in JS can hold on to references to UI/DOM nodes... and DOM nodes can reference JS event handlers. In many cases this means that those portions won't be garbage collected leading to inflated memory usage. It was far worse with earlier versions, but still happens.
You can have similar issues with other browsers, but IE tends to display this behavior much sooner. This also happens more with long-living single page applications.
If you only load each resource once, into its' own DOM node, you can simply detach/reattach that node. Also, you can rely on event propagation to listen to events from the parent node. Either of these will reduce the risk of contention, and overhead.
As to unregistering your event handlers, jQuery does a better job than most with this, as long as you register with jQuery, and use jQuery to remove/delete the node (and its' children).
Have you ever consider to use xhr requests?
They can load the content to your target using ajax.
I did a sample fiddle to your question. Have a look at it.
Cheers.
Snippet
function getXmlHttpRequest() {
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
// code for IE7+, Firefox, Chrome, Opera, Safari
} else if (window.ActiveXObject) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
// code for IE5 and IE6
} else {
alert("Browser doesn't support Ajax..!!");
}
return xmlhttp;
}
function loadPage(pageTitle) {
//pageTitle = pageTitle + ".html";
xmlhttp = getXmlHttpRequest();
if (xmlhttp != null) {
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState < 4) {
document.getElementById('loadPage').innerHTML = "Content Loading...!";
} else if (xmlhttp.readyState == 4) {
var res = xmlhttp.responseText;
document.getElementById('loadPage').innerHTML = res;
}
}
xmlhttp.open("GET", pageTitle, true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send(null);
}
}
function showAlert() {
alert("This is me!");
}
$(document).ready(function() {
$(".openpage").on("click", function() {
loadPage($(this).attr("id"));
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<input type="radio" class="openpage" name="radio-group" id="https://dl.dropboxusercontent.com/u/105580681/xhr-fiddle/0001.html">
<input type="radio" class="openpage" name="radio-group" id="https://dl.dropboxusercontent.com/u/105580681/xhr-fiddle/0002.html">
<input type="radio" class="openpage" name="radio-group" id="https://dl.dropboxusercontent.com/u/105580681/xhr-fiddle/0003.html">
<input type="radio" class="openpage" name="radio-group" id="https://dl.dropboxusercontent.com/u/105580681/xhr-fiddle/0004.html">
<div id="loadPage"></div>
In this fiddle, i'm loading the html files using dropbox links. You can use your initial idea of 0001 - 0004 id numbers.
However if you are loading the entire content of a html page this will load everything from that external html page to inside of your targeted main page.
Example:
<div id="loadPage">
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<div>Content of HTML 0001 Page</div>
</div>
This will affect to your DOM file of the main page. Page functionality won't loose but it is not a good programming technic. So you probably need to write or load the content in xxxx.html files that you want to show on targeted element.
Learn more from
Using XMLHttpRequest Mozilla MDN
Using FormData Objects Mozilla MDN

Queries not retaining in Internet Explorer

Can't figure out why queries made in the search box are not being retained in IE (of course). Can somebody please open the link below in IE
http://www.adhuntr.com/p/results.html?ie=UTF-8&q=ipad+mini&min=&max=&l=all&c=all&t=&p=
The error is due to your addLoadEvent() function, calling just fillSearchBox() from the IE Dev Console fires this function correctly and populate the input box with the query.
Specially, the error is in this call: addLoadEvent(fillSearchBox);
I tried using the updated suggestion for the addLoadEvent function in jsFiddle without any success.
Since you are using jQuery just a little further down the code you can use this instead. Sample in jsFiddle:
jQuery(document).ready(function () {
fillSearchBox()
});
BTW, you have a typo on input.result, which is why the search does not submit automatically when you select a suggestion:
input
.attr ("autocomplete", "off")
.autocomplete ("http://clients1.google.com/complete/search", options)
.result (function () { searchform.submit(); }); //<== typo in this line, should be submit
You really should move all your inline code to external files, you have an awful lot of inline JavaScript and CSS in the page which need to be downloaded every time the page loads.
I am guessing by retaining, you mean show up in the search bar as you are typing, or suggestion? Well, it could be because, that older versions of IE namely 6,7 do not support the Ajax XMLHttpRequest() object, therefore... you have to change your ajax code, namely less than just one line, to check also for window.ActiveXObject of IE. by doing
if(window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest(); }
else if(window.ActiveXObject) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
else {
alert('Please update your browse, to see Ajax in Action :) ');
}

// #sourceurl on script tag in firefox

In firefox 19 and firebug 1.X I encountered a strange bug when trying //#sourceurl.
Basically I'm dynamically adding script tag through dom manipulation as you can see in the sample below. This does not work.
Maybe it's a limitation of ff but I find it odd that it works in chrome and not in ff.
Can you confirm this and do you have any bypass to this bug?
Ps: I don't want to use global eval() as it crash in ie when using document.write
<html>
<head>
<script type="text/javascript">
var count=0;
function addNewScriptToHead()
{
var newScriptElem;
var newScriptText;
newScriptElem = document.createElement('script');
newScriptElem.setAttribute('type', 'text/javascript');
newScriptElem.setAttribute('id', '' + count);
newScriptElem.text= 'console.log("Yay !");//# sourceURL=root/test'+count++ +'.js';
document.body.appendChild(newScriptElem);
};
</script>
</head>
<body>
<button onclick="addNewScriptToHead()">add script</button><br><br>
</body>
</html>
Experimentation has lead me to believe the following:
As of version 20.0, FF still does not support //# sourceURL directly in its inbuilt web console.
//# sourceURL does work with the Firebug addon in FF, but not completely as expected/hoped.
A. It only works for eval. It doesn't work at all for appended
script nodes like in the original question.
B. Errors will have a line number and the URL, and you can click
the error to see the line of code. However, console.log does not
seem to be affected and shows no line number or URL.
Testing this feature from within FF's web console is not advised. I got different results than testing directly in HTML at least some of the time.

Firefox not rendering jQuery templates

I'm using jQuery templates for a website I developed and they work perfectly fine on Chrome, Safari, and even IE9, but the templates just won't render on Firefox. I'm loading them externally, and the $.get is processed (I've checked Firebug, the get goes through and pulls the right file), but then I'm greeted with a blank page and inspecting the html reveals the body element contains only the footer (included in the html), but with display : none, which is how it should be, so the javascript ran to completion (since the footer is hidden inside the loadtemplate functions). It seems that Firefox is simply skipping the $.tmpl() call. Here's the function :
var loadTemplate = function(templateName){
$.get(templateName, function(template){
$.tmpl(template).appendTo("body");
});
};
var loadHomePage = function(){
history = [];
clearPage();
loadTemplate("./templates/home.tmpl");
current_page = "./templates/home.tmpl";
}
var clearPage = function(){
$(".page-content").remove();
$(".page-header").remove();
$("#popup-container").remove();
$(".page-footer").hide();
};
Any help would be greatly appreciated, I can follow up with more code if required as well.
EDIT: even works on Opera, I don't need to support it so the styles don't work (using LESS which Opera doesn't support and a css file strictly for IE), but it still loads the templates without a problem.
Requesting a template may get processed as HTML by some browsers, which in-turn can result in a mangled template. Try setting the datatype to "text" so that all browsers properly return un-modified text.
$.get(templateName, function(template){
$.tmpl(template).appendTo("body");
}, "text");

Categories

Resources