What is wrong with this piece of code:
jQuery('<iframe id="groundplan_popup" class="groundplan_hidden" />').appendTo("#popup_holder");
var iframe = jQuery("#groundplan_popup");
iframe.attr("src","::censored::" + filename);
var iframe_body = iframe.contents().find('body').append('<div id="groundplan_popup_exit"></div>');
var exit_btn_gp = iframe_body.append(jQuery("#groundplan_popup_exit"));
So i have to dynamically create an iframe element which will open up .pdf file in a popup and that part works. What I can't manage to do is create a div with an id of "groundplan_popup_exit" within that iframe. I don't know exactly why this doesnt' work and what exactly I'm doing wrong. When i inspect the iframe window console brings out this warning:
/deep/ combinator is deprecated. See https://www.chromestatus.com/features/6750456638341120 for more
details.
Dont know if it has anything to do with the reason why this isn't working.
EDIT:
This is what my code looks like now.
Console prtscr:
Iframe console elements prtscr:
So i'm basically confused about the whole situation as I'm not that experienced in using jquery in general and this is my first time using it with iframes. I'm not even sure if the #groundplan_popup_exit div is even created and how do I find it if it is.
I see some problems:
var iframe_body = iframe.contents().find('body').append('<div id="groundplan_popup_exit"></div>');
Here you are already appending the element to the body.
var exit_btn_gp = iframe_body.append(jQuery("#groundplan_popup_exit"));
After you have appended above, you are trying to append again with jQuery("#groundplan_popup_exit") which does not even exists.
Fix (untested) would be something like this:
var iframe_body = iframe.contents().find('body');
var exit_btn_gp = iframe_body.append('<div id="groundplan_popup_exit"></div>');
Related
var iframe = $('iframe').contentWindow.document.getElementById('idclick');
iframe.click()
this clicks an element id but throws undefined so I cannot process anything after iframe.click()
Why does it show undefined but yet clicks? Is it because I'm mixing jquery with javascript? If so, how would I write this either fully on jquery or js.
A solution with both jquery and js is + point, I'd like to see the difference.
ISSUE:
var iframe is undefined.
I'm making a Chrome Extension that changes the DOM of a page. But I would like to give the user an option to switch between the page before the changes and the changed page.
It's a little bit like Google translate where you can change between the orginal language and the translated message.
I could not find anything in my own searches.
I know JavaScript but not JQuery yet.
Thanks for the help.
You could save the entire body in a variable, then start overwriting things. If you want to switch back load up the old body.
You could save all the original DOM content to a variable before running the content script. You can do this by using the following code at the top of your content script:
var originalDOM = document.getElementsByTagName("*");
This saves the entire DOM in an array called originalDOM. The * acts a universal tag, requesting every tag in the document. You can read more about the .getElementsByTagName() API here.
You could try:
var html = document.getElementsByTagName("html")[0];
var page = html.innerHTML;
This will give you everything between the <html> tags.
After the content script is injected, run:
var newPage = html.innerHTML;
Now, whenever you want to switch between the pages, simply run:
html.innerHTML = page; //or newPage
You can read more about the .getElementsByTagName() API here
My code is as follows:
window.onload = initialise;
function initialise() {
var objPForSubmitMsg = document.createElement('p');
objPForSubmitMsg.setAttribute('class', 'submitmsg');
var arObjForms = document.getElementsByTagName('form');
for (i = 0; i < arObjForms.length; i++) {
var objFormParent = arObjForms[i].parentNode;
alert(objFormParent);
objFormParent.insertBefore(objPForSubmitMsg, arObjForms[i]);
}
} // end initialise().
I checked the function with alerts and it goes through.
When I "view-source" for the page after the function initialise() is done, there are no new elements added.
So my first question would be as per subject: can new elements inserted with javascript be seen with view-source?
If yes, then what is wrong with my code above? Why it doesn't insert new element?
I also tried to call initialise() from a button, but nothing happens then either.
I'm new to javascript so any comments would be appreciated.
EDIT: Thanks everyone. Ok, view-source cannot see it...
Than if I pass my page to php and load it with: $page = file_get_contents("mypage.html"); , if I echo that back with: echo $page; then I guess the newly created elements will not appear there either?
If that is the case, how would you pass the whole thing including the newly js created elements to php?
View Source in the browser shows you the original HTML source of the page - exactly what came from the server before any client side modifications have been made.
As such, it will NOT include any dynamic changes to the page made by javascript.
To see changes that have been made dynamically, use a DOM inspector. There is one built into Safari and Chrome and IE and Firebug is an add-on for Firefox. All will show you the entire DOM hierarchy, live exactly like it currently exists in the browser. In fact, you can even modify the live DOM yourself in the inspector.
Your current code is inserting an empty <p> tag which may not be visible because it's empty. If you put some content into the <p> tag, it successfully inserts one <p> tag into your page. It will only insert one because you only create one and then you try to insert the same tag before each form. You can see what your current code does here: http://jsfiddle.net/jfriend00/3fvbj7re/.
If you want a <p> tag inserted before each form in the page, you'd need to create a separate <p> tag for each insertion like this:
function initialise() {
var arObjForms = document.getElementsByTagName('form');
var objPForSubmitMsg;
for (i = 0; i < arObjForms.length; i++) {
objPForSubmitMsg = document.createElement('p');
objPForSubmitMsg.innerHTML = "hello"; // give tag some content
objPForSubmitMsg.setAttribute('class', 'submitmsg');
var objFormParent = arObjForms[i].parentNode;
objFormParent.insertBefore(objPForSubmitMsg, arObjForms[i]);
}
}
window.onload = initialise;
The Dom elements you add at runtime, were not present when the first time your page was loaded. In other words, it wasn't a part of your original page.
When you view source of your original page, it just shows the HTMl, without executing any JS or CSS, since you only explore HTMl in the source.
Hence, even when you add dynamic html elements in a page, you won't be able to see them when you click view source.
To see those elements, you should use the Developer Console of a browser.
If you want to see the current DOM you should use the code inspector (Developer Tools) or javascript console, not the source, which is what the original response body was.
In Chrome for example go to view->developer->developer tools
I would like to add that just because you can't see it with view-source, doesn't mean you can't access your newly created elements using document.getElementById('el-id') or something similar. Kinda off topic but it's important to note.
I generate some html content dynamically like:
var content = "<head><title>testtitle</title></head><body>testbody</body>";
Then I get myself a new tab with about:blank, and now I want to display my generated html in this tab. If the tab's contentDocument is newDoc, I thought I just do:
newDoc.documentElement.innerHTML = content;
However, that doesn't work. It seems to have no effect at all. In firebug it seems to work once but screws up firebug at the same time, so I can't verify, source view remains unchanged.
I then tried:
newDoc.getElementsByTagName("head")[0].innerHTML = headContent;
newDoc.body.innerHTML = bodyContent;
Which doesn't change the displayed empty page, also not in the source view, but if I alert newDoc.documentElement.innerHTML, it reflects the changes. It seems like this isn't the document that's displayed any more. Weird.
So my question: how do I do that? Specifically in a firefox extension, if that is important.
Is there maybe a href format with "text://..." instead of "file://..." or something?
Update:
It turns out that I can't only replace the full code this way, I can't even body.appendChild, but I'm sure I did that before, so I compared. Here I get my document this way:
var tab = getBrowser().addTab(); //make new tab
getBrowser().selectedTab = tab; //bring it to front
var browser = getBrowser().getBrowserForTab(tab); //get the window of the tab
var newDoc = browser.contentDocument;
Now I can do:
newDoc.location.href = url;
And this works, it loads the given page.
So I thought this is the correct document, but if I don't assign a url, but instead try to build the dom myself, it simply doesn't work.
If I do those changes to window.content.document after the tab is in front, it works. So how come these documents are different? If newDoc is the wrong one, how come assigning a location does anything?
Although I can get it to work now, I don't particularly like the solution of getting the document by bringing the tab to the front and then grabbing the window.content document, that feels like a hack and depends on timing.
I just found a nifty jQuery method that might accomplish this: http://api.jquery.com/html/#html2
I created a page with a button that calls the script:
$("html").html("<span>Hello <b>World</b></span>");
This replaces the entire page DOM.
I've created a JavaScript script that can be pasted on someone's page to create an iFrame. I would like for the person to be able to paste the script where they would like the iFrame to appear.
However, I can't figure out how to append the DOM created iFrame to the location where the script has been pasted. It always appends it to the very bottom of the body.
How do I append in place?
Mm. You could do:
document.write("<div id='iframecontainer'></div>");
document.getElementById('iframecontainer').innerHTML = '...';
But that feels ugly/wrong in a lot of different levels. I am not aware of any other alternatives, though.
EDIT: Actually, a quick google search revealed this artlcle which discusses why document.write is ugly and a nice alternative for the particular pickle you're in: Give your script tag an ID!
<script id="iframeinserter" src=".."></script>
And then you can get a reference to the script tag and insert the iframe before it:
var newcontent = document.createElement('iframe');
var scr = document.getElementById('iframeinserter');
scr.parentNode.insertBefore(newcontent, scr);
Paulo's answer can also be done without the ID, by simply looking for the last <script> element. This must be the script block we're in, because JavaScript guarantees all content past the closing tag of the current script block has not yet been parsed(*):
var scripts= document.getElementsByTagName('script');
var script= scripts[scripts.length-1];
script.parentNode.insertBefore(d, script);
This can be put in an onload/ready function if you like, but if so the ‘var script’ must be calculated at include-time and not in the ready function (when that executes, more <script>s will have been parsed).
(*: except in the case of <script defer>.)
If the user can give an id of an element that will be where the iframe should be, then it would be possible to just use css to move the iframe to where it should be on the page.