.InnerHTML Not working properly in Internet Explorer - javascript

I wanted to assign a link tag to innerHTML of a HTML control. But this is not working properly in Internet Explorer. However when I try to assign anything other than <link> & <style> tags it works fine.
<html>
<head>
<script type="text/javascript">
function getValue()
{
var x=document.getElementById("myHeader");
x.innerHTML='<link \"http://test.com/css/template.css\" rel=\"stylesheet\"><div>abc</div>';
alert(x.innerHTML);
}
</script>
</head>
<body>
<h1 id="myHeader" onclick="getValue()">Click me!</h1>
</body>
</html>
Also, If I change sequence of <div> tag and <link> tag above it works fine in Internet Explorer also.
x.innerHTML='<div>abc</div><link \"http://test.com/css/template.css\" rel=\"stylesheet\">';
Please suggest! Thanks.
EDIT: This is a bug in Internet Explorer with ExtJs. More information at
http://www.sencha.com/forum/showthread.php?30110-internet-explorer-autoLoad-css-not-applied

innerHTML won't work in IE, but using DOM methods it will:
function getValue()
{
var x=document.getElementById("myHeader")
, link = document.createElement('link')
, div = document.createElement('div');
x.innerHTML = '';
x.appendChild(link);
x.appendChild(div);
div.innerHTML = 'abc';
link.href = 'http://test.com/css/template.css';
link.rel = 'stylesheet';
alert(x.innerHTML);
}
Although the reference states a link tag may only appear in the header, interesting enough the style link does work if you use the code I provided, in all browsers I tried (IE, firefox, chrome). See this jsfiddle (where I used a real css-href from test.com ;-)
If you however want to place the link in it's rightful section (<head>), use:
var header = document.getElementsByTagName('head')[0];
, link = document.createElement('link');
header.appendChild(link);
link.href = 'http://test.com/css/template.css';
link.rel = 'stylesheet';

For starters, you are missing an href attribute on your <link>.
<link href=\"http://test.com/css/template.css\" rel=\"stylesheet\" />
And don't put link and style tags into the <body>. Inject them into the <head>
var link = document.createElement("link");
link.href = "http://test.com/css/template.css";
link.rel = "StyleSheet";
document.head.appendChild(link);

A lot of people are missing the point here. What he is trying to do ( after fixing the typo where the href attribute is missing ) works in any other browser.
IE 8 and below have a bug where if the first element in the text when setting innerHTML is a tag (maybe others), it is ignored. If you just put a space or newline or other tag first, it works.
He even discovered this when he said putting the <div> first fixes it.
It isn't valid, but that's how you fix it.
Edit: in other words: foo.innerHTML = "\n" + yourHtmlWithLinkInIt;

<link> can only be contained in <head>.
This element defines a link. Unlike A,
it may only appear in the HEAD section
of a document, although it may appear
any number of times.
reference: http://www.w3.org/TR/html401/struct/links.html#edef-LINK

i think the problem is that the <link> hast to be an empty element. change your code to this:
x.innerHTML='<link \"http://test.com/css/template.css\" rel=\"stylesheet\" /><div>abc</div>';
// this is the trick ^^^
EDIT: i havn't tested this, but it's the first thing that hurts my eyes.
EDIT2: <link> tags should only occur inside of the <head>-section... i hope you know what you're trying to do.

to the set text properly, i would recommend you to go what i generally do. if you have ie 8 then open the html in ie. press f12 to show the developer tool. now in the new window go to script tag. set break point from where your javascript starts. now press on the button start debugging. execute the js function from your by some event or the way it executes. now on the object in the javascripg function, when the break point hits, right click and add watch. expand the object and see, where your earlier text was and where is your new text.

What exactly are you trying to achieve, as your end goal? As said previously a link tag should really only appear in the <head> of an html document.
JavaScript can be a tricky thing in its vanilla flavour, you're better off using a framework, my personal favourite is MooTools though I hear JQuery is pretty good, but MooTools has OOP (for real programmers - tehe).
This'll allow you to do a lot more, and probably get to your end goal, if you let me / us know then you should get a more direct answer to your issue.

