How to get element in user-agent shadow root with JavaScript? - javascript

I need get elements from Shadow DOM and change it. How i can do it?
<div>
<input type="range" min="100 $" max="3000 $">
</div>

You cannot access a Shadow DOM created by the browser to display a control, that is called a #shadow-root (user-agent) in the Dev Tools. <input> is one example.
You can only access open custom Shadow DOM (the ones that you create yourself), with the { mode: 'open' } option.
element.attachShadow( { mode: 'open' } )
Update
It's true for most UX standard HTML elements: <input>, <video>, <textarea>, <select>, <audio>, etc.
3rd party edit 2022
The following might help to illustrate the question. Give there is only 1 <input type=range> in the html document this code shows if its children can be accessed.
// returns 1 as expected since only one input element is in the document
document.querySelectorAll("input").length;
// get a reference to <input type=range>
var rangeInput = document.querySelector("input");
// Is it a shadowRoot?
// if null then either
// - it is not a shadowRoot OR
// - its elements can not be accessed (mode == closed)
console.log(rangeInput.shadowRoot); // returns null
The code above shows that the internals of an <input type=range> can not be accessed.

To answer a generalized version of the OP's question:
Query shadow elements FROM ANYWHERE on the page?
It feels like the shadow root API is still lacking (or I just don't know it well enough). It seems to make querySelectorAll useless, in that querySelectorAll will not actually get all matching elements anymore, since it ignores all descendants in shadowRoots. Maybe there is an API that fixes that, but since I have not found any, I wrote my own:
This function recursively iterates all shadowRoots and gets you all matching elements on the page, not just those of a single shadowRoot.
/**
* Finds all elements in the entire page matching `selector`, even if they are in shadowRoots.
* Just like `querySelectorAll`, but automatically expand on all child `shadowRoot` elements.
* #see https://stackoverflow.com/a/71692555/2228771
*/
function querySelectorAllShadows(selector, el = document.body) {
// recurse on childShadows
const childShadows = Array.from(el.querySelectorAll('*')).
map(el => el.shadowRoot).filter(Boolean);
// console.log('[querySelectorAllShadows]', selector, el, `(${childShadows.length} shadowRoots)`);
const childResults = childShadows.map(child => querySelectorAllShadows(selector, child));
// fuse all results into singular, flat array
const result = Array.from(el.querySelectorAll(selector));
return result.concat(childResults).flat();
}
// examples:
querySelectorAllShadows('td'); // all `td`s in body
querySelectorAllShadows('.btn') // all `.btn`s in body
querySelectorAllShadows('a', document.querySelector('#right-nav')); // all `a`s in right menu

Here is an example:
var container = document.querySelector('#example');
//Create shadow root !
var root = container.createShadowRoot();
root.innerHTML = '<div>Root<div class="test">Element in shadow</div></div>';
//Access the element inside the shadow !
//"container.shadowRoot" represents the youngest shadow root that is hosted on the element !
console.log(container.shadowRoot.querySelector(".test").innerHTML);
Demo:
var container = document.querySelector('#example');
//Create shadow root !
var root = container.createShadowRoot();
root.innerHTML = '<div>Root<div class="test">Element in shadow</div></div>';
//Access the element inside the shadow !
console.log(container.shadowRoot.querySelector(".test").innerHTML);
<div id="example">Element</div>
I hope this will help you.

Related

I can't seem to clear a tables tbody properly, not delete, just clear the rows and whatever cells are in it [duplicate]

How would I go about removing all of the child elements of a DOM node in JavaScript?
Say I have the following (ugly) HTML:
<p id="foo">
<span>hello</span>
<div>world</div>
</p>
And I grab the node I want like so:
var myNode = document.getElementById("foo");
How could I remove the children of foo so that just <p id="foo"></p> is left?
Could I just do:
myNode.childNodes = new Array();
or should I be using some combination of removeElement?
I'd like the answer to be straight up DOM; though extra points if you also provide an answer in jQuery along with the DOM-only answer.
Option 1 A: Clearing innerHTML.
This approach is simple, but might not be suitable for high-performance applications because it invokes the browser's HTML parser (though browsers may optimize for the case where the value is an empty string).
doFoo.onclick = () => {
const myNode = document.getElementById("foo");
myNode.innerHTML = '';
}
<div id='foo' style="height: 100px; width: 100px; border: 1px solid black;">
<span>Hello</span>
</div>
<button id='doFoo'>Remove via innerHTML</button>
Option 1 B: Clearing textContent
As above, but use .textContent. According to MDN this will be faster than innerHTML as browsers won't invoke their HTML parsers and will instead immediately replace all children of the element with a single #text node.
doFoo.onclick = () => {
const myNode = document.getElementById("foo");
myNode.textContent = '';
}
<div id='foo' style="height: 100px; width: 100px; border: 1px solid black;">
<span>Hello</span>
</div>
<button id='doFoo'>Remove via textContent</button>
Option 2 A: Looping to remove every lastChild:
An earlier edit to this answer used firstChild, but this is updated to use lastChild as in computer-science, in general, it's significantly faster to remove the last element of a collection than it is to remove the first element (depending on how the collection is implemented).
The loop continues to check for firstChild just in case it's faster to check for firstChild than lastChild (e.g. if the element list is implemented as a directed linked-list by the UA).
doFoo.onclick = () => {
const myNode = document.getElementById("foo");
while (myNode.firstChild) {
myNode.removeChild(myNode.lastChild);
}
}
<div id='foo' style="height: 100px; width: 100px; border: 1px solid black;">
<span>Hello</span>
</div>
<button id='doFoo'>Remove via lastChild-loop</button>
Option 2 B: Looping to remove every lastElementChild:
This approach preserves all non-Element (namely #text nodes and <!-- comments --> ) children of the parent (but not their descendants) - and this may be desirable in your application (e.g. some templating systems that use inline HTML comments to store template instructions).
This approach wasn't used until recent years as Internet Explorer only added support for lastElementChild in IE9.
doFoo.onclick = () => {
const myNode = document.getElementById("foo");
while (myNode.lastElementChild) {
myNode.removeChild(myNode.lastElementChild);
}
}
<div id='foo' style="height: 100px; width: 100px; border: 1px solid black;">
<!-- This comment won't be removed -->
<span>Hello <!-- This comment WILL be removed --></span>
<!-- But this one won't. -->
</div>
<button id='doFoo'>Remove via lastElementChild-loop</button>
Bonus: Element.clearChildren monkey-patch:
We can add a new method-property to the Element prototype in JavaScript to simplify invoking it to just el.clearChildren() (where el is any HTML element object).
(Strictly speaking this is a monkey-patch, not a polyfill, as this is not a standard DOM feature or missing feature. Note that monkey-patching is rightfully discouraged in many situations.)
if( typeof Element.prototype.clearChildren === 'undefined' ) {
Object.defineProperty(Element.prototype, 'clearChildren', {
configurable: true,
enumerable: false,
value: function() {
while(this.firstChild) this.removeChild(this.lastChild);
}
});
}
<div id='foo' style="height: 100px; width: 100px; border: 1px solid black;">
<span>Hello <!-- This comment WILL be removed --></span>
</div>
<button onclick="this.previousElementSibling.clearChildren()">Remove via monkey-patch</button>
In 2022+, use the replaceChildren() API!
Replacing all children can now be done with the (cross-browser supported) replaceChildren API:
container.replaceChildren(...arrayOfNewChildren);
This will do both:
remove all existing children, and
append all of the given new children, in one operation.
You can also use this same API to just remove existing children, without replacing them:
container.replaceChildren();
This is fully supported in Chrome/Edge 86+, Firefox 78+, and Safari 14+. It is fully specified behavior. This is likely to be faster than any other proposed method here, since the removal of old children and addition of new children is done without requiring innerHTML, and in one step instead of multiple.
Use modern Javascript, with remove!
const parent = document.getElementById("foo")
while (parent.firstChild) {
parent.firstChild.remove()
}
This is a newer way to write node removal in ES5. It is vanilla JS and reads much nicer than relying on parent.
All modern browsers are supported.
Browser Support - 97% Jun '21
The currently accepted answer is wrong about innerHTML being slower (at least in IE and Chrome), as m93a correctly mentioned.
Chrome and FF are dramatically faster using this method (which will destroy attached jquery data):
var cNode = node.cloneNode(false);
node.parentNode.replaceChild(cNode, node);
in a distant second for FF and Chrome, and fastest in IE:
node.innerHTML = '';
InnerHTML won't destroy your event handlers or break jquery references, it's also recommended as a solution here:
https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML.
The fastest DOM manipulation method (still slower than the previous two) is the Range removal, but ranges aren't supported until IE9.
var range = document.createRange();
range.selectNodeContents(node);
range.deleteContents();
The other methods mentioned seem to be comparable, but a lot slower than innerHTML, except for the outlier, jquery (1.1.1 and 3.1.1), which is considerably slower than anything else:
$(node).empty();
Evidence here:
http://jsperf.com/innerhtml-vs-removechild/167 http://jsperf.com/innerhtml-vs-removechild/300
https://jsperf.com/remove-all-child-elements-of-a-dom-node-in-javascript
(New url for jsperf reboot because editing the old url isn't working)
Jsperf's "per-test-loop" often gets understood as "per-iteration", and only the first iteration has nodes to remove so the results are meaningless, at time of posting there were tests in this thread set up incorrectly.
If you use jQuery:
$('#foo').empty();
If you don't:
var foo = document.getElementById('foo');
while (foo.firstChild) foo.removeChild(foo.firstChild);
var myNode = document.getElementById("foo");
var fc = myNode.firstChild;
while( fc ) {
myNode.removeChild( fc );
fc = myNode.firstChild;
}
If there's any chance that you have jQuery affected descendants, then you must use some method that will clean up jQuery data.
$('#foo').empty();
The jQuery .empty() method will ensure that any data that jQuery associated with elements being removed will be cleaned up.
If you simply use DOM methods of removing the children, that data will remain.
The fastest...
var removeChilds = function (node) {
var last;
while (last = node.lastChild) node.removeChild(last);
};
Thanks to Andrey Lushnikov for his link to jsperf.com (cool site!).
EDIT: to be clear, there is no performance difference in Chrome between firstChild and lastChild. The top answer shows a good solution for performance.
Use elm.replaceChildren().
It’s experimental without wide support, but when executed with no params will do what you’re asking for, and it’s more efficient than looping through each child and removing it. As mentioned already, replacing innerHTML with an empty string will require HTML parsing on the browser’s part.
MDN Documentation
Update It's widely supported now
If you only want to have the node without its children you could also make a copy of it like this:
var dupNode = document.getElementById("foo").cloneNode(false);
Depends on what you're trying to achieve.
Ecma6 makes it easy and compact
myNode.querySelectorAll('*').forEach( n => n.remove() );
This answers the question, and removes “all child nodes”.
If there are text nodes belonging to myNode they can’t be selected with CSS selectors, in this case we’ve to apply (also):
myNode.textContent = '';
Actually the last one could be the fastest and more effective/efficient solution.
.textContent is more efficient than .innerText and .innerHTML, see: MDN
Here's another approach:
function removeAllChildren(theParent){
// Create the Range object
var rangeObj = new Range();
// Select all of theParent's children
rangeObj.selectNodeContents(theParent);
// Delete everything that is selected
rangeObj.deleteContents();
}
element.textContent = '';
It's like innerText, except standard. It's a bit slower than removeChild(), but it's easier to use and won't make much of a performance difference if you don't have too much stuff to delete.
Here is what I usually do :
HTMLElement.prototype.empty = function() {
while (this.firstChild) {
this.removeChild(this.firstChild);
}
}
And voila, later on you can empty any dom element with :
anyDom.empty()
In response to DanMan, Maarten and Matt. Cloning a node, to set the text is indeed a viable way in my results.
// #param {node} node
// #return {node} empty node
function removeAllChildrenFromNode (node) {
var shell;
// do not copy the contents
shell = node.cloneNode(false);
if (node.parentNode) {
node.parentNode.replaceChild(shell, node);
}
return shell;
}
// use as such
var myNode = document.getElementById('foo');
myNode = removeAllChildrenFromNode( myNode );
Also this works for nodes not in the dom which return null when trying to access the parentNode. In addition, if you need to be safe a node is empty before adding content this is really helpful. Consider the use case underneath.
// #param {node} node
// #param {string|html} content
// #return {node} node with content only
function refreshContent (node, content) {
var shell;
// do not copy the contents
shell = node.cloneNode(false);
// use innerHTML or you preffered method
// depending on what you need
shell.innerHTML( content );
if (node.parentNode) {
node.parentNode.replaceChild(shell, node);
}
return shell;
}
// use as such
var myNode = document.getElementById('foo');
myNode = refreshContent( myNode );
I find this method very useful when replacing a string inside an element, if you are not sure what the node will contain, instead of worrying how to clean up the mess, start out fresh.
Using a range loop feels the most natural to me:
for (var child of node.childNodes) {
child.remove();
}
According to my measurements in Chrome and Firefox, it is about 1.3x slower. In normal circumstances, this will perhaps not matter.
There are couple of options to achieve that:
The fastest ():
while (node.lastChild) {
node.removeChild(node.lastChild);
}
Alternatives (slower):
while (node.firstChild) {
node.removeChild(node.firstChild);
}
while (node.hasChildNodes()) {
node.removeChild(node.lastChild);
}
Benchmark with the suggested options
var empty_element = function (element) {
var node = element;
while (element.hasChildNodes()) { // selected elem has children
if (node.hasChildNodes()) { // current node has children
node = node.lastChild; // set current node to child
}
else { // last child found
console.log(node.nodeName);
node = node.parentNode; // set node to parent
node.removeChild(node.lastChild); // remove last node
}
}
}
This will remove all nodes within the element.
A one-liner to iteratively remove all the children of a node from the DOM
Array.from(node.children).forEach(c => c.remove())
Or
[...node.children].forEach(c => c.remove())
innerText is the winner! http://jsperf.com/innerhtml-vs-removechild/133. At all previous tests inner dom of parent node were deleted at first iteration and then innerHTML or removeChild where applied to empty div.
Simplest way of removing the child nodes of a node via Javascript
var myNode = document.getElementById("foo");
while(myNode.hasChildNodes())
{
myNode.removeChild(myNode.lastChild);
}
let el = document.querySelector('#el');
if (el.hasChildNodes()) {
el.childNodes.forEach(child => el.removeChild(child));
}
i saw people doing:
while (el.firstNode) {
el.removeChild(el.firstNode);
}
then someone said using el.lastNode is faster
however I would think that this is the fastest:
var children = el.childNodes;
for (var i=children.length - 1; i>-1; i--) {
el.removeNode(children[i]);
}
what do you think?
ps:
this topic was a life saver for me. my firefox addon got rejected cuz i used innerHTML. Its been a habit for a long time. then i foudn this. and i actually noticed a speed difference. on load the innerhtml took awhile to update, however going by addElement its instant!
Why aren't we following the simplest method here "remove" looped inside while.
const foo = document.querySelector(".foo");
while (foo.firstChild) {
foo.firstChild.remove();
}
Selecting the parent div
Using "remove" Method inside a While loop for eliminating First child element , until there is none left.
Generally, JavaScript uses arrays to reference lists of DOM nodes. So, this will work nicely if you have an interest in doing it through the HTMLElements array. Also, worth noting, because I am using an array reference instead of JavaScript proto's this should work in any browser, including IE.
while(nodeArray.length !== 0) {
nodeArray[0].parentNode.removeChild(nodeArray[0]);
}
Just saw someone mention this question in another and thought I would add a method I didn't see yet:
function clear(el) {
el.parentNode.replaceChild(el.cloneNode(false), el);
}
var myNode = document.getElementById("foo");
clear(myNode);
The clear function is taking the element and using the parent node to replace itself with a copy without it's children. Not much performance gain if the element is sparse but when the element has a bunch of nodes the performance gains are realized.
Functional only approach:
const domChildren = (el) => Array.from(el.childNodes)
const domRemove = (el) => el.parentNode.removeChild(el)
const domEmpty = (el) => domChildren(el).map(domRemove)
"childNodes" in domChildren will give a nodeList of the immediate children elements, which is empty when none are found. In order to map over the nodeList, domChildren converts it to array. domEmpty maps a function domRemove over all elements which removes it.
Example usage:
domEmpty(document.body)
removes all children from the body element.
You can remove all child elements from a container like below:
function emptyDom(selector){
const elem = document.querySelector(selector);
if(elem) elem.innerHTML = "";
}
Now you can call the function and pass the selector like below:
If element has id = foo
emptyDom('#foo');
If element has class = foo
emptyDom('.foo');
if element has tag = <div>
emptyDom('div')
element.innerHTML = "" (or .textContent) is by far the fastest solution
Most of the answers here are based on flawed tests
For example:
https://jsperf.com/innerhtml-vs-removechild/15
This test does not add new children to the element between each iteration. The first iteration will remove the element's contents, and every other iteration will then do nothing.
In this case, while (box.lastChild) box.removeChild(box.lastChild) was faster because box.lastChild was null 99% of the time
Here is a proper test: https://jsperf.com/innerhtml-conspiracy
Finally, do not use node.parentNode.replaceChild(node.cloneNode(false), node). This will replace the node with a copy of itself without its children. However, this does not preserve event listeners and breaks any other references to the node.
Best Removal Method for ES6+ Browser (major browsers released after year 2016):
Perhaps there are lots of way to do it, such as Element.replaceChildren().
I would like to show you an effective solution with only one redraw & reflow supporting all ES6+ browsers.
function removeChildren(cssSelector, parentNode){
var elements = parentNode.querySelectorAll(cssSelector);
let fragment = document.createDocumentFragment();
fragment.textContent=' ';
fragment.firstChild.replaceWith(...elements);
}
Usage: removeChildren('.foo',document.body);: remove all elements with className foo in <body>
If you want to empty entire parent DOM then it's very simple...
Just use .empty()
function removeAll() {
$('#parent').empty();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button onclick="removeAll()">Remove all the element of parent</button>
<div id="parent">
<h3>Title</h3>
<p>Child 1</p>
<p>Child 2</p>
<p>Child 3</p>
</div>

Javascript get all first children elements [duplicate]

I'm writing a Chrome content script extension and I need to be able to target a specific element that, unfortunately, has no unique identifiers except its parent element.
I need to target the immediate first child element of parentElement. console.log(parentElement) reports both of the child elements/nodes perfectly, but the succeeding console logs (the ones that target the childNodes) always return an undefined value no matter what I do.
This is my code so far
(I have excluded the actual names to avoid confusion and extra, unnecessary explanation)
function injectCode() {
var parentElement = document.getElementsByClassName("uniqueClassName");
if (parentElement && parentElement.innerHTML != "") {
console.log(parentElement);
console.log(parentElement.firstElementChild);
console.log(parentElement.firstChild);
console.log(parentElement.childNodes);
console.log(parentElement.childNodes[0]);
console.log(parentElement.childNodes[1]);
} else {
setTimeout(injectCode, 250);
}
}
How do I select the first child element/node of parentElement?
Update:
parentElement.children[0] also has the same error as parentElement.childNodes[0].
Both these will give you the first child node:
console.log(parentElement.firstChild); // or
console.log(parentElement.childNodes[0]);
If you need the first child that is an element node then use:
console.log(parentElement.children[0]);
Edit
Ah, I see your problem now; parentElement is an array.
If you know that getElementsByClassName will only return one result, which it seems you do, you should use [0] to dearray (yes, I made that word up) the element:
var parentElement = document.getElementsByClassName("uniqueClassName")[0];

How do I copy an HTML document and edit the copy based upon the selection, without altering the original document?

I have an HTML document, and I would like to remove some of the tags from it dynamically using Javascript, based on whether the tags are within the current selection or not. However, I do not want to update the actual document on the page, I want to make a copy of the whole page's HTML and edit that copy. The problem is that the Range object I get from selection.getRangeAt(0) still points to the original document, as far as I can see.
I've managed to get editing the original document in place with this code:
var node = window.getSelection().getRangeAt(0).commonAncestorContainer;
var allWithinRangeOfParent = node.getElementsByTagName("*");
for (var i=0, el; el = allWithinRangeParent[i]; i++) {
// The second parameter says to include the element
// even if it's not fully selected
if (selection.containsNode(el, true) ) {
el.remove();
}
}
But what I want to do is to somehow perform the same operation with removing elements, but remove them from a copy of the original HTML. I've made the copy like this: var fullDocument = $('html').clone(); How could I accomplish this?
Either dynamically add a class or data attribute to all your elements on load before you clone so that you have a point of reference then grab the class or data attribute on the common ancestor and remove it from the clone. I can give an example if you like? Along these lines - http://jsfiddle.net/9s9hpc2v/ isn't properly working exactly right but you get the gist.
$('*').each(function(i){
$(this).attr('data-uniqueId', i);
});
var theclone = $('#foo').clone();
function laa(){
var node = window.getSelection().getRangeAt(0).commonAncestorContainer;
if(node.getElementsByTagName){
var allWithinRangeOfParent = $(node).find('*');
console.log(allWithinRangeOfParent, $(allWithinRangeOfParent).attr('data-uniqueId'));
$.each(allWithinRangeOfParent, function(){
theclone.find('[data-uniqueId="'+$(this).attr('data-uniqueId')+'"]').remove();
});
console.log(theclone.html());
}
}
$('button').click(laa);

Extract property of a tag in HTML using Javascript

Is it possible to extract properties of a HTML tag using Javascript.
For example, I want to know the values present inside with the <div> which has align = "center".
<div align="center">Hello</div>
What I know is:
var division=document.querySelectorAll("div");
but it selects the elements between <div> & </div> and not the properties inside it.
I want to use this in the Greasemonkey script where I can check for some malicious properties of a tag in a website using Javascript.
Hope I'm clear..!!
You are looking for the getAttribute function. Which is accessible though the element.
You would use it like this.
var division = document.querySelectorAll('div')
for(var i=0,length=division.length;i < length;i++)
{
var element = division[i];
var alignData = division.getAttribute('align'); //alignData = center
if(alignData === 'center')
{
console.log('Data Found!');
}
}
If you're looking to see what attributes are available on the element, these are available though
division.attributes
MDN Attributes
So for instance in your example if you wanted to see if an align property was available you could write this.
//Test to see if attribute exists on element
if(division.attributes.hasOwnProperty('align'))
{
//It does!
}
var test = document.querySelectorAll('div[align="center"]');

using javascript's .insertBefore to insert item as last child

I so miss jQuery. I'm working on a project where I need to get my hands dirty with good 'ol plain Javascript again.
I have this scenario:
parent
child1
child2
child3
Via javascript, I want to be able to insert a new node before or after any of those children. While javascript has an insertBefore, there is no insertAfter.
Insert before would work fine on the above to insert a node before any one of those:
parent.insertBefore(newNode, child3)
But how does one insert a node AFTER child3? I'm using this at the moment:
for (i=0,i<myNodes.length,i++){
myParent.insertBefore(newNode, myNodes[i+1])
}
That is inserting my newNode before the next sibling node of each of my nodes (meaning it's putting it after each node).
When it gets to the last node, myNodes[i+1] become undefined as I'm now trying to access a array index that doesn't exist.
I'd think that'd error out, but it seems to work fine in that in that situation, my node is indeed inserted after the last node.
But is that proper? I'm testing it now in a few modern browsers with no seemingly ill effects. Is there a better way?
Pure JavaScript actually has a method for what you want:
parent.appendChild(child_to_be_last)
The functionality of insertBefore(newNode, referenceNode) is described as:
Inserts the specified node before a reference node as a child of the current node. If referenceNode is null, then newNode is inserted at the end of the list of child nodes.
And since myNodes[i+1] is outside of the array bounds, it returns undefined, which is treated as null in this case. This means you get your desired behavior.
Edit: Link to the W3 specification of insertBefore()
Modern Solution
If you want to position based on child, simply use before or after
child1.before(newNode) // [newNode, child1, child2]
// or
child1.after(newNode) // [child1, newNode, child2]
If you want to position based on parent, use prepend or append
parent.prepend(newNode) // [newNode, child1, child2]
// or
parent.append(newNode) // [child1, child2, newNode]
Advanced usage
You can pass multiple values (or use spread operator ...).
Any string value will be added as a text element.
Examples:
child1.after(newNode, "foo") // [child1, newNode, "foo", child2]
const list = ["bar", newNode]
parent.prepend(...list, "fizz") // ["bar", newNode, "fizz", child1, child2]
Mozilla Docs
before - after
prepend - append
Can I Use - 95% Mar 2021
To insert item as a last node use :parentNode.insertBefore(newNode, null);
Also when not iterating through children (just inserting after referenceNode) this might be useful:
parentNode.insertBefore(newNode, referenceNode.nextSibling);
I got this code is work to insert a link item as the last child
var cb=function(){
//create newnode
var link=document.createElement('link');
link.rel='stylesheet';link.type='text/css';link.href='css/style.css';
//insert after the lastnode
var nodes=document.getElementsByTagName('link'); //existing nodes
var lastnode=document.getElementsByTagName('link')[nodes.length-1];
lastnode.parentNode.insertBefore(link, lastnode.nextSibling);
};
var raf=requestAnimationFrame||mozRequestAnimationFrame||
webkitRequestAnimationFrame||msRequestAnimationFrame;
if (raf)raf(cb);else window.addEventListener('load',cb);

Categories