Deteksi Klik ke Iframe menggunakan JavaScript

128

Saya mengerti bahwa tidak mungkin memberi tahu apa yang dilakukan pengguna di dalam iframejika domain lintas. Yang ingin saya lakukan adalah melacak jika pengguna mengklik sama sekali di iframe. Saya membayangkan sebuah skenario di mana ada yang tidak terlihat divdi atas iframedan divkemudian hanya akan melewati acara klik ke iframe.

Apakah hal seperti ini mungkin? Jika ya, lalu bagaimana saya melakukannya? The iframesadalah iklan, jadi saya tidak memiliki kontrol atas tag yang digunakan.

Russ Bradberry
sumber
4
Itu mungkin dan ada solusi crossbrowser: stackoverflow.com/a/32138108/1064513
Dmitry Kochin

Jawaban:

39

Apakah hal seperti ini mungkin?

Tidak. Yang dapat Anda lakukan adalah mendeteksi mouse yang masuk ke iframe, dan berpotensi (meskipun tidak andal) ketika keluar kembali (mis. Mencoba mencari tahu perbedaan antara penunjuk yang melewati iklan dalam perjalanannya di tempat lain versus bertahan lama di iklan).

Saya membayangkan sebuah skenario di mana ada div yang tidak terlihat di atas iframe dan div kemudian akan meneruskan acara klik ke iframe.

Tidak, tidak ada cara untuk memalsukan acara klik.

Dengan menangkap mousedown Anda akan mencegah klik asli untuk membuka iframe. Jika Anda dapat menentukan kapan tombol mouse akan ditekan, Anda bisa mencoba mengeluarkan div yang tidak terlihat sehingga klik akan melewati ... tetapi juga tidak ada peristiwa yang terjadi tepat sebelum mousedown.

Anda dapat mencoba menebak, misalnya dengan melihat apakah penunjuk telah berhenti, menebak klik yang akan datang. Tapi itu sama sekali tidak bisa diandalkan, dan jika Anda gagal, Anda baru saja kehilangan diri Anda melalui klik-tayang.

bobince
sumber
4
Ya itu. Dan ada solusi crossbrowser: stackoverflow.com/a/32138108/1064513
Dmitry Kochin
1
Saya memeriksa tautan ini dan saya kira jawabannya benar. Anda hanya dapat mendeteksi klik di dalam iframe tetapi tidak apa yang diklik.
user568021
Saya downvote, hanya karena itu tidak sepenuhnya benar. Sebagian besar dari apa yang Anda katakan adalah benar, tetapi ada solusi seperti jawaban yang lebih populer di utas ini.
newms87
154

Ini tentu saja mungkin. Ini berfungsi di Chrome, Firefox, dan IE 11 (dan mungkin yang lain).

focus();
var listener = window.addEventListener('blur', function() {
    if (document.activeElement === document.getElementById('iframe')) {
        // clicked
    }
    window.removeEventListener('blur', listener);
});

JSFiddle


Peringatan: Ini hanya mendeteksi klik pertama. Seperti yang saya mengerti, itu yang Anda inginkan.

Paul Draper
sumber
1
@the_joric, itu karena 4 tahun setelah pertanyaan, dan orang-orang biasanya tidak menggulir melewati jawaban pasangan pertama.
Paul Draper
3
Yang juga perlu diperhatikan adalah bahwa jika Anda mengubah tab browser, itu akan mengaktifkan fokus ();
Linnay
7
Tidak berfungsi di Firefox. JSFiddle berisi kesalahan yang menyembunyikan ini: = bukannya ===. Ada solusi crossbrowser (bahkan di IE8): stackoverflow.com/a/32138108/1064513
Dmitry Kochin
8
Acara blur tidak menyala jika pengguna tidak mengklik dokumen utama terlebih dahulu! Selain itu, ini tidak dapat digunakan untuk mendeteksi klik pada banyak iframe, karena tidak ada kejadian yang menyala ketika fokus berubah dari satu iframe ke yang lain ( bluracara iframe tidak menyala).
Tomáš Kafka
1
mengapa ada ketergantungan pada fokus ();
Prasad Shinde
107

