I've got some simple html like below, and I need to access the SVG object in a JS script, and I'm having a horrible time of it.
<!DOCTYPE html>
<html>
<head>
<script src="../dist/svg-pan-zoom.js"></script>
</head>
<body>
<h1>Demo for svg-pan-zoom: SVG in HTML 'object' element</h1>
<object id="demo-tiger" type="image/svg+xml" data="tiger.svg" style="width: 500px; height: 500px; border:1px solid black; ">Your browser does not support SVG</object>
<script>
// Don't use window.onLoad like this in production, because it can only listen to one function.
window.onload = function() {
svgPanZoom('#demo-tiger', {
zoomEnabled: true,
controlIconsEnabled: true
});
};
</script>
</body>
</html>
Once this page loads, there is a new document with an svg tag within the object. I can select the object tag with document.querySelector("#demo-tiger"), that seems to work fine, but absoultely cannot get to the svg within it. i've tried contentDocument and getSVGDocument() and everything else i could think of. They all turn up null.
Any guidance would be greatly appriciated.
Unfortunately, this will not work if you load it locally through file://. This is because the contentDocument attribute is only accessible when both frames (main/top and the loaded one) are SameOrigin and the rules for file: uri's are stricter than normal urls for security reasons. You can find more information on this here: What is the Same-Origin Policy for File URIs?
Related
Is there a way to determine from inside of a cross-domain iframe if the iframe is in view or not?
I was trying to achieve this using Intersection Observer API. But it seems to work only for same-domain iframe and not cross-domain. I checked the Intersection Observer API documentation(both on MDN and W3C), but couldn't find anything related to this. I hope I'm not missing anything here.
Here is the example code
Main Html Page
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Main Page</title>
</head>
<body>
<div style="margin:700px auto;text-align:center;">
<iframe marginwidth="0" marginheight="0" frameborder="0" height="250px" width="300px"
id="aax_if_aax_sidebar-btf-1" allowtransparency="true" src="http://127.0.0.1:8080/iframe.html"></iframe>
</div>
</body>
</html>
Embedded Iframe Page
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Iframe</title>
</head>
<body>
<div id="abc" style="background-color: black;width:100%;height: 100%;"></div>
<script>
setupIntersectionObserver = function (adContainer) {
console.log('setting up observer', observer);
var observer = new IntersectionObserver(
function (entries) {
console.log('observer triggered', entries);
},
{
root: null,
rootMargin: '10px',
threshold: 0
}
);
observer.observe(adContainer);
};
setupIntersectionObserver(document.getElementById('abc'))
</script>
</body>
</html>
If I run the main page locally, then the intersection observer inside the iframe works only if the page is browsed using 127.0.0.1:8080, and not for localhost:8080 (cross-domain)
Does Intersection Observer works from inside of a cross-domain iframe, with respect to the viewport?
I do not believe that there are any restrictions on cross-origin IntersectionObservers, however in my understanding they should have no explicit root set. In your case that would mean removing root: null from IntersectionObserver's configuration in the sub-frame.
It is important to note however, that your specified rootMargin value will not take effect in the cross-origin case as per the W3C it is only applied "for targets which belong to the same unit of related similar-origin browsing contexts".
You might also need to explicitly switch your JavaScript context in dev tools to the sub-frame to see the log message. Example in Chrome Dev Tools.
This use case is supported by WebKit & Blink for sure, because they have automated testing specifically for cross-origin IntersectionObserver: main frame page, sub-frame page
EDIT:
I found out that the problem has to do with not having access to the elements inside an iframe without a specific API or something like that. It has been solved.
I need to embed the image of the Astronomy Picture of the Day website. Here is the html that I have now:
<head>
<style>
body, html {
margin: 0px;
padding: 0px;
}
iframe {
border: none;
}
</style>
</head>
<body>
<iframe id="iframe" width="100%" height="600px"
src="https://apod.nasa.gov/apod/astropix.html"></iframe>
<div id="PlaceToPutTable"></div>
<script src="panel.js"></script>
</body>
Here is the JavaScript that I have now:
var iframe = document.getElementById("iframe");
var div = document.getElementById("PlaceToPutTable");
div.innerHTML =
iframe.contentWindow.document.getElementsByTagName("a")[1];
I have tried using iframe.contentWindow.document.getElementByTagName("img")[0] with and without .innerHTML following it.
I am using this as an Opera Sidebar Extension, so I keep getting this error when adding .innerHTML: Uncaught type error: cannot read property 'innerHTML' of undifined.
I got this code by manipulating the code I got at this answer, but the Astronomy Picture of the Day image does not include an id.
The undefined property indicates that a variable has not been assigned
a value.
You are not getting anything from there.
I would suggest you to debug a bit your code. First of all it seems like this is not getting anything iframe.contentWindow.document.getElementsByTagName("a")[1] so you should first debug it to see if it contains the element you are looking for.
So you should debug with a console log and see what this gets:
console.log(iframe.contentWindow.document.getElementsByTagName("img"));
Hope this helps you out.
I need to load an html page inside a div in the following pseudo page:
<html>
<head></head>
<style>
body {
background-color: yellow;
}
</style>
<body>
<div style="display:none">
<html>
<head></head>
<style>
body {
background-color: blue;
}
</style>
<body>
<div style="display:none">
...
</div>
</body>
</html>
</div>
</body>
</html>
What naturally happens in this code is that the background will turn blue, as it is being changed in the middle of the page. Is there a way to isolate this div? So it would act similarly to an iframe. The content inside the div is stored in a variable, so I think I cannot use a frame, as the html code is not stored in a file to use it as a source.
Thank you!
This is just wrong.
An HTML document can only have one html tag and one body tag, otherwise it will be an invalid document, browsers won't allow it.
If you load an iframe, instead, it will have his own #document and it's fine.
You can not load a Site into a Site without an Iframe due to security risks.
The only thing you can do, is to load the external Site with a serverside script like php, cut of the head with regexp and send the rest to your site into your div.
I have a JavaScript code that I got from the site: http://www.micahcarrick.com/change-image-with-jquery.html I only modified the name of the images as to use .png files I have. The issue is if I open this in a web browser locally, then when I click on one of thumbnails called django.gif I am directed to the actual image rather then the new image replacing the other. However, if I put this .html script on a Godaddy.com website and go to it with the same web browser it does work correctly just like the original site: http://www.micahcarrick.com/code/jquery-image-swap/index.html . I notice that at the site I got this code from the author mentions that "The thumbnails are links to full size versions of the images. If a user does not have JavaScript, the links still go to the large image." Does this mean I don't have Java Script? I can run other simple JavaScript codes locally. Why does this work when I put it on a site, but does not work when testing locally, even when using the exact same web browser? Here is the code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Example: Change Image with jQuery</title>
<style type="text/css">
body { width: 600px; margin: auto; }
#imageWrap {
width: 640px;
height: 420px;
background: url('ajax-loader.gif') center center no-repeat;
}
</style>
<script type="text/javascript"
src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('.thumbnail').live("click", function() {
$('#mainImage').hide();
$('#imageWrap').css('background-image', "url('ajax-loader.gif')");
var i = $('<img />').attr('src',this.href).load(function() {
$('#mainImage').attr('src', i.attr('src'));
$('#imageWrap').css('background-image', 'none');
$('#mainImage').fadeIn();
});
return false;
});
});
</script>
</head>
<body>
<h1>Example: Change Image with jQuery</h1>
<p>
Main image is replaced using jQuery when a thumbnail is clicked. See full
description at <a
href="http://www.micahcarrick.com/change-image-with-jquery.html">Change
Image with jQuery</a>
</p>
<a href="bidu.png" class="thumbnail"><img src="django.gif"
alt="Image 1"/></a>
<a href="athex.png" class="thumbnail"><img src="django.gif"
alt="Thumbnail 2"/></a>
<div id="imageWrap">
<img src="bidu.png" alt="Main Image" id="mainImage"/>
</div>
</body>
</html>
Thank you,
Tom
This line right here is what's causing your issues:
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
The "//" before the URL tells the browser to use the same protocol as the page is, and when running locally, the protocol is going to be "file:" which the browser will use to look into your local drive to find the jquery library (which it won't find, thus breaking the page). To fix this, prepend "http:" or "https:" to the URL so it looks like
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
I see two problems.
1. Your script tag src attribute for jQuery will not locate the correct resource. Running locally, this syntax (//ajax...) will resolve as file:///ajax.googleapis.com/..., which is not where jQuery is. Try putting a http:// or https:// in front of it.
2. You're using a deprecated jQuery function. .live() is not in version 1.6.2 - you need to use .on() instead, like so:
$(".thumbnail").on("click",function() { ... });
That should work.
Hope this helps.
change the src of the script tag to include the http: protocol
src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"
<script type="text/javascript">
function printDoc() {
document.getElementById("frame_singleCheque").contentWindow.print();
}
</script>
<iframe style ="height:400px; width: 750px; overflow:scroll;" id="frame_singleCheque" src="http://www.w3schools.com"></iframe>
<input type="button" id = "btnCPrint" value = "Print" onclick="javascript:printDoc()" />
Error
[16:41:44.054] Error: Permission denied to access property 'print' # http://localhost/pdf/print.php:3
i have verified with lot of stack suggested threads for print iframe content. but for me those are not worked.
Exactly above code only present in my print.php file. i want to print the iframe content.
Also i want to know, how to print the specific div which is present inside the iframe. example in this iframe " class = 'example_code notranslate' " .
You can print a cross-domain iframe page perfectly by nesting the cross domain iframe in a locally hosted iframe. A "proxy iframe".
This way the parent javascript can print the proxy iframe without issue since it's local, which will transitively print it's inner iframe originating from another domain.
This technique works and has been verified by myself.
In your container page, host the iframe like this
<iframe id="printf" name="printf" class="A4" src="/SomeController/IFrameProxy?url=TARGETURL"></iframe>
The proxy iframe should look like something like this
#model string
<html>
<head>
<title>IFrame Proxy</title>
<style>
html, body, iframe {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
border-style: none;
}
</style>
</head>
<body>
<iframe src="#Model" seamless></iframe>
</body>
</html>
The javascript that prints the iframe (defined on container page) should look something like this:
function printFrame() {
var frm = document.getElementById("printf").contentWindow;
frm.focus();// focus on contentWindow is needed on some ie versions
frm.print();
}
It look like you've got a pretty standard cross-domain iframe issue here - namely that browsers are designed so you can't do this. There's a lot of fudges I could suggest, but largely, iframes are the wrong solution to this problem.
Basically, your best bet is to scrape the page - make a http request and parse out the content you want. Then you can interact with it as part of your own page's DOM.
How do I print an IFrame from javascript in Safari/Chrome
Print iFrame Content (#5)
Print contents of IFRAME from parent window