IE9 appending svg to DOM when you have custom namespaces in it - javascript

I have this problem that I am stuck for several days now. I am trying to append a svg to the DOM. I have custom namespaces in it and when they are added into the DOM and you try to get the innerHTML property of the parent element to which you appended them you get them with some random namespaces. This happens only in IE9.
Example:
$(document).ready(function () {
var svg = '<svg xmlns="http://www.w3.org/2000/svg" ns:attr="val" />';
alert($("div").append(svg).html());
});
The output will be:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:NS1="" NS1:a:b="val" />
Any idea how could this be solved? I've tried to define the namespaces but it's not working again. Here's a jsfiddle link http://jsfiddle.net/RwNqk/3/
Thanks in advance.

First, you have an HTML document—instead of XHTML—in your JSFiddle. HTML does not have custom namespaces, only XML/XHTML has that.
Secondly, you are using a ns namespace prefix without ever defining what that namespace is. It's a wonder that other browsers work at all.
Thirdly, even if you fix these problems, you (unfortunately) can't use jQuery to jam elements into the DOM using previously-defined namespace prefixes:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:foo="hello"><head>
<title>Using jQuery to add namespaced attribute</title>
</head><body>
<div><p foo:bar="yes">one</p></div>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript"><![CDATA[
var xhtml = '<p foo:bar="no">two</p>';
alert($('div').html());
try{ $('div').append(xhtml); }
catch(e){ alert(e); }
]]></script>
</body></html>
The first alert shows that the custom namespace works:
<p xmlns="http://www.w3.org/1999/xhtml" foo:bar="yes" xmlns:foo="hello">one</p>
The second alert shows the failure:
[Firefox] "An invalid or illegal string was specified" code: "12"
[Chrome] Error: SYNTAX_ERR: DOM Exception 12
[IE9] DOM EXception: SYNTAX_ERR (12)
This has nothing to do with IE9 or SVG. It mostly has to do with jQuery. (You can set the .innerHTML of the DOM element in IE9 and FF and it will work as desired, but not with Chrome.)

Related

How to suppress or exclude CSS file from shiny header without reloading app [duplicate]

I don't want to use styles from style.css, so I decided to remove style.css from DOM. This work just fine in Firefox and IE8, but not in IE6:
$("LINK[href='http://www.example.com/style.css']").remove();
Any other solution, with jQuery?
Here is example:
HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Testing</title>
<script type="text/javascript" src="path/to/jquery.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("link[href*='style.css']").remove();
});
</script>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<div id="content">...</div>
</body>
</html>
And here is CSS (style.css):
#content {
background-color:#333;
}
Only in IE #content is still dark. :(
Maybe is jQuery bug?
This is not a bug in jQuery, it is a bug (or possibly, a feature) of the IE rendering engine.
It seems this problem is being caused by the fact that Internet Explorer does not correctly re-render the page after removing the LINK element from the DOM.
In this particular case, the LINK tag is no longer present at the DOM, but IE still displays the CSS that has been loaded into memory.
A workaround / solution for this is to disable the stylesheet using the .disabled property like this:
// following code will disable the first stylesheet
// the actual DOM-reference to the element will not be removed;
// this is particularly useful since this allows you to enable it
// again at a later stage if you'd want to.
document.styleSheets[0].disabled = true;
EDIT in reply to your comment:
Or, if you want to remove it by the href use the following code:
var styleSheets = document.styleSheets;
var href = 'http://yoursite.com/foo/bar/baz.css';
for (var i = 0; i < styleSheets.length; i++) {
if (styleSheets[i].href == href) {
styleSheets[i].disabled = true;
break;
}
}
Perhaps it's something strange IE6 does to URL in the href attribute? Try something like:
$("LINK[href*='style.css']").remove();
(i.e. check whether the href value contains "style.css")
It's just a guess, however. If that doesn't work, I recommend checking the JQuery documentation closely on the subject of attribute selectors and the remove method.
Also keep in mind that it's also not impossible that it's in fact a bug. (IE6 in general causes lots of issues involving JavaScript and DOM manipulation, among other things.)
Topic's quite old, but You can only add ID to your link element, and delete it by element:
$("#id").remove();
Maybe using lowercase on the tag name?

Getting SCRIPT5009: 'id' is undefined in Internet Explore IE 11