Berdasarkan jawaban Mohammed Radwan saya datang dengan solusi jQuery berikut. Pada dasarnya yang dilakukannya adalah melacak apa yang orang iFrame hovering. Kemudian jika jendela mengaburkan itu kemungkinan besar berarti pengguna mengklik spanduk iframe.

iframe harus diletakkan di div dengan id, untuk memastikan Anda tahu iframe mana yang diklik pengguna:

<div class='banner' bannerid='yyy'>
    <iframe src='http://somedomain.com/whatever.html'></iframe>
<div>

begitu:

$(document).ready( function() {
    var overiFrame = -1;
    $('iframe').hover( function() {
        overiFrame = $(this).closest('.banner').attr('bannerid');
    }, function() {
        overiFrame = -1
    });

... ini membuat iFrame tetap di -1 saat tidak ada iFrame yang melayang-layang, atau 'bannerid' yang diatur dalam div pembungkus ketika iframe melayang-layang. Yang harus Anda lakukan adalah memeriksa apakah 'overiFrame' diatur ketika jendela kabur, seperti: ...

    $(window).blur( function() {
        if( overiFrame != -1 )
            $.post('log.php', {id:overiFrame}); /* example, do your stats here */
    });
});

Solusi yang sangat elegan dengan kelemahan minor: jika pengguna menekan ALT-F4 saat mengarahkan mouse ke atas iFrame, itu akan mencatatnya sebagai klik. Ini hanya terjadi di FireFox, IE, Chrome dan Safari tidak mendaftarkannya.

Terima kasih sekali lagi Mohammed, solusi yang sangat berguna!

patrick
sumber
Saya telah memberi +1 jawaban ini, walaupun, memiliki masalah berikut: 1. Ketika ada beberapa iframe, Anda mengklik salah satunya, lalu langsung pada yang lain - klik kedua tidak terdeteksi. 2. Banyak klik di dalam iframe juga tidak dihitung. 3. Tidak berfungsi dengan benar di ponsel, karena Anda tidak bisa melakukan "hover" acara dengan jari.
Sych
Skrip di atas digunakan oleh saya untuk mendeteksi klik dari situs saya. Sebagian besar jaringan periklanan sekarang melayani spanduk dalam bingkai. Jika Anda mengklik satu dan kemudian dengan cepat satu lagi sebelum Anda pergi pada klik pertama, secara teknis saya ingin tahu klik terakhir yang sebenarnya Anda tinggalkan. Jadi dalam kasus saya itu perilaku yang diinginkan. Itu mendeteksi dengan baik klik pada spanduk seluler juga. Jadi hover harus diluncurkan tepat sebelum klik dijalankan
patrick
Tidak berfungsi jika elemen svg dalam konten iframe :( stackoverflow.com/questions/32589735/…
Serhiy
@ Serhiy, itu karena Anda tidak benar-benar keluar dari halaman asli ketika mengklik iframe ...
patrick
6
Jawaban ini adalah yang terbaik dari mereka, namun, jika Anda ingin menerima setiap klik ke dalam iframe, Anda harus mengambil fokus darinya setelah pengguna mengklik untuk memantau klik lebih lanjut. Ini harus ditambahkan ke bagian $ (window) .blur (): setTimeout(function(){ window.focus(); }, 0);. Sekarang, pengguna mengklik, menempatkan fokus di iframe, skrip menarik fokus itu kembali, dan sekarang dapat memantau perubahan fokus lebih lanjut dari klik di masa depan.
HelpingHand
89

Ini adalah solusi kecil yang bekerja di semua browser bahkan IE8:

var monitor = setInterval(function(){
    var elem = document.activeElement;
    if(elem && elem.tagName == 'IFRAME'){
        clearInterval(monitor);
        alert('clicked!');
    }
}, 100);

Anda dapat mengujinya di sini: http://jsfiddle.net/oqjgzsm0/

Dmitry Kochin
sumber
1
Bagaimana jika Anda memiliki beberapa iframe dan Anda tidak tahu id mereka?
shankshera
1
hanya solusi andal lintas-browser yang juga berfungsi di FF terbaru! Terima kasih banyak. Itu layak mendapatkan lebih banyak upvotes
BrainOverflow
6
@shankshera Baru saja dapatkan elem.id, itu id iframe Anda :). Lihat jsfiddle.net/oqjgzsm0/219
Tomáš Kafka
1
Saya menggunakan ini untuk melacak klik pada tombol suka sosial. Tetapi karena 3/4 dari yang saya gunakan menggunakan iframe, saya perlu melacak klik di banyak iframe. Saya telah memperbarui biola untuk memungkinkan untuk itu: jsfiddle.net/oqjgzsm0/273 . Ini menetapkan interval baru yang memeriksa untuk melihat apakah klik di luar iframe yang terakhir diklik. Kemudian reset interval asli untuk memeriksa klik lagi. Itu tidak melacak beberapa klik di iframe yang sama tanpa klik di luar itu.
brouxhaha
14
Terlepas dari kenyataan bahwa menggunakan interval perulangan terus-menerus pada tingkat seperti itu bukanlah ide yang sangat baik, ini akan mendeteksi positif palsu jika pengguna menetapkan fokus pada iframe melalui navigasi tombol tab
Kaiido
36