The thing is it works in FireFox and Google Chrome, but not in IE.
This is, because you cannot set the innerHTML tag of InternetExplorer with a string, if the string is more than text, ie a HTML element.
I experienced this trying to dynamically populate a ComboBox into a table cell with AJAX...
The solution is to use JQuery.
Then you can do:
$("#YourElementID").html('<link \"http://test.com/css/template.css\" rel=\"stylesheet\" /> <div>abc</div>');
and JQuery will do the DOM stuff, that selbie and KooiInc describe, for you.

Found different and easy solution here for "link" and "sytle", but "script" needs to be added using appendChild. Very much similar to what Vectorjohn has said, also provides more references.
http://allofetechnical.wordpress.com/2010/05/21/ies-innerhtml-method-with-script-and-style-tags/

try
document.getElementById('tblList').outerHTML="ypur html";

Related

How or can I use JavaScript to append a div tag after the html or body tags?

For a very specific reason I would like to know if you can add a tag either after the body or html tags.
<!DOCTYPE html>
<html>
<body>
</body>
<!-- Can I add a tag here? -->
</html>
<!-- Can I add a tag here? -->
I have noticed this is what the Skype plugin for Chrome does, and would like to know how they did it. I have attached a screenshot of proof.
You can append some element after the body element as such:
var e = document.createElement('a');
document.body.parentNode.appendChild(e);
Attempting to insert an element which is a sibling of the html element results in the following error:
There are several ways to do it, KPthunder's sample springing to mind. You can also just rewrite the content of the entire document and reload it. Ugly, and brutal, but it works.
Note, however, that browsers are not required to honor the element. As mentioned, it's noncompliant, and therefore not guaranteed to work across all browsers. It'll likely work in IE. But that's IE. And IE supports everything. </eyeroll>
I've actually encountered elements that appeared both before and after the HTML element itself, and it wasn't intentional (cough). Likely, this is the case here. My advice to you is, don't try to repeat it.
Sorry for jQuery but, for example
$( "<p>Test</p>" ).insertAfter( "body" );

How can you see which Javascript script generated a certain html line?

