How to select element based on another already-existing selector? - javascript

I have the following code:
<html>
<head>
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
google.load("jquery", 1);
</script>
<script type="text/javascript">
var rt, rt2;
window.onload = function () {
rt = $('#rt').contents().get(0);
rt.designMode = 'On';
}
</script>
</head>
<body>
<iframe id="rt" width="500" height="500"></iframe>
</body>
</html>
rt is currently selecting the whole iframe document. I want rt2 to select the body element inside the document element, which is what rt is selecting. I tried:
rt2 = jQuery(rt, "html");
rt2 = jQuery(rt2, "body");
But it didn't seem to work. How would it be possible?

According to the documentation, the context to search within should be supplied as the second parameter, not the first, so try this instead:
rt2 = jQuery("html", rt);
The context can be:
A DOM Element, Document, or jQuery to use as context
Internally, the context is implemented using the .find() method. So the above example is just a short hand of:
rt2 = jQuery(rt).find("html");

Use find:
var myFrame = $('#rt').contents();
var myvar = myFrame.find('body');

Try with:
rt2body = iframeElement.find("body");
Further reading on .find: http://api.jquery.com/find/

Related

Use inline javascript to set some values [duplicate]

I'm wondering if there is a way to get a handle on the DOM element that contains the script inside it. So if I had:
<script type="text/javascript> var x = ?; </script>
Is there a way that I can assign "x" a reference to the script element that contains "x"?
There isn't a truly safe way.
The closest you can come is to use getElementsByTagName to get all the scripts, get its length, get the last script element, then work from there.
This can fail if the script is deferred or if the script has been dynamically added to the page before another script element.
You could include some marker text in the script element, and then (similar to what David said), you can loop through all the script elements in the DOM (using getElementsByTagName or whatever features your library, if you're using one, may have). That should find the element reliably. That would look something like this (live example):
<body>
<script id='first' type='text/javascript'>
(function() {
var x = "MARKER:first";
})();
</script>
<script id='second' type='text/javascript'>
(function() {
var x = "MARKER:second";
})();
</script>
<script id='third' type='text/javascript'>
(function() {
var x = "MARKER:third";
})();
</script>
<script id='last' type='text/javascript'>
(function() {
var scripts, index, script;
scripts = document.getElementsByTagName("script");
for (index = 0; index < scripts.length; ++index) {
script = scripts[index];
if (script.innerHTML.indexOf("MARKER:second") >= 0
&& script.id !== "last") {
display("Found MARKER:second in script tag #" + script.id);
}
}
function display(msg) {
var p = document.createElement('p');
p.innerHTML = msg;
document.body.appendChild(p);
}
})();
</script>
</body>
Note that, like the script above, if you're looking for a script tag marker from within a different script tag, you'll need to handle that. Above it's handled by checking the ID of the script tag, but you can also just break it up in the one you don't want to find, like this (live example):
if (script.innerHTML.indexOf("MARKER:" + "second") >= 0) {
display("Found MARKER:" + "second in script tag #" + script.id);
}

Javascript create iframe set content then return it from one function

I need to create an iframe dynamically, set its html, then return it as a function so it can be called later with newAdUnit(). Right now it returns [object HTMLIFrameElement]. I'm trying to figure out a way to do this all from one function. The reason for this is I'm setting up ads that need to be loaded in dynamically. A single function would make my code a lot cleaner since I can call it in a number of different ways. Any ideas?
<script>
function newAdUnit(size) {
var iframe = document.createElement('iframe');
iframe.onload = function() {
iframe = iframe.contentWindow.document;
var html = '<body>This is a test</body>';
iframe.open();
iframe.write(html);
iframe.close();
};
return iframe;
}
</script>
<div id="test">
<script>document.getElementById("test").innerHTML = newAdUnit()</script>
</div>
It will be so much easy if you use JQuery for the current operation. The code below shows how to
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
function newAdUnit(obj) {
var iframe = document.createElement('iframe');
iframe.onload = function() {
iframe = iframe.contentWindow.document;
var html = '<body>This is a test</body>';
iframe.open();
iframe.write(html);
iframe.close();
};
$(obj).append(iframe);
}
newAdUnit($('#test'));
});
</script>
</head>
<body>
<div id="test">
</div>
</body>
</html>
You should only use .innerHTML when the thing you want to add is a string of HTML. However, in your case, you have a HTMLIFrameElement object, and so, you can't use .innerHTML in this case. Currently, Javascript is implicitly calling .toString() on your element object returned by newAdUnit(), which results in [object HTMLIFrameElement].
Instead, when you want to add a node element to another element, you can use .appendChild() like so:
<div id="test"></div>
<script>
function newAdUnit(size) {
var iframe = document.createElement('iframe');
iframe.onload = function() {
iframe = iframe.contentWindow.document;
var html = '<body>This is a test. The size is ' + size + '</body>';
iframe.open();
iframe.write(html);
iframe.close();
};
return iframe;
}
document.getElementById("test").appendChild(newAdUnit(10));
</script>

javascript document.write script

