ตรวจสอบคลิกเข้าสู่ Iframe โดยใช้ JavaScript


128

ฉันเข้าใจว่ามันเป็นไปไม่ได้ที่จะบอกว่าผู้ใช้กำลังทำอะไรภายในiframeถ้ามันเป็นข้ามโดเมน สิ่งที่ฉันต้องการจะทำคือการติดตามหากผู้ใช้คลิกiframeเลย ผมคิดว่าสถานการณ์ที่มีการมองไม่เห็นdivด้านบนของiframeและที่จะเพิ่งผ่านเหตุการณ์แล้วคลิกไปที่ diviframe

เป็นไปได้อย่างนี้ไหม? ถ้าเป็นเช่นนั้นฉันจะไปเกี่ยวกับมันได้อย่างไร iframesโฆษณาดังนั้นผมจึงมีการควบคุมมากกว่าแท็กที่ใช้ไม่มี


4
เป็นไปได้และมีวิธีแก้ปัญหา crossbrowser: stackoverflow.com/a/32138108/1064513
Dmitry Kochin

คำตอบ:


39

เป็นไปได้อย่างนี้ไหม?

ไม่ได้สิ่งที่คุณทำได้คือตรวจจับเมาส์ที่เข้าสู่ iframe และอาจเกิดขึ้นได้ (แม้ว่าจะไม่น่าเชื่อถือ) เมื่อมันกลับมา (เช่นการพยายามหาข้อแตกต่างระหว่างตัวชี้ที่ส่งผ่านโฆษณาระหว่างทางเทียบกับที่อื่น ในโฆษณา)

ฉันจินตนาการถึงสถานการณ์ที่มี div ที่มองไม่เห็นอยู่ด้านบนของ iframe และ div ก็จะส่งเหตุการณ์ click ไปที่ iframe

ไม่, ไม่สามารถปลอมเหตุการณ์คลิกได้

ด้วยการจับเมาส์ที่คุณต้องการป้องกันไม่ให้คลิกดั้งเดิมไปที่ iframe หากคุณสามารถกำหนดได้ว่าเมื่อไรที่จะกดปุ่มเมาส์คุณสามารถลอง div ที่มองไม่เห็นออกไปเพื่อให้การคลิกผ่านไป ...

คุณสามารถลองเดาได้โดยดูจากการดูว่าตัวชี้หยุดพักหรือไม่โดยคาดเดาว่าจะมีการคลิก แต่มันไม่น่าเชื่อถืออย่างสมบูรณ์และถ้าคุณล้มเหลวคุณก็สูญเสียการคลิกผ่าน


4
ใช่แล้ว. และมีวิธีแก้ปัญหาของ crossbrowser: stackoverflow.com/a/32138108/1064513
Dmitry Kochin

1
ฉันตรวจสอบลิงก์เหล่านี้และฉันคิดว่าคำตอบนั้นถูกต้อง คุณสามารถตรวจพบคลิกภายใน iframe แต่ไม่ใช่สิ่งที่คลิก
user568021

ฉันลงคะแนนเพียงเพราะมันไม่เป็นความจริงโดยสิ้นเชิง สิ่งที่คุณพูดส่วนใหญ่เป็นเรื่องจริง แต่มีวิธีแก้ไขเช่นเดียวกับคำตอบที่ได้รับความนิยมมากในหัวข้อนี้
newms87

154

เป็นไปได้อย่างแน่นอน สิ่งนี้ใช้ได้ใน Chrome, Firefox และ IE 11 (และอาจเป็นอย่างอื่น)

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

JSFiddle


Caveat: วิธีนี้จะตรวจพบการคลิกครั้งแรกเท่านั้น เท่าที่ฉันเข้าใจนั่นคือทั้งหมดที่คุณต้องการ


1
@the_joric มันเป็นเพราะมันเป็นเวลา 4 ปีหลังจากคำถามและโดยปกติผู้คนจะไม่เลื่อนดูคำตอบของคู่แรก
พอลเดรเปอร์

3
อีกอย่างของโน้ตคือถ้าคุณเปลี่ยนแท็บของเบราว์เซอร์มันจะทำการโฟกัส ();
Linnay

