9

I got a warning by my ad system provider about click fraud. No further info, all they are recommending is "hide the ads for users who click on ads too quickly'". I wrote a piece of JS script that hides all DIVs with ads for N seconds (using cookie) when clicked on, but this solution does not work as the "inner" content (with ads) is generated by an JS script that calls and renders the content from external server (as you would expect from an ad system). So, when one takes the cross-domain security into account it is kinda Catch 22. How can I detect a click inside a DIV (locally defined) of which content is rendered by an external JS and in iframe?

Example:

<div class="ad-class"> <!-- locally defined div -->
   <div id="my-id"> </div> <!-- identifies my ad in the provider's system -->
   <script>
      var foo = blah // declares the ad dimensions and stuff
      //  and renders the contextual ad in #my-id DIV
   </script>
</div>

Were it all local, solution would be easy as the internal div would inherit the parent class ("ad-class"). In case of cross-domain, this is not valid. Any tips, dudes?

olaf
  • 151
  • 1
  • 1
  • 8
  • you can always detect the click on a `div` using the `onclick` event without caring what is inside the `div`. but you can check if the `div` `innerHTML` to see if the ad is loaded or it's empty and if the ad was loaded then run your script. – EhsanT Mar 30 '15 at 03:42
  • Hi EhsanT, I wish you were right but unfortunately the onclick does not work here. – olaf Mar 30 '15 at 17:15
  • Possible duplicate of [Detect Click into Iframe using JavaScript](https://stackoverflow.com/questions/2381336/detect-click-into-iframe-using-javascript) – Amir Ali Akbari Oct 17 '17 at 10:05

6 Answers6

11

You cannot detect click events in cross-domain iframe.

That put, you might have one bad option:

One of the nearest things you can do is detect that the focus moved from your window to the iframe:

window.focus(); //force focus on the currenct window;
window.addEventListener('blur', function(e){
    if(document.activeElement == document.querySelector('iframe'))
    {
        alert('Focus Left Current Window and Moved to Iframe / Possible click!');
    }
});

http://jsfiddle.net/wk1yv6q3/

However it's not reliable, loose focus does not mean a click, it could be user moving across the website using TAB.

Another problem is that, you only detect the first time focus is moved to the iframe, you do not know what user does in there, he can click a million times and you will never know.

Luizgrs
  • 4,765
  • 1
  • 22
  • 28
  • Thank you very much, Luizgrs. That is the best solution so far. The probability of ppl surfing the web site using TAB is very low. So is the probability of clicking on the ad text instead of the links. Like I said, after a click (or any interaction in this case) the ad divs get hidden, the time of such interaction in iframe is stored in a cookie. If a visitor keeps browsing the web site, the cookie is read again and ad divs will get displayed again after N seconds. – olaf Mar 30 '15 at 17:23
  • But yes, I find the ad provider's requirements kinda stupid. BTW, I wonder how one can protect Adsense divs from click fraud (I am not using Adsense now but been thinking of switching to it.) – olaf Mar 30 '15 at 17:28
  • This solution is not working in firefox's latest version. Any way to fix it? – Vivek Sancheti Dec 22 '15 at 10:05
  • Thanks for the inspiration, you might be interested to see my answer which is an upgrade of your. – AnonBird Feb 21 '17 at 17:06
10

Luizgrs inspired me this solution :

var clickIframe = window.setInterval(checkFocus, 100);
var i = 0;

function checkFocus() {
  if(document.activeElement == document.getElementById("ifr")) {
   console.log("clicked "+(i++));
   window.focus();
   }
}
<!DOCTYPE html>
<h2>Onclick event on iframe</h2>
<iframe src="https://www.brokenbrowser.com/" id="ifr"></iframe>

The function detect if the iframe has the focus, if yes, the user clicked into the iframe. We then give back the focus to our main windows, which allow us to find if the user click another time.

This trick has been usefull to me for a POC on a 2 step iframe click-jacking. Getting to know when the user clicked for the first time on the iframe allowed me to reorganize my different layers to keep the illusion perfect.

Community
  • 1
  • 1
AnonBird
  • 570
  • 13
  • 27
  • 1
    I was using a similar script for dynamic iframes and your window.focus was the missing piece I needed! Thanks for this. – eleytheria Nov 16 '20 at 22:52
1

The approach @Luizgrs pointed out is very accurate, however I managed to indeed detect the click event using a variation of the method:

var iframeMouseOver = false;
    $("YOUR_CONTAINER_ID")
        .off("mouseover.iframe").on("mouseover.iframe", function() {
            iframeMouseOver = true;
        })
        .off("mouseout.iframe").on("mouseout.iframe", function() {
            iframeMouseOver = false;
        });

    $(window).off("blur.iframe").on("blur.iframe", function() {
        if(iframeMouseOver){
            $j("#os_top").click();
        }
    });

The above code works like a charm on desktop if you want to add mobile support you just need to use touch events touchstartand touchendevents to simulate the mouseover on mobile.

Source

svelandiag
  • 4,231
  • 1
  • 36
  • 72
0

Well, a while ago I found this plugin for WordPress. Obviously it does what I need -- just wondering how this guy made it to work, it does count clicks on Adsense iframe. I must have a closer look though I am not a PHP programmer. I program mainly in Python and need some solution of this kind for Django. If anyone can read the code easily, I would appreciate any help.

olaf
  • 151
  • 1
  • 1
  • 8
0

The plugin is searching first for any iframe wrapped by a previous specified class name.

The iframe id´s will be collected in a array and for everyone of these id´s an mouseover event will be created which fires the script which hides the class 'cfmonitor'. As a result the iframe containing ad is not visible anymore.

// IFRAME ACTION
    function iframeAction () {
        jq.each(jq.cfmonitor.iframes, function(index,element) {
            frameID = jq(element).attr('id') || false;
            if (frameID) initiateIframe(frameID);
            //alert (frameID);
        });
    }

    // INIT IFRAME
    function initiateIframe(elementID) {
        var element = document.getElementById(elementID);
        // MOUSE IN && OUT
        if (element) {
            element.onmouseover = processMouseOver;
            element.onmouseout = processMouseOut;
            //console.log("mouse on out");
        }
        // CLICKS
        if (typeof window.attachEvent !== 'undefined') {
            top.attachEvent('onblur', processIFrameClick);
        }
        else if (typeof window.addEventListener !== 'undefined') {
            top.addEventListener('blur', processIFrameClick, false);
        }
}

// IFRAME CLICKS
    function processIFrameClick() {
        // ADD A CLICK
        if(isOverIFrame) {
            //addClick();
            // Some logic here to hide the class 'cfmonitor'
            //console.log("Go");
            top.focus();
        }
}
Rene Hermenau
  • 323
  • 1
  • 9
0

Check this it might help. You can not detect the click event when its cross browser.

window.focus();
window.addEventListener('blur', function(e){
  if(document.activeElement == document.getElementById('Your iframe id'))
   {
    console.log('iframe click!');
   }
});
Shagun1390
  • 35
  • 1
  • 8