Kode berikut akan menunjukkan kepada Anda jika pengguna mengklik / mengarahkan atau keluar dari iframe: -

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Detect IFrame Clicks</title>
<script type="text/javascript">
    $(document).ready(function() {
        var isOverIFrame = false;

        function processMouseOut() {
            log("IFrame mouse >> OUT << detected.");
            isOverIFrame = false;
            top.focus();
        }

        function processMouseOver() {
            log("IFrame mouse >> OVER << detected.");
            isOverIFrame = true;
        }

        function processIFrameClick() {
            if(isOverIFrame) {
                // replace with your function
                log("IFrame >> CLICK << detected. ");
            }
        }

        function log(message) {
            var console = document.getElementById("console");
            var text = console.value;
            text = text + message + "\n";
            console.value = text;
        }

        function attachOnloadEvent(func, obj) {
            if(typeof window.addEventListener != 'undefined') {
                window.addEventListener('load', func, false);
            } else if (typeof document.addEventListener != 'undefined') {
                document.addEventListener('load', func, false);
            } else if (typeof window.attachEvent != 'undefined') {
                window.attachEvent('onload', func);
            } else {
                if (typeof window.onload == 'function') {
                    var oldonload = onload;
                    window.onload = function() {
                        oldonload();
                        func();
                    };
                } else {
                    window.onload = func;
                }
            }
        }

        function init() {
            var element = document.getElementsByTagName("iframe");
            for (var i=0; i<element.length; i++) {
                element[i].onmouseover = processMouseOver;
                element[i].onmouseout = processMouseOut;
            }
            if (typeof window.attachEvent != 'undefined') {
                top.attachEvent('onblur', processIFrameClick);
            }
            else if (typeof window.addEventListener != 'undefined') {
                top.addEventListener('blur', processIFrameClick, false);
            }
        }

        attachOnloadEvent(init);
    });
</script>
</head>
<body>
<iframe src="www.google.com" width="100%" height="1300px"></iframe>
<br></br>
<br></br>
<form name="form" id="form" action=""><textarea name="console"
id="console" style="width: 100%; height: 300px;" cols="" rows=""></textarea>
<button name="clear" id="clear" type="reset">Clear</button>
</form>
</body>
</html>

Anda perlu mengganti src di iframe dengan tautan Anda sendiri. Semoga ini bisa membantu. Salam, Mo.

Mohammed Radwan
sumber
1
Berdasarkan pengujian cepat, contoh yang diberikan (setelah memperbaiki URL) tampaknya bekerja di IE 8, agak andal di Chrome 14.0.835.186 m, tetapi tidak sama sekali di Firefox 6.0.2.
Matthew Flaschen
Bekerja dengan baik untuk Chrome, tetapi tidak berfungsi untuk Firefox v62, karena ketika klik pada acara iframe blur tidak dilempar
slesh
11

