I'm trying to get a reference to a DOM object created by qUnit, with no luck. It works just fine with a "home made" DOM element. I have made a test site to illustrate the problem. Turn on Firebug or other logging window when visiting the site.
This is the code of the website:
window.onload = function() {
var qunitTestrunnerToolbar_element = document.getElementById("qunit-testrunner-toolbar");
console.log("qunitTestrunnerToolbar_element: ", qunitTestrunnerToolbar_element);
var test_element = document.getElementById("test_element");
console.log("test_element: ", test_element);
};
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Testing 'require' error</title>
</head>
<body>
<p>See console for output</p>
<script src="index.js"></script>
<script src="http://code.jquery.com/jquery-2.2.0.js"></script>
<p id="test_element">Test element</p>
</body>
</html>
It won't work like this
I am not talking about qunit but document.getElementById("qunit-testrunner-toolbar"); will return null because there are no element present in this html.
If you are particularly asking how to get actual id and not null
You may, add your original script file in this html and then var qunitTestrunnerToolbar_element = document.getElementById("qunit-testrunner-toolbar"); will console it in indexjs or if you can include <iframe> in your test html you can do
<iframe src="urlWithinYourDomain.html" style="display:none" id="iframeId"></iframe>
and in indexjs
var qunitTestrunnerToolbar_element = document.getElementById('iframeId').contentWindow.document.getElementById('qunit-testrunner-toolbar'); if you like html way.
Related
I have small snippet that is inside iframe and generates script html tag and appends it to the window.top.document.head.
Now I want to know how do I check from within potato.js from which iframe it was generated from once it is already loaded?
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<iframe>
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script>
(function() {
var s = document.createElement('script');
s.setAttribute('type','text/javascript');
s.setAttribute('src','https://test.com/potato.js');
window.top.document.head.appendChild(s);
})();
</script>
</body>
</html>
</iframe>
</body>
</html>
Edit: I can not change this code inside the iframe
That information isn't stored automatically.
The only way I can think of would be to add an expando-prop to the script with a reference to the current window (i.e. the frame's window)…
s.sourceWindow = window;
… then read that from within potato.js …
const sourceWindow = document.currentScript.sourceWindow;
… and then loop over all the frames (window.frames) looking for a match.
Since you are using window.top and not window.parent you might need to be recursive there.
Can someone help me with stating what am I doing wrong in this example -- http://jsbin.com/bekoxo/2/edit?html,output#H:L23
The screenshot for the chrome inspector is at -
https://www.dropbox.com/s/t6uua7h714h2otg/Screenshot%202014-10-13%2001.32.54.png?dl=0
I can figure out that the element (appler-page) is not registered successfully, template shows document-fragment instead of desired shadow-root
the 2nd element, where polymer definition is part of the markup(same markup) is rendered successfully.
Can someone point out what am I missing in order to make the first part of example also work.
(which is creating an element via javascript and using it immediately)
EDIT --- problem code below
<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/polymer/0.3.3/platform.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/polymer/0.3.3/polymer.js"></script>
<meta name="description" content="problem with dynamically building a polymer element" />
<script src="//code.jquery.com/jquery-1.9.1.min.js"></script>
<script>
var scr = '<polymer-element name="appler-page"><template>template content {{test}}</template><script>var proxymodel = {};proxymodel["test"] = "testfie" ;'+
'Polymer(proxymodel);<\/script><\/polymer-element><appler-page><\/appler-page>';
$(document).ready(function(){
document.getElementById("fie").onclick = function(){
var divel = document.createElement("div");
divel.innerHTML = scr;
document.querySelector(".polymerized").innerHTML = "";
document.querySelector(".polymerized").appendChild(divel);
}
});
</script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<input type="button" id="fie" value="fie"/>
<div class="polymerized">before content</div>
EDIT -- A better jsbin for the problem
http://jsbin.com/bekoxo/2/edit?html,output#H:L23
Here is one way in which you can register your element imperatively (which, I believe is what your first element is trying to do). I've simplified your example a bit.
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
</head>
<body>
<script src="http://www.polymer-project.org/platform.js"></script>
<link rel="import"
href="http://www.polymer-project.org/components/polymer/polymer.html">
<script>
Polymer('appler-page', {test: 'testfile'});
var el = document.createElement('div');
el.innerHTML = '\
<polymer-element name="appler-page">\
<template>template content {{test}}</template>\
</polymer-element>';
document.body.appendChild(el);
</script>
<appler-page></appler-page>
</body>
</html>
See http://jsbin.com/qifupa/edit
Another instance of staying up with the latest Polymer version I found.
here's the working piece of code that may help anyone else if they are attempting the same thing.
I switched to Polymer-project.org addresses for the imports and it worked.
http://jsbin.com/bekoxo/14/edit?html,output#H:L23
Using jQuery I am trying to access div id="element".
<body>
<iframe id="uploads">
<iframe>
<div id="element">...</div>
</iframe>
</iframe>
</body>
All iframes are on the same domain with no www / non-www issues.
I have successfully selected elements within the first iframe but not the second nested iframe.
I have tried a few things, this is the most recent (and a pretty desperate attempt).
var iframe = jQuery('#upload').contents();
var iframeInner = jQuery(iframe).find('iframe').contents();
var iframeContent = jQuery(iframeInner).contents().find('#element');
// iframeContent is null
Edit:
To rule out a timing issue I used a click event and waited a while.
jQuery().click(function(){
var iframe = jQuery('#upload').contents().find('iframe');
console.log(iframe.find('#element')); // [] null
});
Any ideas?
Thanks.
Update:
I can select the second iframe like so...
var iframe = jQuery('#upload').contents().find('iframe');
The problem now seems to be that the src is empty as the iframe is generated with javascript.
So the iframe is selected but the content length is 0.
Thing is, the code you provided won't work because the <iframe> element has to have a "src" property, like:
<iframe id="uploads" src="http://domain/page.html"></iframe>
It's ok to use .contents() to get the content:
$('#uploads).contents() will give you access to the second iframe, but if that iframe is "INSIDE" the http://domain/page.html document the #uploads iframe loaded.
To test I'm right about this, I created 3 html files named main.html, iframe.html and noframe.html and then selected the div#element just fine with:
$('#uploads').contents().find('iframe').contents().find('#element');
There WILL be a delay in which the element will not be available since you need to wait for the iframe to load the resource. Also, all iframes have to be on the same domain.
Hope this helps ...
Here goes the html for the 3 files I used (replace the "src" attributes with your domain and url):
main.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>main.html example</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(function () {
console.log( $('#uploads').contents().find('iframe').contents().find('#element') ); // nothing at first
setTimeout( function () {
console.log( $('#uploads').contents().find('iframe').contents().find('#element') ); // wait and you'll have it
}, 2000 );
});
</script>
</head>
<body>
<iframe id="uploads" src="http://192.168.1.70/test/iframe.html"></iframe>
</body>
iframe.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>iframe.html example</title>
</head>
<body>
<iframe src="http://192.168.1.70/test/noframe.html"></iframe>
</body>
noframe.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>noframe.html example</title>
</head>
<body>
<div id="element">some content</div>
</body>
var iframeInner = jQuery(iframe).find('iframe').contents();
var iframeContent = jQuery(iframeInner).contents().find('#element');
iframeInner contains elements from
<div id="element">other markup goes here</div>
and iframeContent will find for elements which are inside of
<div id="element">other markup goes here</div>
(find doesn't search on current element) that's why it is returning null.
Hey I got something that seems to be doing what you want a do. It involves some dirty copying but works. You can find the working code here
So here is the main html file :
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
Iframe = $('#frame1');
Iframe.on('load', function(){
IframeInner = Iframe.contents().find('iframe');
IframeInnerClone = IframeInner.clone();
IframeInnerClone.insertAfter($('#insertIframeAfter')).css({display:'none'});
IframeInnerClone.on('load', function(){
IframeContents = IframeInner.contents();
YourNestedEl = IframeContents.find('div');
$('<div>Yeepi! I can even insert stuff!</div>').insertAfter(YourNestedEl)
});
});
});
</script>
</head>
<body>
<div id="insertIframeAfter">Hello!!!!</div>
<iframe id="frame1" src="Test_Iframe.html">
</iframe>
</body>
</html>
As you can see, once the first Iframe is loaded, I get the second one and clone it. I then reinsert it in the dom, so I can get access to the onload event. Once this one is loaded, I retrieve the content from non-cloned one (must have loaded as well, since they use the same src). You can then do wathever you want with the content.
Here is the Test_Iframe.html file :
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>Test_Iframe</div>
<iframe src="Test_Iframe2.html">
</iframe>
</body>
</html>
and the Test_Iframe2.html file :
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>I am the second nested iframe</div>
</body>
</html>
You probably have a timing issue. Your document.ready commend is probably firing before the the second iFrame is loaded. You dont have enough info to help much further- but let us know if that seems like the possible issue.
You should use live method for elements which are rendered later, like colorbox, hidden fields or iframe
$(".inverter-value").live("change",function() {
elem = this
$.ajax({
url: '/main/invertor_attribute/',
type: 'POST',
aysnc: false,
data: {id: $(this).val() },
success: function(data){
// code
},
dataType: 'html'
});
});
I think the best way to reach your div:
var your_element=$('iframe#uploads').children('iframe').children('div#element');
It should work well.
If browser supports iframe, then DOM inside iframe come from src attribute of respective tag. Contents that are inside iframe tag are used as a fall back mechanism where browser does not supports iframe tag.
Ref: http://www.w3schools.com/tags/tag_iframe.asp
I guess your problem is that jQuery is not loaded in your iframes.
The safest approach is to rely on pure DOM-based methods to parse your content.
Or else, start with jQuery, and then once inside your iframes, test once if typeof window.jQuery == 'undefined', if it's true, jQuery is not enabled inside it and fallback on DOM-based method.
Currently I'm doing this:
var newdoc = document.implementation.createHTMLDocument("Wrong title");
newdoc.open();
newdoc.write('<!doctype html><html><head><title>Right title</title></head><body><div id="a_div">Right content</div></body></html>');
newdoc.close();
And then I try to get some info about the document loaded, for example:
> newdoc.title
Right title
> newdoc.getElementById("a_div").innerHTML
Right content
The issue is that it only works in Chrome. On Firefox and Opera the DOM does not seem to be loaded after document close. What am I doing wrong?
I wrote this little fiddle to demonstrate the problem: http://jsfiddle.net/uHz2m/
Okay, after reading the docs I noticed createHTMLDocument() does not create a zero byte-length document object but a basic HTML scaffolding like this:
<!DOCTYPE html>
<html>
<head>
<title>Wrong title</title>
</head>
<body></body>
</html>
That's why newdoc.write() does not work as expected.
Instead, I can just take the html element and change its HTML code (corrected fiddle).
var newdoc = document.implementation.createHTMLDocument("Wrong title");
newdoc.documentElement.innerHTML = '\
<!doctype html>\
<html>\
<head>\
<title>Right title</title>\
</head>\
<body>\
<div id="a_div">Right content</div>\
</body>\
</html>';
This question already has answers here:
Why does jQuery or a DOM method such as getElementById not find the element?
(6 answers)
Closed 6 years ago.
Ok. I need fresh eyes because I'm still on this s***d problem for one hour!
Here is my simple HTML code (testssio.html) that include javascript script:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var ssio = document.getElementById('ssio');
ssio.html = "it finally works!";
</script>
</head>
<body>
<div id="ssio"></div>
</body>
</html>
But it doesn't work! Using the debugger, I get:
Uncaught TypeError: Cannot set property 'html' of null /testssio/:6
Does anyone get it? I know it's not the correct place to look for debugging help, but I'll be crazy if I don't get it! So please, any help?
Tahnks in advance.
The reason for this is that scripts in the head load before the page is rendered. This means your content is not yet rendered and therefore not a part of document.
If you want to see this work, try moving your script below the element renders, like this:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="ssio"></div>
<script type="text/javascript">
var ssio = document.getElementById('ssio');
ssio.innerHTML = "it finally works!";
</script>
</body>
</html>
A more standardized way of doing this is with events. Many people use jQuery but it can be done with plain js. This would mean changing your script like this:
<script type="text/javascript">
function WinLoad() {
var ssio = document.getElementById('ssio');
ssio.innerHTML = "It finally works!";
}
window.onload = WinLoad;
</script>
This way you can still leave it in the <head>.
Also, using .html is from jQuery. It is generally used as .html(content). If you want to use the plain javascript version use .innerHTML = content.
I mention jQuery so much because it is a highly used API. This quote is from their site:
jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development. jQuery is designed to change the way that you write JavaScript.
Your code is running too early before the DOM is loaded and thus document.getElementById() doesn't find the element in the document yet.
You can either move your script tag down to right before the </body> tag or you can wait for the DOM to load before running your code with either the window onload event or a DOMReady event.
There are two errors here. First, you need to put the SCRIPT tag after the element. Second, it's not .html, but .innerHTML. So here is the corrected code:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="ssio"></div>
<script type="text/javascript">
var ssio = document.getElementById('ssio');
ssio.innerHTML = "it finally works!";
</script>
</body>
</html>
you can use something like this
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
document.onload= function(){
var ssio = document.getElementById('ssio');
ssio.html = "it finally works!";
}
</script>
</head>
<body>
<div id="ssio"></div>