Is it possible to access the jQuery lib from an iframe, when it's included in the parent window only? I have a parent window which loads (sometimes hundreds) of iframes. In each iframe I want to execute some jQuery functions. I can only get this working if I define the lib in each iframe, using :
<script src="/jquery.min.js" type="text/javascript"></script>
However, I would prefer, for faster loading, that I include the above script tag only in the parent window, then from each child/iframe access the parent's library to execute a function that affects the iframe.
Thanks for the response. Here is what I have in the child frame :
<script>
var $ = parent.jQuery;
$(this, document).ready(function(){
var step = 0.2;
$('body', document).css('MozTransform','scale(0.2)');
});
</script>
And what I'd expect is that once the child's doc is "ready" it would shrink itself down to 20%. Except its not working. Is it possible, or should I try add the child's code to the parent doc and assign ids to each frame, then loop through them.
Using
$( document ).ready(function(){
$('body').css('MozTransform','scale('
results in the parent window scaling down. I'm wanting to scale down the iframe.
Assuming the iframes are in the same domain as the parent document, you can easily get a reference to the parent window's jQuery:
var $ = parent.jQuery;
Or if you have iframes nested more than one level deep:
var $ = top.jQuery;
However, jQuery by default will only query the document from where it was included. In case you need to query the given iframe's DOM, you have two options:
Pass document, which in this case points to the given iframe's window.document, as context:
$('#elementInsideIframe', document).doSomething();
Or, store a jQuery object containing the iframe's document and .find() its descendants.
var $dom = $(document);
$dom.find('#elementInsideIframe').doSomething();
Live demo
Parent window
iframe contents
Despite what others say, caching is not "good enough" for your use case. jQuery has quite some init overhead and it is something that you do not want to include hundreds of times.
As per OP update:
Just use $(document).ready() inside the frames. In an (i)frame context, document points to the given frame's window.document.
Also, if you're using jQuery >= 1.8, you don't need to use vendor prefixes - jQuery will use the appropriate vendor-prefixed property in case the standard one is not supported.
Demo: parent, iframe
The overhead of jerking around with the html-code of a parent window or top window will cost more than the extra line of script to to load jquery as you should.
Load it individually in each frame, possibly use an online version of jquery, this will increase the chanses of the client having the library loaded before entering your site.
In example
<script src="http://code.jquery.com/jquery-latest.min.js"
type="text/javascript"></script>
Related
I am trying to fill a textarea in a window opened with open(link_here) (on the same domain). It works fine in all browsers except IE/Edge.
Steps to reproduce here on stackoverflow:
var w = open('https://stackoverflow.com'); // example
// (allow popups and) wait for window to be opened, then:
let input = w.document.getElementsByClassName('f-input js-search-field')[0]
const prototype = Object.getPrototypeOf(input); // returns null on IE/Edge
Any workaround?
Thanks
I believe it is a Hierarchy access restriction. Since the element is not in the same window as the Object you are using, it doesn't have access to the object's information. You will have a somewhat similar problem if you try to append an element created by the main document and try to append it to the iframe document. When attempting this you will get a HierarchyRequestError.
Instead of using the main window's Object use the iframe window's Object:
var prototype = w.window.Object.getPrototypeOf(input);
console.log(prototype);
instead of vanilla javascript try JQUERY which works on every browser correct so change your selector to jquery one you need to include first JQUERY at your file
I'm working within a setup that I have no control over:
Parent->Iframe->Iframe->My document
How do I access an element that is on the parent from within my document?
These are all on the same domain, so no cross-domain issues. I can do this with either straight up JS or jQuery.
I've been searching around, but haven't found any examples of someone trying to access an element on the top from the bottom through multiple iframes!
The solution, in case anyone else comes across this:
var p = $("#Viewport",window.top.document);
alert(p.attr('name'));
Just use window.top, like:
console.log(top.document.getElementById('someInputId').value);
Notice that window in implicit, so you can leave it off. Of course, you will have to change 'someInputId' to an input id on your top page to see if this works. Use .innerHTML instead of .value if you are testing against an Element that is not an input.
I believe you will be able to access this via window.parent, as thus:
window.parent.document.getElementById('target-element');
Similar to Firebug Inspect I have a block of code to read the DOM and upon mouseover highlight the current element, and upon click to print out that current element's DOM location. See demo:
http://jsfiddle.net/94EaH/4/
I'm trying to modify the code to work on the content within an iframe. I don't want it to work on the current page AND iframe's DOM, because I know that won't work. I want to change the selector the code is bound to, to be the iframe. The iframe is of course embedded within a page, but only the iframe's DOM is being analyzed.
I can manipulate the parent through the iframe like this:
<iframe id="testFrame" src="blah.html" width="200px" height="200px"></iframe>
<div id="testBox">text text text</div>
$("#testFrame").contents().bind("click", function() {
$('#testBox').css('color', 'green');
});
But if I add one more line to modify the content of a DIV inside the iframe.. nothing.
$("#testFrame").contents().bind("click", function() {
$('#testBox').css('color', 'green');
$('#iframeDiv').css('color', 'red'); //this produces no result
console.log(event.target); // I get no information out of this also..
});
http://jsfiddle.net/94EaH/3/
It's difficult to show full functionality, since blah.html (iframe source) can't be displayed on jsfiddle..
Any ideas on how I could extend this functionality to an iframe's DOM instead of the #container element of the current page I've used in the example?
The iframe file is on the same server, so no security issues
If you're trying to access an element in an Iframe with jQuery from the parent window, then you've got a problem. Imagine you've got a iframe. Inside the iframe, there's a div with id 'container'. If you do this from the parent document, $('#container'), you'll find the jQuery object is empty.
jQuery is bound to the window and document objects of the page in which it is declared (loaded). It does no matter that you're constructing it from an event handler bound to the iframe, the $ function you're using still belongs to the parent window. If you load jQuery in the iframe's page, however, you could get references to the objects like this:
$('#testFrame')[0].contentWindow.$('#container');
Here, the first '$' and the second '$' do not refer to the same jQuery constructor.
Edited I forgot the [0] to access the first iframe in the jQuery object.
I hope this helps you.
I'm trying to manipulate some anchors after the document is loaded to alter their href attribute using Prototype. Based on the class of an anchor, its href has to be rewritten to be used by a tracking software.
I hacked some things together but can't quite figure out why it doesn't work. It always returns undefined, not matter what I search for.
<script type="text/javascript">
var elements = $$(".replace");
for (el in elements) {
el.href = "other_href.html";
}
</script>
Link
When I alert(el) in the loop, it returns either undefined or (when I search for a.replace an extraordinary number of elements that don't even exist on my page.
Where is my thinking error in here?
Untested:
<script type="text/javascript">
document.observe('dom:loaded', function() {
$$(".replace").each(function(a) {
a.writeAttribute('href', 'other_href.html');
});
});
</script>
Link
I'm guessing your JavaScript was loaded and executed before the HTML it was supposed to manipulate was loaded by the browser. It can't manipulate what doesn't exists yet. That's where observing events comes in handy. In this case, we're waiting for the DOM to finish loading, but before the page is rendered by the browser, to make our changes.
I also took advantage of Prototype's each() functionality. It's a great way to loop through arrays and any enumerables. And writeAttribute() is a good cross-browser way to modify element attributes.
I have an instance of CKEditor on a page. I am trying to give the CKEditor's body a class or ID so it matches some styles I have defined in a stylesheet.
There is a API documentation that should give access to the respective DOM elements, but I can't seem to get it working. All objects I try to query that way turn out undefined.
Does anybody know how to do this, or how to properly address CKEditor's dom elements?
Edit: Thanks folks, nemisj's answer did it for me but for some reason, I don't get to set the "accepted" checkmark in this question.
Although that part of the API wasn't ported from 2.x at the time that this question was placed, now it's easier to use the bodyId and bodyClass config options.
Of course, the explanation by nemisj is good and can be useful for other things, but you must remember that each time that you switch away from design (to source view), the iframe is destroyed, so you'll need to reassign your attributes if you do it manually.
If you are talking about CKEditor( version 3), then there is a possibility to get any DOM instance inside the editor itself. Every CKEditor instance has reference to it's document via "document" property.
var documentWrapper = edit.document;
This reference represent some public wrapper for all CKEditor nodes, but it also has the direct reference to its node. You can retrieve by getting ["$"] property.
var documentNode = documentWrapper.$; // or documentWrapper['$'] ;
documentNode will represent the DOM instance of the document node inside the iframe. After you have the DOM instance, you can do whatever you want to do with DOM structure, Append, remove, replace classes, rebuild, etc. For example
documentNode.body.className = "zork";
I hope this should be enough.
I had the same problem today in trying to set the bodyClass like this:
CKEDITOR.replace( 'editor1',
{
fullPage : true,
bodyClass : 'myClass'
});
What I found is that in this version (3.3.1), if you set fullpage = true, setting the bodyId or bodyClass does not work, but if you set fullPage = false, it does work.
Hope this helps.
From the Manual:
<static> {String|Array} CKEDITOR.config.contentsCss
The CSS file(s) to be used to apply style to the contents. It should reflect the CSS used in the final pages where the contents are to be used.
config.contentsCss = '/css/mysitestyles.css';
config.contentsCss = ['/css/mysitestyles.css', '/css/anotherfile.css'];
Default Value:
<CKEditor folder>/contents.css
Don't know that editor, but as they all work the same way, you probably can't access the DOM elements created by the instance because they are created after the page has finished loading, and the DOM is ready as well. So, any new DOM elements added after that, theorically will not exist.
Still, you can try TinyMCE editor, wich has a "partnership" with jQuery javascript library to manipulate all you want, and the editor itself is pretty easy to change in almost every way.
Your queries may return undefined because the editor instances are placed inside an iFrame and your query is not looking there?
In config.js, write this code
config.bodyId = 'contents_id';
then you see body id in Ckeditor but when you want to access this id please use
$('#parent_id').find('iframe').contents().find('#within_iframe')
there $('#parent_id') means form_id or any parent which is simply way to access iframe. follow this code to access element in iframe