Baru saja menemukan solusi ini ... Saya mencobanya, saya menyukainya ..

Berfungsi untuk iframe lintas domain untuk desktop dan seluler!

Tidak tahu apakah itu sangat mudah

window.addEventListener('blur',function(){
      if(document.activeElement.id == 'CrossDomainiframeId'){
        //do something :-)
      }
});

Selamat coding

Tony
sumber
2
Jawaban yang sama ini (mungkin versi yang sedikit lebih baik) telah diposting setahun sebelumnya di sini di halaman yang sama: stackoverflow.com/a/23231136/470749
Ryan
5

Anda dapat mencapai ini dengan menggunakan blur event pada elemen window.

Berikut ini adalah plugin jQuery untuk melacak klik pada iframe (ini akan menjalankan fungsi callback kustom ketika iframe diklik): https://github.com/finalclap/iframeTracker-jquery

Gunakan seperti ini:

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

lihat http://jsfiddle.net/Lcy797h2/ untuk solusi panjang lebar saya yang tidak berfungsi dengan baik di IE

        $(window).on('blur',function(e) {    
            if($(this).data('mouseIn') != 'yes')return;
            $('iframe').filter(function(){
                return $(this).data('mouseIn') == 'yes';
            }).trigger('iframeclick');    
        });

        $(window).mouseenter(function(){
            $(this).data('mouseIn', 'yes');
        }).mouseleave(function(){
            $(this).data('mouseIn', 'no');
        });

        $('iframe').mouseenter(function(){
            $(this).data('mouseIn', 'yes');
            $(window).data('mouseIn', 'yes');
        }).mouseleave(function(){
            $(this).data('mouseIn', null);
        });

        $('iframe').on('iframeclick', function(){
            console.log('Clicked inside iframe');
            $('#result').text('Clicked inside iframe'); 
        });
        $(window).on('click', function(){
            console.log('Clicked inside window');
            $('#result').text('Clicked inside window'); 
        }).blur(function(){
            console.log('window blur');
        });

        $('<input type="text" style="position:absolute;opacity:0;height:0px;width:0px;"/>').appendTo(document.body).blur(function(){
                $(window).trigger('blur');
            }).focus();
DiverseAndRemote.com
sumber
Pembuat kode yang luar biasa .... apa yang sebenarnya saya inginkan ... +1 ke @Omar Jackman .. sangat membantu untuk menangkap klik iklan youtube
saun4frsh
4

Ini berfungsi untuk saya di semua browser (termasuk Firefox)

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

https://jsfiddle.net/sidanmor/v6m9exsw/

var myConfObj = {
  iframeMouseOver : false
}
window.addEventListener('blur',function(){
  if(myConfObj.iframeMouseOver){
    console.log('Wow! Iframe Click!');
  }
});

document.getElementById('idanmorblog').addEventListener('mouseover',function(){
   myConfObj.iframeMouseOver = true;
});
document.getElementById('idanmorblog').addEventListener('mouseout',function(){
    myConfObj.iframeMouseOver = false;
});
<iframe id="idanmorblog" src="https://sidanmor.com/" style="width:400px;height:600px" ></iframe>

<iframe id="idanmorblog" src="https://sidanmor.com/" style="width:400px;height:600px" ></iframe>

sidanmor
sumber
3

Mohammed Radwan, Solusi Anda elegan. Untuk mendeteksi klik iframe di Firefox dan IE, Anda dapat menggunakan metode sederhana dengan document.activeElement dan timer, namun ... Saya telah mencari di seluruh jalinan metode untuk mendeteksi klik pada iframe di Chrome dan Safari. Di ambang menyerah, saya menemukan jawaban Anda. Terima kasih Pak!