7
มันไม่ทำงานใน Firefox JSFiddle มีข้อผิดพลาดที่ซ่อนสิ่งนี้: = แทน === มีวิธีแก้ปัญหา crossbrowser (แม้แต่ใน IE8): stackoverflow.com/a/32138108/1064513
Dmitry Kochin

8
เหตุการณ์ความพร่ามัวไม่ทำงานหากผู้ใช้ไม่คลิกเข้าไปในเอกสารหลักก่อน! นอกจากนี้ยังใช้งานไม่ได้สำหรับการตรวจจับคลิกเพื่อ iframes หลายรายการเนื่องจากไม่มีเหตุการณ์ที่เกิดขึ้นเมื่อโฟกัสเปลี่ยนจาก iframe หนึ่งไปเป็นอีกอัน ( blurเหตุการณ์ของ iframe ไม่ทำงาน)
Tomáš Kafka

1
เหตุใดจึงต้องพึ่งพาการโฟกัส ();
Prasad Shinde

107

จากคำตอบของโมฮัมเหม็ดราวันวานฉันได้คำตอบ jQuery ต่อไปนี้ขึ้นมา โดยพื้นฐานแล้วสิ่งที่มันทำคือการติดตามสิ่งที่คน iFrame กำลังโฉบ ถ้าหน้าต่างนั้นพร่ามัวซึ่งหมายความว่าผู้ใช้คลิกที่แบนเนอร์ iframe

iframe ควรใส่ div ที่มี id เพื่อให้แน่ใจว่าคุณทราบ iframe ที่ผู้ใช้คลิก:

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

ดังนั้น:

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

... สิ่งนี้จะทำให้ overiFrame อยู่ที่ -1 เมื่อไม่มีการโฮเวอร์ iFrames หรือการตั้งค่า 'bannerid' ใน div การตัดเมื่อ iframe ถูกโฮเวอร์ สิ่งที่คุณต้องทำคือตรวจสอบว่า 'overiFrame' ถูกตั้งค่าเมื่อหน้าต่างพร่ามัวเช่นนั้น: ...

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

ทางออกที่สวยงามมากพร้อมข้อเสียเล็กน้อย: หากผู้ใช้กด ALT-F4 เมื่อวางเมาส์เหนือ iFrame มันจะเข้าสู่ระบบเมื่อคลิก สิ่งนี้เกิดขึ้นใน FireFox เท่านั้นเช่น IE, Chrome และ Safari ไม่ได้ลงทะเบียน

ขอบคุณอีกครั้งโมฮัมเหม็ดทางออกที่มีประโยชน์มาก!


ฉันมี +1 คำตอบนี้แม้ว่าจะมีปัญหาต่อไปนี้: 1. เมื่อมี iframe หลายรายการคุณคลิกที่หนึ่งในนั้นจากนั้นทันทีอีกที่หนึ่ง - ตรวจไม่พบการคลิกครั้งที่สอง 2. การคลิกหลายครั้งภายใน iframe จะไม่ถูกนับเช่นกัน 3. ไม่ทำงานอย่างถูกต้องบนมือถือเพราะคุณไม่สามารถทำกิจกรรม "โฮเวอร์" ด้วยนิ้ว
Sych

ฉันใช้สคริปต์ข้างต้นเพื่อตรวจจับการคลิกออกจากเว็บไซต์ของฉัน เครือข่ายโฆษณาส่วนใหญ่ตอนนี้ให้บริการแบนเนอร์ในเฟรม หากคุณคลิกหนึ่งครั้งแล้วคลิกอีกครั้งอย่างรวดเร็วก่อนที่คุณจะออกจากการคลิกครั้งแรกในทางเทคนิคฉันต้องการทราบคลิกสุดท้ายที่คุณเหลือจริง ดังนั้นในกรณีของฉันมันต้องการพฤติกรรม มันตรวจจับการคลิกที่แบนเนอร์บนมือถือด้วยเช่นกัน ดังนั้นการวางเมาส์ไว้จะต้องเปิดตัวก่อนดำเนินการคลิก
แพทริค

