61

I have an iframe on a page, coming from a 3rd party (an ad). I'd like to fire a click event when that iframe is clicked in (to record some in-house stats). Something like:

$('#iframe_id').click(function() {
    //run function that records clicks
});

..based on HTML of:

<iframe id="iframe_id" src="http://something.com"></iframe>

I can't seem to get any variation of this to work. Thoughts?

13 Answers 13

40

There's no 'onclick' event for an iframe, but you can try to catch the click event of the document in the iframe:

document.getElementById("iframe_id").contentWindow.document.body.onclick = 
function() {
  alert("iframe clicked");
}

EDIT Though this doesn't solve your cross site problem, FYI jQuery has been updated to play well with iFrames:

$('#iframe_id').on('click', function(event) { });

Update 1/2015 The link to the iframe explanation has been removed as it's no longer available.

Note The code above will not work if the iframe is from different domain than the host page. You can still try to use hacks mentioned in comments.

Sign up to request clarification or add additional context in comments.

9 Comments

Thanks, this works nicely, but only for content from my domain. If I try to load in 3rd party content from another domain, the click event doesn't fire. I've ran into some other posts on the web mentioning something similar...basically, you can play with iframe content, but only if its your own. I would definitely be dealing with only 3rd party content. Hmm, any other ideas?
Yes, actually. Try putting a transparent div on top of the iframe (use position: absolute). You can then catch clicks on that div. Don't forget to pass them down to the iframe (works only if it's a simple iframe content - if it contains its own even handling - don't use this method).
Just to update: I've tried the absolute positioning, and all events were ignored if there was 3rd party content in the iframe. I don't think this one is going to happen, but I greatly appreciate the fact that you put forth some help.
No problem - that's what we're here for :) Sorry it didn't work out.
Archive.org is our friend. ;^) Archived blog link
|
19

I was trying to find a better answer that was more standalone, so I started to think about how JQuery does events and custom events. Since click (from JQuery) is just any event, I thought that all I had to do was trigger the event given that the iframe's content has been clicked on. Thus, this was my solution

$(document).ready(function () {
    $("iframe").each(function () {
        //Using closures to capture each one
        var iframe = $(this);
        iframe.on("load", function () { //Make sure it is fully loaded
            iframe.contents().click(function (event) {
                iframe.trigger("click");
            });
        });

        iframe.click(function () {
            //Handle what you need it to do
        });
    });
});

1 Comment

It works only if the frame contains page from the same domain (does not violate same-origin policy)
16

Try using this : iframeTracker jQuery Plugin, like that :

jQuery(document).ready(function($){
    $('.iframe_wrap iframe').iframeTracker({
        blurCallback: function(){
            // Do something when iframe is clicked (like firing an XHR request)
        }
    });
});

1 Comment

The only thing helped me to catch click event on embedded Youtube iframe. Thanks!
9

It works only if the frame contains page from the same domain (does not violate same-origin policy)

See this:

var iframe = $('#your_iframe').contents();

iframe.find('your_clicable_item').click(function(event){
   console.log('work fine');
});

4 Comments

Add some explanation with answer for how this answer help OP in fixing current issue
change 'your_clicable_item' with 'body' and this is the perfect answer
It works only if the frame contains page from the same domain (does not violate same-origin policy)
This worked for me but I had to stuff it inside a function and then call it after the DOM loaded and the iFrame loaded. Thanks @jhonatan2760
7

You could simulate a focus/click event by having something like the following. (adapted from $(window).blur event affecting Iframe)

$(window).blur(function () {
  // check focus
  if ($('iframe').is(':focus')) {
    console.log("iframe focused");
    $(document.activeElement).trigger("focus");// Could trigger click event instead
  }
  else {
    console.log("iframe unfocused");
  }                
});

//Test
$('#iframe_id').on('focus', function(e){
  console.log(e);
  console.log("hello im focused");
})

1 Comment

I was able to stop web page audio playback for a YouTube video click by switching the 'focus' to 'click' as you stated.
2

None of the suggested answers worked for me. I solved a similar case the following way:

<a href="http://my-target-url.com" id="iframe-wrapper"></a>
<iframe id="iframe_id" src="http://something.com" allowtrancparency="yes" frameborder="o"></iframe>

The css (of course exact positioning should change according to the app requirements):

#iframe-wrapper, iframe#iframe_id {
  width: 162px;
  border: none;
  height: 21px;
  position: absolute;
  top: 3px;
  left: 398px;
}
#alerts-wrapper {
  z-index: 1000;
}

Of course now you can catch any event on the iframe-wrapper.

2 Comments

This will prevent all clicks from registering in the iframe.
You are right. It will route all clicks to the iframe-wrapper element. This works for me because in my case the iframe has no interactive elements, I need it just for display.
1

You can use this code to bind click an element which is in iframe.

jQuery('.class_in_iframe',jQuery('[id="id_of_iframe"]')[0].contentWindow.document.body).on('click',function(){	
	console.log("triggered !!")
});

Comments

1

This will allow you to target a specfic element in the iframe such as button or text fields or practically anything as on method allows you to put selector as an argument

$(window).load(function(){
    $("#ifameid").contents().on('click' , 'form input' , function(){
            console.log(this);
    });
});

Comments

0

Maybe somewhat old but this could probably be useful for people trying to deal with same-domain-policy.

let isOverIframe = null;
$('iframe').hover(function() {
        isOverIframe = true;
    }, function() {
        isOverIframe = false;
    });

$(window).on('blur', function() {
    if(!isOverIframe)
        return;

    // ...
});

Based on https://gist.github.com/jaydson/1780598

Comments

0

You may run into some timing issues depending on when you bind the click event but it will bind the event to the correct window/document. You would probably get better results actually binding to the iframe window though. You could do that like this:

    var iframeWin = $('iframe')[0].contentWindow;
    iframeWin.name = 'iframe';
    $(iframeWin).bind('click', function(event) {
        //Do something
        alert( this.name + ' is now loaded' );
    });

Comments

-1

This may be interesting for ppl using Primefaces (which uses CLEditor):

document.getElementById('form:somecontainer:editor')
.getElementsByTagName('iframe')[0].contentWindow
.document.onclick = function(){//do something}

I basically just took the answer from Travelling Tech Guy and changed the selection a bit .. ;)

Comments

-1

Solution that work for me :

var editorInstance = CKEDITOR.instances[this.editorId];

            editorInstance.on('focus', function(e) {

                console.log("tadaaa");

            });

Comments

-3

You can solve it very easily, just wrap that iframe in wrapper, and track clicks on it.

Like this:

<div id="iframe_id_wrapper"> <iframe id="iframe_id" src="http://something.com"></iframe> </div>

And disable pointer events on iframe itself.

#iframe_id { pointer-events: none; }

After this changes your code will work like expected.

$('#iframe_id_wrapper').click(function() { //run function that records clicks });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.