Beberapa tips: Saya telah menemukan solusi Anda lebih dapat diandalkan ketika memanggil fungsi init () secara langsung, daripada melalui attachOnloadEvent (). Tentu saja untuk melakukan itu, Anda harus memanggil init () hanya setelah iframe html. Jadi akan terlihat seperti:

<script>
var isOverIFrame = false;
function processMouseOut() {
    isOverIFrame = false;
    top.focus();
}
function processMouseOver() { isOverIFrame = true; }
function processIFrameClick() {
    if(isOverIFrame) {
    //was clicked
    }
}

function init() {
    var element = document.getElementsByTagName("iframe");
    for (var i=0; i<element.length; i++) {
        element[i].onmouseover = processMouseOver;
        element[i].onmouseout = processMouseOut;
    }
    if (typeof window.attachEvent != 'undefined') {
        top.attachEvent('onblur', processIFrameClick);
    }
    else if (typeof window.addEventListener != 'undefined') {
        top.addEventListener('blur', processIFrameClick, false);
    }
}
</script>

<iframe src="http://google.com"></iframe>

<script>init();</script>
zone117x
sumber
3

Anda dapat melakukan ini untuk menggelembungkan acara ke dokumen induk:

$('iframe').load(function() {
    var eventlist = 'click dblclick \
                    blur focus focusin focusout \
                    keydown keypress keyup \
                    mousedown mouseenter mouseleave mousemove mouseover mouseout mouseup mousemove \
                    touchstart touchend touchcancel touchleave touchmove';

    var iframe = $('iframe').contents().find('html');

    // Bubble events to parent
    iframe.on(eventlist, function(event) {
        $('html').trigger(event);
    });
});

Cukup rentangkan daftar acara untuk lebih banyak acara.

Taner Topal
sumber
Saya menggunakan acara 'touchend' dan berhasil! Jawaban Anda banyak membantu saya!
3

Saya mengalami situasi di mana saya harus melacak klik pada tombol media sosial yang ditarik melalui iframe. Jendela baru akan dibuka ketika tombol diklik. Inilah solusi saya:

var iframeClick = function () {
    var isOverIframe = false,
    windowLostBlur = function () {
        if (isOverIframe === true) {
            // DO STUFF
            isOverIframe = false;
        }
    };
    jQuery(window).focus();
    jQuery('#iframe').mouseenter(function(){
        isOverIframe = true;
        console.log(isOverIframe);
    });
    jQuery('#iframe').mouseleave(function(){
        isOverIframe = false;
        console.log(isOverIframe);
    });
    jQuery(window).blur(function () {
        windowLostBlur();
    });
};
iframeClick();
pizzarob
sumber
3

http://jsfiddle.net/QcAee/406/

Buat saja lapisan yang tidak terlihat di atas iframe yang kembali ketika klik dan naik ketika acara mouse akan dipecat !!
Butuh jQuery

solusi ini jangan menyebarkan klik pertama di dalam iframe!

$("#invisible_layer").on("click",function(){
		alert("click");
		$("#invisible_layer").css("z-index",-11);

});
$("iframe").on("mouseleave",function(){
		$("#invisible_layer").css("z-index",11);
});
iframe {
    width: 500px;
    height: 300px;
}
#invisible_layer{
  position: absolute;
  background-color:trasparent;
  width: 500px;
  height:300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="message"></div>
<div id="invisible_layer">

</div>
<iframe id="iframe" src="//example.com"></iframe>

r1si
sumber
1

Ini pasti berfungsi jika iframe berasal dari domain yang sama dengan situs induk Anda. Saya belum mengujinya untuk situs lintas domain.

$(window.frames['YouriFrameId']).click(function(event){  /* do something here  */ });
$(window.frames['YouriFrameId']).mousedown(function(event){ /* do something here */ });
$(window.frames['YouriFrameId']).mouseup(function(event){ /* do something here */ });

Tanpa jQuery Anda dapat mencoba sesuatu seperti ini, tetapi sekali lagi saya belum mencoba ini.

window.frames['YouriFrameId'].onmousedown = function() { do something here }

Anda bahkan dapat memfilter hasil Anda:

