Using jQuery, one can easily find out whether a particular element is visible using
$(element).is(':visible')
While having some limitations (doesn't cover css visibility hidden or the actual visibility in the viewport, i.e. whether it's covered by other elements or scrolled away), I find it being useful for my scenario. The catch is, it only works within one iframe.
If the element has any parent within its document with display:none;, it returns false. If the whole document is included in an iframe which has display:none, it returns true. Is it possible to somehow detect this in another way ?
Hmm, seems like you have to call top (parent) document within an iframe, then search for specific iframe and check if it's visible.
You'll probably have to have same domain/subdomain for this to work, but anyway:
Let's assume you know iframe id/class (you have to).
if ($(top).find('#iframeID').is(':visible')) {
// iframe is visible
} else {
// iframe is NOT visible
}
Can't guarantee correct work.
Seems that the window's frameElement property works in all browsers and delivers the current iframe where the window is contained (if cross-domain restriction doesn't apply, which was my case).
not possible afaik. an iframe is basically a different site and as such guarded against xss. simply don't use iframes but server-side includes.
Related
I use an Iframe with an external API, which I don't control. My goal is to add Javascript code in my Website, to change the style of a few elements in the Iframe. First I considered using
document.getElementById(iframeId).contentWindow.document.getElementById(elementId);
but I soon recognized that it will not be successful because I am getting security issues. I tested a bit and found out when I inspect the element in the Iframe, which I want to change, I am able to get the element simply by using:
document.getElementById(elementId);
I don't understand. Why does this technique only work when I inspect the correct element first? And is there any way I can use this trick for my normal JS backend?
I have an iframe, inside which arbitrary content is served. I want to ensure content within the iframe is not accessible to screen readers, and specify what screen readers should read out when the iframe is selected.
My expectation is when tabbing through different elements on the page, myDiv is selected as a single unit, and it reads out Unknown content.
I tried the following
<div id="myDiv" title="Unknown content">
<iframe id="myIframe" aria-hidden="true">
{arbitraryContent}
</html>
</div>
Problems I face with this are
Not all content within the iframe are being ignored. Perhaps that is because aria-hidden does not work with focusable child elements.
Unknown text is not always being read, especially if the child elements are focusable.
I also tried setting tabIndex=-1 on the iframe. This however causes all the elements (including myDiv) to not be selectable by keyboard.
What is the right approach to achieve what I am looking for?
If you prevent the screen reader from reading the entire iframe and if it still has focusable elements, yes, you have a fatal accessibility problem:
you can focus something but the screen reader isn't allowed to tell what is focused. So what to do ? Should it say nothing, or go against what you have defined ?
Technically, it means that there shouldn't be any focusable element inside aria-hidden=true.
You must ensure that it never happens.
However, the good question you have to ask yourself is why do you want to completely hide what is in the iframe or in other words, explicitely make it totally unaccessible.
IF your fear is that contents out of your control could break the accessibility of your page, then
Administratively speaking, certifications based on WCAG complience know this problem and usually accept exceptions, i.e. don't take into account something you haven't control in.
Pratically speaking as a screen reader user, the badly accessible iframe will probably indeed give the impression that the whole accessibility of your site is bad in general, but it's still certainly better to have some partially accessible content rather than nothing at all.
You'd better remove the aria-hidden=true. Even if you know that it isn't very accessible, leave a chance to access a little of it no matter what, instead of blocking it definitely. Perhaps the accessibility of the content will improve over time.
The exception to this is if the content of the iframe is objectionnable, decorative, or doesn't bring any real information in the context of your page. Typical examples include ads and various kinds of widgets (weather, clock, social network share, etc.)
For those, go ahead, leave the aria-hidden=true and remove all focusable elements of the iframe. They are anyway just useless noise, without any regret if they are completely skipped.
I'm trying to capture where the user clicks on the hole page but from an iframe inside an iframe.
so basically I can control where the user clicks on the 1st iframe from the 2nd iframe, but can't control where he clicks on the root document.
I've tried nearly everything and can't find an answer.
Here is my actuall javascript:
$(window, window.parent.document).document.click(function( event ) {
alert(event.target.nodeName );
});
for context, I'm using shadowbox as iframes and my objective is to control when a user clicks outside of the shadowboxes
$(window).document in itself already returns undefined, you would need to de-reference the jQuery object first to get the "DOM version" of window, $(window)[0].document
But turns out you can simply use $(parent.document, parent.parent.document).click()
That also kinda seems to be the most straight forward way to me.
(Don't know why top.document did not work, because that is always the topmost window instance, so from within an iframe-inside-iframe that should be the same as parent.parent.document ... or are there even more (i)frames involved, another level? Anyway, as long as you got something that works it doesn't really matter.)
Is it possible to prevent iFrame element to get focus or if not, at least to return focus instantly to parent window once such iFrame gets focus? Please advise with code example.
It depends upon what you're really trying to accomplish and which focus methods you are trying to prevent. There's no magic setting you can set that prevents focus going to an iframe.
You can put a transparent element over the top of the iframe and have it capture all clicks so nothing in the iframe is clickable. You can likely just position this with CSS and wouldn't necessarily need javascript unless the iframe size is dynamic or not known in advance. This won't prevent javascript code from setting focus to the iframe, but will prevent mouse clicks from moving the focus to the iframe.
You can regularly check (javascript polling) where focus is and if it's not in your own document, then put it back in your document. This is kind of a hack.
Here's a demo of the first option: http://bit.ly/10jzdlp
If the problem that you're encountering is due to script in the iframe's document focusing one of its element, then one solution may be to use the iframe's sandbox attribute to prevent the iframe's document from running script (that is, setting the attribute to a value that does not contain the flag 'allow-scripts'). Whether that's acceptable will depend on whether it will break other things, of course.
I wanted it to work in an Iframe but if I define the js. in the parent document it does not recognize the elements that should be "introduced" inside the iframe. If I use it inside the iframe the effect is not what I expect (the overlay covers only the iframe).
[Intro.js being used inside an iframe.png] https://dl.dropboxusercontent.com/u/6421243/Intro.js%20being%20used%20inside%20an%20iframe.png
Is there something I can do with the plugin code so that it searches the elements inside an iframe but still shows the overlay over the parent?
UPDATE: I would like the black overlay over the WHOLE page (so the border of the iframe would also be covered by it).
Run intro.js in both iFrame and the parent.
In the parent, remove the toolTip and just highlight the iframe
In the iframe, run whatever toolTips you need
To communication between the two, have a look at this: How to communicate between iframe and the parent site?
First of all you should know that if you define your JavaScript codes outside of iframe, it's no longer available in the inner iframe because you don't have access to them.
So, you should put your codes inside the iframe only.
Update:
So I think you put the container element wrongly so the IntroJs define the overlay wrong wrongly too. Update and change your element container and then you will don't have any problem with that.