ไม่ทำงานในกรณีขององค์ประกอบ svg ในเนื้อหา iframe :( stackoverflow.com/questions/32589735/…
Serhiy

@Serhiy นั่นเป็นเพราะคุณไม่ได้ออกจากหน้าต้นฉบับจริง ๆ เมื่อคลิกที่ iframe ...
patrick

6
คำตอบนี้เป็นคำตอบที่ดีที่สุดอย่างไรก็ตามหากคุณต้องการได้รับการคลิกทุกครั้งใน iframe คุณจะต้องให้ความสำคัญเมื่อผู้ใช้คลิกเพื่อติดตามการคลิกเพิ่มเติม นี้ควรจะเพิ่มไปยัง $ (หน้าต่าง) .blur () setTimeout(function(){ window.focus(); }, 0);ส่วน: ตอนนี้ผู้ใช้คลิก, ให้ความสำคัญกับ iframe, สคริปต์จะดึงโฟกัสนั้นกลับมา, และตอนนี้สามารถตรวจสอบการเปลี่ยนแปลงที่มุ่งเน้นต่อไปจากการคลิกในอนาคต
ช่วยมือ

89

นี่เป็นโซลูชันขนาดเล็กที่ใช้งานได้กับเบราว์เซอร์ทั้งหมดแม้กระทั่ง IE8:

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

คุณสามารถทดสอบได้ที่นี่: http://jsfiddle.net/oqjgzsm0/


1
ถ้าคุณมี iframe หลายอันและคุณไม่รู้ id ของพวกเขาล่ะ
shankshera

1
โซลูชันที่น่าเชื่อถือข้ามเบราว์เซอร์เท่านั้นที่ใช้งานได้ใน FF ล่าสุด! ขอบคุณมาก. มันสมควรได้รับการ
โหวต

6
@shankshera เพิ่งได้รับ elem.id นั่นคือรหัส iframe ของคุณ :) ดูjsfiddle.net/oqjgzsm0/219
Tomáš Kafka

1
ฉันใช้สิ่งนี้เพื่อติดตามคลิกบนปุ่มโซเชียล แต่เนื่องจาก 3/4 ของรายการที่ฉันใช้ใช้ iframes ฉันต้องติดตามการคลิกในหลาย iframe ผมได้ปรับปรุงซอเพื่อให้ว่าjsfiddle.net/oqjgzsm0/273 มันตั้งค่าช่วงเวลาใหม่ที่ตรวจสอบเพื่อดูว่าคลิกอยู่นอก iframe คลิกที่ผ่านมา จากนั้นรีเซ็ตช่วงเวลาดั้งเดิมเพื่อตรวจสอบการคลิกอีกครั้ง ไม่ติดตามการคลิกหลายครั้งใน iframe เดียวกันโดยไม่มีการคลิกภายนอก
brouxhaha

14
นอกเหนือจากความจริงที่ว่าการใช้ช่วงเวลาวนรอบอย่างต่อเนื่องในอัตราดังกล่าวไม่ใช่ความคิดที่ดีมากสิ่งนี้จะตรวจหาผลบวกที่ผิดพลาดหากผู้ใช้ตั้งค่าโฟกัสบน iframe ผ่านการนำทางแท็บคีย์
Kaiido

36

รหัสต่อไปนี้จะแสดงให้คุณเห็นหากผู้ใช้คลิก / โฮเวอร์หรือย้ายออกจาก 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>

คุณต้องแทนที่ src ใน iframe ด้วยลิงก์ของคุณเอง หวังว่านี่จะช่วยได้ ขอแสดงความนับถือโม


1
จากการทดสอบอย่างรวดเร็วตัวอย่างที่ให้ไว้ (หลังจากแก้ไข URL) ดูเหมือนว่าจะทำงานใน IE 8 ได้อย่างน่าเชื่อถือใน Chrome 14.0.835.186 m แต่ไม่ใช่ทั้งหมดใน Firefox 6.0.2
Matthew Flaschen