$(window.frames['YouriFrameId']).mousedown(function(event){   
  var eventId = $(event.target).attr('id');      
  if (eventId == 'the-id-you-want') {
   //  do something
  }
});
Jonathan Tonge
sumber
1

Menggabungkan jawaban di atas dengan kemampuan untuk mengklik lagi dan lagi tanpa mengklik iframe luar.

    var eventListener = window.addEventListener('blur', function() {
    if (document.activeElement === document.getElementById('contentIFrame')) {
        toFunction(); //function you want to call on click
        setTimeout(function(){ window.focus(); }, 0);
    }
    window.removeEventListener('blur', eventListener );
    });
Talha Asif
sumber
1

Kami dapat menangkap semua klik. Idenya adalah mengatur ulang fokus pada elemen di luar iFrame setelah setiap klik:

    <input type="text" style="position:fixed;top:-1000px;left:-1000px">
    <div id="message"></div>
    <iframe id="iframe" src="//example.com"></iframe>
    <script>
        focus();
        addEventListener('blur', function() {
            if(document.activeElement = document.getElementById('iframe')) {
                message.innerHTML += 'Clicked';
                setTimeout(function () {
                    document.querySelector("input").focus();
                    message.innerHTML += ' - Reset focus,';
                }, 1000);
            }  
        });
    </script>

JSFiddle

Alexandre Muraviov
sumber
0

Saya yakin Anda bisa melakukan sesuatu seperti:

$('iframe').contents().click(function(){function to record click here });

menggunakan jQuery untuk mencapai ini.

Penjual Daniel
sumber
0

Seperti yang ditemukan di sana: Deteksi Klik ke Iframe menggunakan JavaScript

=> Kita bisa menggunakan iframeTracker-jquery :

$('.carousel-inner .item').each(function(e) {
    var item = this;
    var iFrame = $(item).find('iframe');
    if (iFrame.length > 0) {
        iFrame.iframeTracker({
            blurCallback: function(){
                // Do something when iFrame is clicked (like firing an XHR request)
                onItemClick.bind(item)(); // calling regular click with right context
                console.log('IFrameClick => OK');
            }
        });
        console.log('IFrameTrackingRegistred => OK');
    }
})
Mickaël
sumber
0

Berbasis di jawaban Paul Draper, saya menciptakan solusi yang bekerja terus menerus ketika Anda memiliki Iframe yang membuka tab lain di browser. Ketika Anda kembali halaman terus aktif untuk mendeteksi klik di atas kerangka kerja, ini adalah situasi yang sangat umum:

          focus();
        $(window).blur(() => {
           let frame = document.activeElement;
           if (document.activeElement.tagName == "IFRAME") {
             // Do you action.. here  frame has the iframe clicked
              let frameid = frame.getAttribute('id')
              let frameurl = (frame.getAttribute('src'));
           }            
        });

        document.addEventListener("visibilitychange", function () {
            if (document.hidden) {

            } else {
                focus();
            }
        });

Kode sederhana, peristiwa blur mendeteksi kehilangan fokus ketika iframe diklik, dan menguji apakah elemen aktif adalah iframe (jika Anda memiliki beberapa iframe Anda bisa tahu siapa yang dipilih) situasi ini sering terjadi ketika Anda memiliki bingkai publisitas .

Acara kedua memicu metode fokus saat Anda kembali ke halaman. digunakan acara perubahan visibilitas.

pengembang freede
sumber
0

Berikut adalah solusi menggunakan pendekatan yang disarankan dengan hover + blur dan trik elemen aktif, bukan pustaka, hanya js murni. Berfungsi baik untuk FF / Chrome. Kebanyakan pendekatan sama dengan yang diusulkan @Mohammed Radwan, kecuali bahwa saya menggunakan metode berbeda yang diusulkan oleh @ zone117x untuk melacak klik iframe untuk FF, karena window.focus tidak berfungsi tanpa penambahan pengaturan pengguna :