I have some crazy app done almost 100% by manipulating the DOM and I find myself in the unfortunate position of changing something in it. As there are probably around 100 different scripts that do God knows what, I have no clue in which file should I look to make my changes. So, I want to ask, is there a way (using Firebug maybe or something similar) to know where a specific piece of html was generated? I'm a C developer, so I'm not very good at this, it drives me crazy.
Are all the elements added at the page load, or partially in the response to the user input? (clicking etc.)
for stuff added with the response to your actions, you can use Firebug's "Break On Next" button in the "Script" tab. To active BON you have to click it, or, in just-shipped Firebug 1.10.0a8, use keyboard shortcut ALT-CTRL-B (useful when you have event listeners bound to mouse movements). Then, when any piece of JS is going to be executed in reaction to your click etc., you will hit a breakpoint.
for stuff added at page load time, you may use the trick of extending the native functions (this might sound crazy - yeah it is, don't do it in production!) like appendChild, insertBefore, replaceChild. Just insert the appropriate code at the very top of your main HTML file, so all the code below will "see" the change.
Unfortunately, this does not work in Firefox due to a bug. But works in Opera and I guess in Chrome as well.
When you extend the native function, you can inject any code before really adding the node to the page. For instance, call console.log or create a breakpoint, to inspect the current page state. You can try playing with breakpoints to see the available variables properties inside those function to adjust what you push to console.log.
For this code:
<!doctype html>
<html>
<head>
<script type="text/javascript">
// this should work in Firefox but it does not -- https://bugzilla.mozilla.org/show_bug.cgi?id=618379
// works at least in Opera, probably Chrome too
Node.prototype._appendChild = Node.prototype.appendChild;
Node.prototype.appendChild = function(child) {
console.log("appending " + child + " to " + this);
return this._appendChild(child); // call the original function with the original parameters
}
// this works in Firefox
document._createElement = document.createElement;
document.createElement = function(tagName){
console.log("creating " + tagName);
return this._createElement(tagName);
}
</script>
</head>
<body>
<script type="text/javascript">
var p = document.createElement("p");
p.appendChild( document.createTextNode("abc"));
document.body.appendChild(p);
</script>
</body>
</html>
Opera outputs:
creating p appendChild.html:14
appending [object Text] to [object HTMLParagraphElement] appendChild.html:7
appending [object HTMLParagraphElement] to [object HTMLBodyElement] appendChild.html:7
To overcome the weakness of Firefox (that you can't override appendChild), you may use the trick: place the code below instead in the top of your HTML
<script>
Node.prototype._appendChild = function(child) {
console.log("appending " + child + " to " + this);
return this.appendChild(child)
};
</script>
and then, use Fiddler proxy by creating auto-responders (WMV tutorial, 9.9 MB) where you manually replace all calls to .appendChild with ._appendChild (you can use Notepad++ for "find replace in all opened files"). Creating auto-responders and hand-tampering requests can be mundane, but it's extremely powerful. To quickly create auto-responder rule, load the page when Fiddler is active, then drag'n'drop files as in the picture below. For each file, right click and choose "Generate File" from menu (this will put a file on the desktop) or create a file by yourself in different location. (it's good to open Fiddler-generated files and remove response headers from them; BTW "Generate file" puts real contents only if the response header was 200, so make sure to load the page with CTRL-F5 to skip the cache).
In Chrome you can inspect an element and right click on it. This menu gives you some options to break when something below the element is changed or when it's own attributes change. Maybe one of those breakpoints will find what you are looking for?
Assuming you've got access to the raw (hopefully un-minified/obfuscated) JS files, maybe just search them for text strings related to DOM manipulation and/or attributes of the node you're trying to find the creation of? I'd try things like "appendChild" "createElement" and the node's ID/class names.
You could also set break points all over the script files, and step through them as the page loads to help you narrow down where to look. Might help to start by just "pausing" the JS execution and stepping through from the very beginning.
If you can share the code (a link to the live site would do fine) I'd be happy to take a look.
If you are using the jQuery framework in your javascript to make the DOM changes then you may find the fireQuery plugin for FireBug in the firefox browser may get you the information you need.
Example:
It adds additional information to the standard HTML view by superimposing additional jquery element information to the display to provide a deeper insight into how your javascript is amending the page content.
I hope that helps you out.

Inserting <style> tags from a string in Internet Explorer

I'm loading a string via AJAX that reads like
<style>[some definitions]</style>
<h1>Lots of Markup</h1>
<p>follows here</p>
Using Webkit/Gecko everything works as expected — the markup is inserted, styles are applied. In IE (8) though the style-definitions are ignored. Actually, if you use the developer tools they are gone.
You can see in this JS-Fiddle that it doesn't work: http://jsfiddle.net/J4Yzr/
Also, I've seen that trick that you create a temporary DOM-Object, set it's innerHTML to your markup and extract your markup as DOM-Objects from your temporary element. That doesn't work with style tags (if I did it right, I'm using prototypeJS):
var text = '<style>h1{color:red;}</style> style added',
el = new Element('div').update(text);
console.log(el.firstChild);
//is a HTMLStyleElement in Webkit but a [object Text] in IE
Does anyone have a suggestion how to properly apply the <style> in IE if you get it from such a string?
I had the same problem, so I tried your solution, but guess what? When I stripped the out after rendering markup retrieved via Ajax, the tags disappeared from the DOM! Back to square one.
So my solution is to prepend this instead:
<hr style='display:none'/>
Which did the trick nicely. Thank you so much for solving this issue.
Ok, it's crazy. Add a <br/>-Tag in front of your string and it works in Internet Explorer.
<br/><style>[some definitions]</style><h1>Lots of Markup</h1>
You don't even need to create that temporary DOM-Object to insert code into. Just append it in your site.
What I'm doing now it insert the code with a <br/>-Tag and remove the <br/> afterwards. It's messy but it works.