I have a very simple script(setUser) which is called on click of a button.This script is working fine in chrome but in IE 11 i am getting a console error.
Another weird thing is i am getting that error only when dev tool is open.It works fine if devtool is not open.
Error is :-
SCRIPT5009: 'id' is undefined
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript">
function setUser(eventType){
console.log(eventType);
}
</script>
</head>
<body>
<button id="vish" onclick="setUser(id)" style="height:40px;width:200px">Click Me</button>
</body>
</html>
Simple Workaround for this is to declare a
var id; just below the script.But i need the proper documented reason why this doesnot work in ie11 but same works in chrome.And is a better solution than what i tried
Workaround :- by adding var id at the top
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript">
var id;
function setUser(eventType){
console.log(eventType);
}
</script>
</head>
<body>
<button id="vish" onclick="setUser(id)" style="height:40px;width:200px">Click Me</button>
</body>
</html>
expected :-
when dev tool is open in ie11 and when we click the button we should get the console log as "vish"
actual result :-
SCRIPT5009: 'id' is undefined js error
id is simply undefined, as the error message says. If you declare it, the error is gone, but it won't behave like you expected. If you declare it, it exists with value undefined. You probably wanted
onclick="setUser(this.id)"
this.id means the button context, while simply id tries to find it in global context. In case of your error, id is not declared, whereas
var id; // or var id=undefined;
declares it, and leaves it undefined, so the browser at least knows it is a variable. By saying id is undefined Explorer means it is not declared.
I believe the reason is that the browser searches for variables and named elements (referenced by name or id attribute; this is not standard, but browsers do it), which actually doesn't exist in global context and are looked up by reference and Explorer obviously can't handle this situation. If it is declared as var, javascript knows it is not a named element reference.
Example below shows the non-standard behaviour: it should end with error test is not defined (it really is not), but browsers say hello.
<input id="test" value="hello">
<script>
alert(test.value);
</script>
The cause of it not working in IE11 is because you do not specify a doctype for the HTML document in the block of code that threw the error.
If I add <!DOCTYPE html> to the start of the HTML, as in the workaround you show; it works in IE11 as well for me, without adding the var id;
The exact reason is unknown to me, but without the doctype, IE will run the page in quirks mode. And that seems to mess up the determination of the function scope when the browser tries to parse onclick="setUser(id)" into valid JS code.
This would not happen if the doctype is correct and the page can hence be run in the correct mode.
This would also no happen if the browsers HTML engine did not have to parse the HTML string setUser(id) into valid JS code before it can be used. Hence it's not a common issue anymore since the standard these days is to not use inline event handler attributes on HTML tags.
So prefer explicit event binding with javascript when possible to not run into issues like this, where a totally unrelated part, the doctype, messes up your code.
Using onclick="setUser(this.id)" should work.
However, a cleaner workaround would be to do all the onclick handling in JavaScript:
onload = function() {
var buttons = document.getElementsByTagName("button");
for(var i = 0; i < buttons.length; i++) {
buttons[i].onclick = function() {
console.log(this.id);
}
}
}
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<button id="vish" style="height:40px;width:200px">Click Me</button>
<button id="vish2" style="height:40px;width:200px">Click Me 2</button>
</body>
</html>

document.querySelector("foreignObject") is null in Chrome

Working with embedded SVG in HTML5 I've found strange behavior in Chrome browser. (http://jsfiddle.net/complynx/htp4hqe2/)
For example, in the following html/svg code:
<svg>
<foreignObject>
<body xmlns="http://www.w3.org/1999/xhtml">
<div>foo</div>
</body>
</foreignObject>
</svg>
<script>
var T=document.querySelector("foreignObject");
</script>
Variable T will be null in Chrome (for Firefox works fine).
Any other selectors, even for contents of <foreignObject> work fine.
Is there any tag-specific selector in Chrome for this case?
Upd:
As Rob W mentioned in comments, there is a known bug in WebKit.
Simple, yet in some cases not good workaround.
<svg>
<foreignObject class="ForeignObjectStubClass">
<body xmlns="http://www.w3.org/1999/xhtml">
<div>foo</div>
</body>
</foreignObject>
</svg>
<script>
var T=document.querySelector(".ForeignObjectStubClass");
</script>
Using CSS class instead of tag name is enough
Edit, Updated
Try
var _T = document.getElementsByTagName("foreignObject");
// select `DIV` element within `_T` `HTMLCollection`
var filtered = _T[0].children.item("DIV");
console.log(filtered);
jsfiddle http://jsfiddle.net/guest271314/htp4hqe2/2/
See ParentNode.children , HTMLCollection ; see also NodeFilter

Image onload, another error in IE - fairly sure it's not a caching error

