When the user clicks on an external iframe, all event listeners on my BODY tag stop working and I need to prompt the user to click outside to regain the "focus" on the body tag.
But knowing when the user clicks on an iframe is actually very hard.
I know of two ways to know when there is a click on an iframe:
1- Overlapping a transparent div on the iframe (with the downside that the user has to click twice to actually click the iframe).
2- A very rough workaround which is having an input autofocused all the time and detect when it loses focus. But it's just stupid to even consider implementing it.
Is there another way to know when the user "loses focus" of the main body by clicking on an external iframe?
This is super easy, but not necessarily effecient/ethical.
setTimeout(function(){
document.body.focus()
}, 100 );
I would in all honesty use option #2 with some jQuery.
$(el).focusout(function(){
$(this).focus();
})
The easiest method and the only one I'm aware of actually is to make an infinite loop that gets current focused element.id.
Then it's simply a matter of comparing that id with your iframes to know which has been clicked.
Note that you will only be able to know for sure the user clicked once in the iframe, but there is no way to count clicks afterwards. Also notes that iframes can focus themselves with this method will be indistinguishable from a click.
Related
I've got dialog that I wrote and it closes when clicking outside (no overlay/backdrop).
It works nicely unless there's an iframe, in which case my listener on outside clicks is never called.
Here is a JSBIN to illustrate the problem. (http://jsbin.com/vuneyopedu/edit?js,console,output)
To briefly explain in the below screenshot:
Clicking RED Dialog Increments.
Clicking Outside Dialog (YELLOW and GREEN) should Decrement but only YELLOW works.
The event listener for outside clicks is never called when clicking iframe (GREEN)
Question is - How do I make clicking anything outside the RED square (specifically clicking the iframe) decrement the number. (or close the dialog, in the "real" world)
How about binding event to iframes' document.
iframes = document.getElementsByTagName('iframe');
iframesArray = Array.prototype.slice.apply(iframes);
iframesArray.forEach(function(frame) {
frame.contentWindow.document.addEventListener('click', function() {
inc();
}, true);
});
The correct approach here is to use a modal and one of the strongest use-cases for the modal. By design modals prevent clicks from falling through to elements below hence there is no need to handle side effects like your iframe issue or e.stopPropagation() or anything else. It also makes positioning very clean.
As a side note, the currently accepted answer is a very poor approach since it relies on adding an event handler inside the iFrame, then binding that onto the parent container window. This is wrong on many levels: no separation of concerns, iframe from different domains will be blocked due to CORS, iframe will register with any and all parents even when not needed, etc.
I am trying to make a page COMPLETELY UNCLICKABLE (both right click and left click) and to display a message when someone clicks. Since I know that this will raise lots of questions such as
"why would anyone ever want to do this...this is stupid...then nobody
can navigate the site...and it doesn't protect your content
anyway...etc"
here is the explanation of my purpose. I have a page that is at the moment only a graphic mockup of what the finished website will eventually look like. No matter how many times I explain that the mockup is ONLY AN IMAGE and not a real navigable website, they still email me to say that they cannot click on the menus and links. Since it is a single page mockup, I want to pop up an alert() message (can't use a modal because you can't click to dismiss it if clicking is disabled) to let them know that they have clicked something non-functional. I am trying to do this in as few lines of code as possible, and have the following working at the moment:
<script>
$('html').mousedown(function(event) {
event.preventDefault();//To prevent following the link
alert('Demo Graphic Only...clicking on stuff will NOT work at this point.');
});
</script>
The issue is that when using .mousedown I capture the user trying to click on the browser scroll-bar to scroll down. I was surprised by this since it is not part of the actual PAGE CONTENT but rather a part of the BROWSER...but it is catching it nonetheless. I tried using .click in place of .mousedown however only seem to catch a normal (left) click in that case... Does anyone know how to easily (minimal lines of code if possible) capture the left AND right click event, but allow user interaction with the browser scrollbar?
Try this :
$(document).click(function(event) {
event.preventDefault();//To prevent following the link
console.log('Demo Graphic Only...clicking on stuff will NOT work at this point.');
});
This Function will be called when click is made on the page , not on the Scrollbars
Try to use
event.stopPropagation();
or
event.stopImmediatePropagation()
For people who come across this question, an alternative approach, good especially if you need to prevent mousedown specifically:
Put the scrolling content in a wrapper element and prevent mousedown only on the inner element. Set the wrapper element to overflow: auto; height: 100%;
Suppose I have a link, which would fade out the entire page when link is clicked. The reason I fade out the page is because a next page is about to load, but it is not loaded yet. I can use pointer-events: none which will disable any mouse events until the next page is loaded.
Suppose it was done with the keyboard, I could use the following to prevent double-enter, or to cleanly disable all elements within, for example tab-enter would be disabled this way as well.
parent.onkeydown = fals
parent.onkeyup = fals
parent.onkeypress = fals
function fals() {return false}
This works well for short loads, but if it takes a long time to load, the user may notice the following difficulties.
Cannot tab away from the a tag.
Cannot use several of the keyboard shortcuts which would control the browser.
Able to tab into the disabled area from the address bar.
Is there a modern and slick way to prevent these 3 problems, other than setting an onfocus=blur for all of the child elements? I do not care about IE today.
I think the commonly accepted way of dealing with things like what you're talking about is to use Modal's, which is to say when they click that link, you pop up a box that says 'Processing' or something like that, and you create a fullscreen div with a z-index above everything else so the user can't click / interact with anything else on the screen until you're done doing whatever it is you are doing.
See http://twitter.github.com/bootstrap/javascript.html#modals for an example of what i'm talking about.
I've got a browser plug-in I'm working on and I want it to behave a certain way when the user clicks things. Not limited to, but including, a behavior for links!
The problem is that the plug-in has to work for a wide variety of sites, and some of those sites use the dreaded pseudo-protocol such as:
Show Element
Currently my behavior is added to the anchor tag via
anchor.addEventListener('click', superAwesomeFunction);
Unfortunately this has a problem where the click listener only fires once. If I preventDefault() of course the click listener sticks around, but I've now broken the host site! Otherwise, clicking the link fires the click listener but only on the first click. I'm wondering why my superAwesomeFunction() doesn't fire again if the link is clicked a second time. Is href="javascript:things()" doing more than I know?
It is possible to add an event listener to a link that has a JavaScript function call set in the href attribute.
Here's a jsFiddle that shows it working. Both functions fire each time the link is clicked.
There must be something else going on with your code beyond what we can see in what you gave us.
If you must wait user some time and going on url then, you may add some code to your superAwesomeFunction's process end:
document.location.href = $(this).attr("href");
I'm trying to know when an user clicks on an iframe with external content (a page not owned by me). The reason I need to do it is that my site relies heavily on keyboard navigation and when the iframe is focused I need to tell users to click outside to keep playing.
I'm using a transparent div on on top of the iframe with an onmousedown event. But it's not a great choice since the user needs to click once for the div to disappear and once again to click wherever they want on the iframe.
Are there are other ways to know when the user clicks on the iframe?
Thanks
The closest I can think of is to listen for blur on your window.
http://www.quirksmode.org/dom/events/blurfocus.html
I would put an onmousedown event on the iframe instead of the div?
you could find a way around this problem. But personally, I don't think its a good practice to capture events in an IFrame from an External Container.