Changing content using innerHTML with a non-standard element in Internet Explorer

I have the non-standard element
<testele></testele>
In every browser except IE, this bit of JavaScript will successfully change the content of the above element
document.getElementsByTagName("testele")[0].innerHTML = 'hi';
However, if I change the <testele> to just a <span> (in the HTML and the JavaScript), it now successfully changes the content of the element in every browser, including IE.
Is there any fix? I have searched around and tried a bunch to no avail.
Use document.createElement("testele") before it is rendered. This script must be included before the document encouters a <testele>:
http://jsfiddle.net/gilly3/LjwbA/
document.createElement("testele");
window.onload = function() {
document.getElementsByTagName("testele")[0].innerHTML = 'hi';
};
If you try to do document.createElement("testele") after a <testele> has been parsed by the browser, it's too late.
Take a look at innerShiv, a Javascript plugin which aims to solve this.

How can I select an <img> element programmatically using JavaScript?

I have an <img> in an HTML document that I would like to highlight as though the user had highlighted it using the mouse. Is there a way to do that using JavaScript?
I only need it to work in Mozilla, but any and all information is welcome.
EDIT: The reason I want to select the image is actually not so that it appears highlighted, but so that I can then copy the selected image to the clipboard using XPCOM. So the img actually has to be selected for this to work.
Here's an example which selects the first image on the page (which will be the Stack Overflow logo if you test it out on this page in Firebug):
var s = window.getSelection()
var r = document.createRange();
r.selectNode(document.images[0]);
s.addRange(r)
Relevant documentation:
http://developer.mozilla.org/en/DOM/window.getSelection
http://developer.mozilla.org/en/DOM/range.selectNode
http://developer.mozilla.org/en/DOM/Selection/addRange
You might also want to call s.removeAllRanges() before s.addRange(r).
What, exactly, are you trying to do? If you're using XPCOM, you're presumably writing an application or an extension for one; can't you just get the image data and put it on the clipboard directly?
My personal choice for selecting elements is jquery:
Then to get the element of your choice is:
$("img#YOURIMAGEHERE").focus();
You can swap the source of the image, as in img.src = "otherimage.png";
I actually did this at one point, and there are things you can do to pre-load the images.
I even set up special attributes on the image elements such as swap-image="otherimage.png", then searched for any elements that had it, and set up handlers to automatically swap the images... you can do some fun stuff.
Sorry I misunderstood the question! but anyways, for those of you interested in doing what I am talking about, here is an example of what I mean (crude implementation, I would suggest using frameworks like jQuery to improve it, but just something to get you going):
<html>
<body>
<script language="javascript">
function swap(name) {
document.getElementById("image").src = name;
}
</script>
<img id="image" src="test1.png"
onmouseover="javascript:swap('test0.png');"
onmouseout="javascript:swap('test1.png');">
</body>
</html>
The basic idea of the "highLight" solution is ok, but you probably want to set a "static" border style (defined in css) for the img with the same dimensions as the one specified in the highLight method, so it doesn't cause a resize.
In addition, I believe that if you change the call to "highLight(this)", and the function def to "highLight(obj)", then you can skip the "document.getElementById()" call (and the specification of the "id" attribute for "img"), as long as you do "obj.style.border" instead.
You probably also need to spell "highLight" correctly.
Give the img tag an ID. Use document.getElementById('id').
<script type="text/javascript" language="javascript">
function highLight()
{
var img = document.getElementById('myImage');
img.style.border = "inset 2px black";
}
</script>
<img src="whatever.gif" id="myImage" onclick="hightLight()" />
EDIT::
You might try .focus to give it focus.

Categories