ทำงานได้ดีสำหรับ Chrome แต่ไม่สามารถใช้งานได้กับ Firefox v62 เพราะเมื่อคลิกที่เหตุการณ์iframe blurไม่ถูกโยนทิ้ง
slesh

11

เพิ่งพบวิธีนี้ ... ฉันพยายามฉันรักมัน ..

ใช้งานได้สำหรับ iframes ข้ามโดเมนสำหรับเดสก์ท็อปและมือถือ!

ไม่รู้ว่ามันจะเข้าใจผิดหรือยัง

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

การเข้ารหัสที่มีความสุข


2
คำตอบเดียวกันนี้ (อาจเป็นรุ่นที่ดีขึ้นเล็กน้อย) ถูกโพสต์เมื่อปีที่แล้วในหน้าเดียวกันนี้: stackoverflow.com/a/23231136/470749
Ryan

5

คุณสามารถทำได้โดยใช้เหตุการณ์เบลอในองค์ประกอบหน้าต่าง

นี่คือปลั๊กอิน jQuery สำหรับติดตามการคลิกบน iframes (มันจะเรียกใช้ฟังก์ชันการเรียกกลับที่กำหนดเองเมื่อมีการคลิก iframe): https://github.com/finalclap/iframeTracker-jquery

ใช้แบบนี้:

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

5

ดูhttp://jsfiddle.net/Lcy797h2/สำหรับวิธีแก้ปัญหาที่ยืดยาวซึ่งไม่สามารถทำงานได้อย่างน่าเชื่อถือใน 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();

มันเป็นคนเขียนโค้ดที่ยอดเยี่ยม .... สิ่งที่ฉันต้องการจริง ๆ ... + 1 ถึง @Omar Jackman .. มีประโยชน์มากในการจับภาพคลิกโฆษณา youtube
saun4frsh

4

สิ่งนี้ใช้ได้กับทุกเบราว์เซอร์ (รวม 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>


3

โมฮัมเหม็ดราวันโซลูชั่นของคุณสวยหรู ในการตรวจสอบการคลิก iframe ใน Firefox และ IE คุณสามารถใช้วิธีการง่าย ๆ กับ document.activeElement และตัวจับเวลาได้อย่างไรก็ตาม ... ฉันได้ทำการค้นหา interwebs ทุกครั้งเพื่อหาวิธีตรวจจับการคลิก iframe ใน Chrome และ Safari ฉันพบคำตอบของคุณ ขอบคุณครับ!

เคล็ดลับ: ฉันพบว่าโซลูชันของคุณเชื่อถือได้มากขึ้นเมื่อเรียกใช้ฟังก์ชัน init () โดยตรงแทนที่จะใช้ attachOnloadEvent () คุณต้องโทรหา init () เฉพาะหลังจาก iframe html เท่านั้น ดังนั้นมันจะมีลักษณะดังนี้:

<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>

3

คุณสามารถทำสิ่งนี้กับเหตุการณ์ฟองไปยังเอกสารหลัก:

$('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);
    });
});

เพียงขยายรายการกิจกรรมสำหรับกิจกรรมเพิ่มเติม


ฉันใช้เหตุการณ์ 'touchend' และใช้งานได้ คำตอบของคุณช่วยฉันได้มาก!

3

ฉันวิ่งเข้าไปในสถานการณ์ที่ต้องติดตามการคลิกบนปุ่มโซเชียลมีเดียที่ถูกดึงเข้ามาผ่าน iframe หน้าต่างใหม่จะเปิดขึ้นเมื่อคลิกปุ่ม นี่คือทางออกของฉัน:

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();

3

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

เพียงแค่สร้างเลเยอร์ที่มองไม่เห็นเหนือ iframe ที่ย้อนกลับไปเมื่อคลิกและขึ้นไปเมื่อเหตุการณ์ mouseleave จะถูกไล่ออก !!
ต้องการ jQuery

โซลูชันนี้จะไม่เผยแพร่คลิกแรกภายใน 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>


1

วิธีนี้ใช้ได้ผลถ้า iframe มาจากโดเมนเดียวกับไซต์แม่ของคุณ ฉันยังไม่ได้ทดสอบกับเว็บไซต์ข้ามโดเมน