Membuat permintaan untuk membawa jendela ke depan. Mungkin gagal karena pengaturan pengguna dan jendela tidak dijamin paling depan sebelum metode ini kembali.

Berikut adalah metode majemuk:

function () {
    const state = {};

    (function (setup) {
        if (typeof window.addEventListener !== 'undefined') {
            window.addEventListener('load', setup, false);
        } else if (typeof document.addEventListener !== 'undefined') {
            document.addEventListener('load', setup, false);
        } else if (typeof window.attachEvent !== 'undefined') {
            window.attachEvent('onload', setup);
        } else {
            if (typeof window.onload === 'function') {
                const oldonload = onload;
                window.onload = function () {
                    oldonload();
                    setup();
                };
            } else {
                window.onload = setup;
            }
        }
    })(function () {
        state.isOverIFrame = false;
        state.firstBlur = false;
        state.hasFocusAcquired = false;

        findIFramesAndBindListeners();

        document.body.addEventListener('click', onClick);

        if (typeof window.attachEvent !== 'undefined') {
            top.attachEvent('onblur', function () {
                state.firstBlur = true;
                state.hasFocusAcquired = false;
                onIFrameClick()
            });
            top.attachEvent('onfocus', function () {
                state.hasFocusAcquired = true;
                console.log('attachEvent.focus');
            });
        } else if (typeof window.addEventListener !== 'undefined') {
            top.addEventListener('blur', function () {
                state.firstBlur = true;
                state.hasFocusAcquired = false;
                onIFrameClick();
            }, false);
            top.addEventListener('focus', function () {
                state.hasFocusAcquired = true;
                console.log('addEventListener.focus');
            });
        }

        setInterval(findIFramesAndBindListeners, 500);
    });

    function isFF() {
        return navigator.userAgent.search(/firefox/i) !== -1;
    }

    function isActiveElementChanged() {
        const prevActiveTag = document.activeElement.tagName.toUpperCase();
        document.activeElement.blur();
        const currActiveTag = document.activeElement.tagName.toUpperCase();
        return !prevActiveTag.includes('BODY') && currActiveTag.includes('BODY');
    }

    function onMouseOut() {
        if (!state.firstBlur && isFF() && isActiveElementChanged()) {
            console.log('firefox first click');
            onClick();
        } else {
            document.activeElement.blur();
            top.focus();
        }
        state.isOverIFrame = false;
        console.log(`onMouseOut`);
    }

    function onMouseOver() {
        state.isOverIFrame = true;
        console.log(`onMouseOver`);
    }

    function onIFrameClick() {
        console.log(`onIFrameClick`);
        if (state.isOverIFrame) {
            onClick();
        }
    }

    function onClick() {
        console.log(`onClick`);
    }

    function findIFramesAndBindListeners() {
        return Array.from(document.getElementsByTagName('iframe'))
            .forEach(function (element) {
                element.onmouseover = onMouseOver;
                element.onmouseout = onMouseOut;
            });
    }
}
slesh
sumber
0

Asumsi -

  1. Script Anda berjalan di luar iframe TETAPI TIDAK di jendela window.top terluar. (Untuk jendela terluar, solusi blur lainnya cukup baik)
  2. Halaman baru dibuka menggantikan halaman saat ini / halaman baru di tab baru dan kontrol dialihkan ke tab baru.

Ini berfungsi baik untuk iframe yang sumber maupun sumber

var ifr = document.getElementById("my-iframe");
var isMouseIn;
ifr.addEventListener('mouseenter', () => {
    isMouseIn = true;
});
ifr.addEventListener('mouseleave', () => {
    isMouseIn = false;
});
window.document.addEventListener("visibilitychange", () => {
    if (isMouseIn && document.hidden) {
        console.log("Click Recorded By Visibility Change");
    }
});
window.addEventListener("beforeunload", (event) => {
    if (isMouseIn) {
        console.log("Click Recorded By Before Unload");
    }
});

Jika tab baru dibuka / halaman yang sama diturunkan dan pointer mouse berada di dalam Iframe, klik dianggap

Sahil Maniar
sumber