This code is the core of a much larger script that works great in almost all browsers. Yet it didn't work in IE. So I've stripped it down and found that the image.onload isn't firing in IE.
I've done some research, and I've guarded against it being an image caching problem. For one, the error occurs first time round before anything is cached, and, more importantly, the onload event is attached before the src.
I'm also reasonably sure I'm attaching the onload event in an IE compatible manner, so what gives, why don't I get an alert?
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript">
function generate(){
var imageGen = document.createElement("img");
imageGen.setAttribute('onload',"primer()");
imageGen.setAttribute('src', "http://www.google.co.uk/images/srpr/logo3w.png");
document.getElementById('image').appendChild(imageGen);
}
function primer() {
alert("here now");
}
</script>
</head>
<body onload="generate()">
<div id="image">
</div>
</body>
</html>
I'm hosting a version here
I only have access to IE8 unfortunately, so I don't know if it persists across other versions, even so it needs to be fixed.
First of all, events are not attributes and must not be set using setAttribute. It might, or might not work.
Second, try creating image object instead of image element:
var imageGen = new Image();
imageGen.src = "http://www.google.co.uk/images/srpr/logo3w.png";
imageGen.onload = primer;
document.getElementById('image').appendChild(imageGen);
Live test case - worked fine for me on IE9 and IE9 compatibility mode which should be like IE8.
Can you try imageGen.onload = primer instead of imageGen.setAttribute('onload',"primer()"); ?

JavaScript: trouble assigning event handlers

I'm not sure what I'm doing wrong here:
index.html
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "XHTML1-s.dtd" >
<html xmlns="http://www.w3.org/TR/1999/REC-html-in-xml" xml:lang="en" lang="en" >
<head>
<script type="text/javascript" src="scripts/eventInit.js"></script>
</head>
<body>
<p id="javascriptWarning">This page will not work with JavaScript disabled.</p>
</body>
</html>
eventInit.js
window.onload = function () {
alert("check"); // works
var jsWarning = document.getElementById("javascriptWarning");
jsWarning.onclick = function () {
alert("hi"); // works
};
jsWarning.onload = function () {
alert("loaded"); // fails
};
}
And yet, nothing happens. What am I doing wrong? I've tried other events, like onmouseover and onload.
I'm doing this in Visual Studio, and intellisense isn't giving me options for setting any event handlers. Is that because I'm doing this wrong?
I have confirmed that JS is working on my setup; just putting alert("hi") in a script and including it does work.
It might be important to note that I'm doing this in JScript, since I'm using Visual Studio 2010, so perhaps event handling is different?
Updated to remove '-' from the ID name, but it still doesn't work.
Updated added the window.onload block. Now onclick works, but onload doesn't.
You are trying to set a load event on a paragraph. Only objects which load external data (window, frame, iframe, img, script, etc) have a load event.
Some JS libraries implement an available event (such as YUI) — but you know the paragraph is available, since you're setting an event on it, and you couldn't do that if it was unavailable.
maybe you forgot to have the code block inside a
window.onload = function() {
// btn click code here
}
You have to wait for the document to be parsed before you can go looking for elements by "id" value. Put your event handling setup into an "onload" function on the window object.
The browser won't fire an "onload" event on your <p> tag. You won't need that anyway if you do your work in the "onload" handler for the window as a whole.
[soapbox] Use a framework.
The script is executed before the desired element exists. Additionally, I don't think, p has an onload-Event. Windows, frames and images, yes, but paragraphs?
You should use <body onload="init();"> or window.onload=function(){ … } or a library function, if you use a library. Example:
index.html
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "XHTML1-s.dtd" >
<html xmlns="http://www.w3.org/TR/1999/REC-html-in-xml" xml:lang="en" lang="en" >
<head>
<script type="text/javascript" src="scripts/eventInit.js"></script>
</head>
<body>
<p id="javascriptWarning">This page will not work with JavaScript disabled.</p>
</body>
</html>
scripts/eventInit.js
window.onload=function(){
alert('JS is working!');}
Edit: Okay, I am very sure, p makes no use of an onload event handler. And it's no wonder, you don't need it. If you want to execute JS code just after the paragraph is finished, do this:
<p>
<!-- stuff -->
</p>
<script type="text/javascript">
/* stuff */
</script>
Instead of this:
jsWarning.onload = function () {
alert("loaded"); // fails
};
try this
if(jsWarning) alert("loaded");
I think someone above mentioned checking for the existence of the element. At this stage the element should be present but it does no harms to check for it.
I think you have to make sure your JavaScript is binding.
Is your javascript before or after your paragraph element, for some reason my brain is aiming towards that.
I would look into using something like jQuery, it will help.
using jQuery your code would be (with the relevant jQuery files included of course):
$(document).ready(function()
{
$("#javascript-warning").click(function(){
alert("HELLO");
});
});
I don't think hyphens are valid in class names when used in conjunction with JavaScript. Try an underscore instead.
onload is a window event.

Categories