$(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 */ });

หากไม่มี jQuery คุณสามารถลองสิ่งนี้ แต่ฉันยังไม่ได้ลอง

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

คุณสามารถกรองผลลัพธ์ของคุณ:

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

1

รวมคำตอบข้างต้นเข้ากับความสามารถในการคลิกซ้ำแล้วซ้ำอีกโดยไม่ต้องคลิกนอก iframe

    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 );
    });

1

เราสามารถตรวจจับการคลิกทั้งหมดได้ แนวคิดคือการรีเซ็ตโฟกัสไปที่องค์ประกอบภายนอก iFrame หลังจากคลิกแต่ละครั้ง:

    <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


0

ฉันเชื่อว่าคุณสามารถทำสิ่งที่ชอบ:

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

ใช้ jQuery เพื่อทำสิ่งนี้ให้สำเร็จ


0

ตรวจพบการคลิกเข้าสู่ Iframe โดยใช้ JavaScript

=> เราสามารถใช้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');
    }
})

0

ตามคำตอบของ Paul Draper ฉันสร้างโซลูชันที่ทำงานอย่างต่อเนื่องเมื่อคุณมี Iframes ที่เปิดแท็บอื่นในเบราว์เซอร์ เมื่อคุณกลับมาหน้ายังคงใช้งานเพื่อตรวจสอบการคลิกผ่านกรอบนี้เป็นสถานการณ์ที่พบบ่อยมาก:

          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();
            }
        });

รหัสนั้นง่ายเหตุการณ์เบลอตรวจจับการสูญเสียโฟกัสเมื่อคลิก iframe และทดสอบว่าองค์ประกอบที่ใช้งานคือ iframe (ถ้าคุณมี iframe หลายตัวคุณสามารถรู้ได้ว่าใครถูกเลือก) สถานการณ์นี้มักเกิดขึ้นเมื่อคุณมีเฟรมประชาสัมพันธ์ .

เหตุการณ์ที่สองเรียกวิธีการโฟกัสเมื่อคุณกลับไปที่หน้า มันใช้เหตุการณ์การเปลี่ยนแปลงการมองเห็น


0

นี่คือวิธีการแก้ปัญหาโดยใช้วิธีการที่แนะนำพร้อมเทคนิคการโฮเวอร์ + เบลอและแอคทีฟไม่ใช่ไลบรารีใด ๆ เพียงแค่บริสุทธิ์ js ทำงานได้ดีสำหรับ FF / Chrome วิธีการส่วนใหญ่เหมือนกับ @Mohammed Radwan ที่เสนอยกเว้นว่าฉันใช้วิธีการที่เสนอโดย @ zone117x เพื่อติดตามการคลิก iframe สำหรับ FF เนื่องจากwindow.focusไม่ทำงานหากไม่มีการตั้งค่าผู้ใช้เพิ่มเติม:

ทำการร้องขอเพื่อนำหน้าต่างไปไว้ด้านหน้า อาจล้มเหลวเนื่องจากการตั้งค่าผู้ใช้และไม่รับประกันว่าหน้าต่างจะอยู่ด้านหน้าสุดก่อนที่วิธีนี้จะส่งคืน

นี่คือวิธีการผสม:

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;
            });
    }
}

0

สมมติฐาน -

  1. สคริปต์ของคุณทำงานนอก iframe แต่ไม่ได้อยู่ในหน้าต่าง window.top ด้านนอกสุด (สำหรับหน้าต่างด้านนอกสุดโซลูชันเบลออื่น ๆ นั้นดีพอ)
  2. หน้าใหม่จะเปิดขึ้นแทนที่หน้าปัจจุบัน / หน้าใหม่ในแท็บใหม่และการควบคุมจะเปลี่ยนเป็นแท็บใหม่

ใช้งานได้กับiframe ทั้งที่มาและไร้ที่มา

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");
    }
});

หากมีการเปิดแท็บใหม่ / หน้าเดียวกันยกเลิกการโหลดและตัวชี้เมาส์อยู่ใน Iframe การคลิกจะถูกพิจารณา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.