Edited qestion
I'm trying to create two separate HTML documents: main.html and sufler.html . Idea is to control sufler.html page from main.html . To do that I found a solution
to write sufler's.html code like string element on main.html page, change what I need in that string element and write it with document.write function from main.html . Everything
works fine except <script> function...
main.html
<script type="text/javascript">
var HTMLstringPage1 = '<!DOCTYPE html><html><head><link href="stilius.css" rel="stylesheet" type="text/css" />',
HTMLstringPage2 = '</body></html>',
HTMLstringStyle = '\x3Cscript type="text/javascript">function styluss(){document.getElementById("flip").style.font="normal normal 30px sans-serif";}\x3C/script>',
HTMLstringDiv1 = '</head><body onload="styluss()"><div id="sufler"><div id="mov"><p id="flip">',
HTMLstringDiv2 = '</p></div></div>';
var newWindow = window.open('sufler.html','_blank','toolbar=no, scrollbars=no, resizable=no, height=615,width=815');
newWindow.document.body.innerHTML = '';
newWindow.document.write(HTMLstringPage1,HTMLstringDiv1+"Text"+HTMLstringDiv2,HTMLstringPage2); //works fine
// newWindow.document.write(HTMLstringPage1,HTMLstringStyle,HTMLstringDiv1+"Text"+HTMLstringDiv2,HTMLstringPage2);//works except script function
</script>
Can someone help on this?
To dynamically add a script tag, it is much better to do this:
var newDoc = newWindow.document;
var script = newDoc.createElement("script");
script.type = "text/javascript";
var text = newDoc.createTextNode('function styluss(){document.getElementById("flip").style.font="normal normal 30px sans-serif";}');
script.appendChild(text);
newDoc.getElementsByTagName("head")[0].appendChild(script);
Working demo: http://jsfiddle.net/jfriend00/JqW5F/
But, creating code on the fly like this is almost never needed. Since you must, by definition, generally already know what you want the code to do, you can just have a pre-created function that takes some arguments and then call that existing function with the right arguments to accomplish what you wanted to rather than creating a custom function on the fly:
function styleIt(id, fontStyle) {
document.getElementById(id).style.font = fontStyle;
}
styleIt("flip", "normal normal 30px sans-serif");
styleIt("flip2", "normal normal 12px sans-serif");
You have to use normal opening brackets for <script> tags:
var HTMLstringStyle = '<script type="text/javascript">function styluss(){document.getElementById("flip").style.font="normal normal 30px sans-serif";}<\/script>';
Although I can't see why you would ever use this... attaching a <script> tag to the <head> or the <body> is almost always a superior solution.

Appending children into a popup-window. (JavaScript)

I'm having some trouble trying to get a fairly simple popupper to work. The idea is that the parent should open a popup window and then append a div in it.
The relevant parts of the code:
parent.html:
var childWindow;
function togglePref() {
childWindow = window.open("popup.html", "prefPopup", "width=200,height=320");
}
function loadPopupElements() {
var prefElements = document.getElementById("prefBrd").cloneNode(true);
var childDoc = childWindow.document;
var childLink = document.createElement("link");
childLink.setAttribute("href", "pop.css");
childLink.setAttribute("rel", "stylesheet");
childLink.setAttribute("type", "text/css");
childDoc.head.appendChild(childLink);
childDoc.body.appendChild(prefElements);
}
popup.html:
<head>
</head>
<body onload="opener.loadPopupElements();">
</body>
This works fine with Safari and Chrome, but for some reason IE refuses to append anything.
Ok, I managed to work around the problem with a uglyish solution using innerHTML. Apparently, as Hemlock mentioned, IE doesn't support appending children from a another document. Some suggested to take a look at the importNode() method but I seemed to have no luck with it either.
So, the workaround goes as follows:
parent.html:
var childWindow;
function togglePref() {
childWindow = window.open("popup.html", "prefPopup", "width=200,height=320");
}
function loadPopupElements() {
var prefElements = document.getElementById("prefBrd");
var childDoc = childWindow.document;
childDoc.body.innerHTML = prefElements.innerHTML;
}
popup.html:
<head>
<link href="pop.css" rel="stylesheet" type="text/css">
</head>
<body onload="loadElements();">
</body>
<script type="text/javascript">
function loadElements() {
opener.loadPopupElements();
}
</script>
This seems quite a nasty way to go because in my case the #prefBrd contains some input elements with dynamically set values, so in order for the popup.html to grab them, it has to do a bit of iteration at the end of the loadElements() function, which wouldn't have been necessary using appendChild.

Reference script container element?

I'm wondering if there is a way to get a handle on the DOM element that contains the script inside it. So if I had:
<script type="text/javascript> var x = ?; </script>
Is there a way that I can assign "x" a reference to the script element that contains "x"?
There isn't a truly safe way.
The closest you can come is to use getElementsByTagName to get all the scripts, get its length, get the last script element, then work from there.
This can fail if the script is deferred or if the script has been dynamically added to the page before another script element.
You could include some marker text in the script element, and then (similar to what David said), you can loop through all the script elements in the DOM (using getElementsByTagName or whatever features your library, if you're using one, may have). That should find the element reliably. That would look something like this (live example):
<body>
<script id='first' type='text/javascript'>
(function() {
var x = "MARKER:first";
})();
</script>
<script id='second' type='text/javascript'>
(function() {
var x = "MARKER:second";
})();
</script>
<script id='third' type='text/javascript'>
(function() {
var x = "MARKER:third";
})();
</script>
<script id='last' type='text/javascript'>
(function() {
var scripts, index, script;
scripts = document.getElementsByTagName("script");
for (index = 0; index < scripts.length; ++index) {
script = scripts[index];
if (script.innerHTML.indexOf("MARKER:second") >= 0
&& script.id !== "last") {
display("Found MARKER:second in script tag #" + script.id);
}
}
function display(msg) {
var p = document.createElement('p');
p.innerHTML = msg;
document.body.appendChild(p);
}
})();
</script>
</body>
Note that, like the script above, if you're looking for a script tag marker from within a different script tag, you'll need to handle that. Above it's handled by checking the ID of the script tag, but you can also just break it up in the one you don't want to find, like this (live example):
if (script.innerHTML.indexOf("MARKER:" + "second") >= 0) {
display("Found MARKER:" + "second in script tag #" + script.id);
}

Categories