Phát hiện Nhấp vào Iframe bằng JavaScript


128

Tôi hiểu rằng không thể nói người dùng đang làm gì bên trong iframenếu đó là tên miền chéo. Những gì tôi muốn làm là theo dõi nếu người dùng nhấp vào tất cả trong iframe. Tôi tưởng tượng một kịch bản trong đó có một thứ vô hình divtrên đầu iframevà ý divchí sau đó chuyển sự kiện nhấp chuột đến iframe.

Có phải bất cư thứ gì như thế này đều được? Nếu có, thì tôi sẽ làm thế nào? Đây iframeslà quảng cáo, vì vậy tôi không kiểm soát các thẻ được sử dụng.


4
Có thể và có giải pháp crossbrowser: stackoverflow.com/a/32138108/1064513
Dmitry Kochin

Câu trả lời:


39

Có phải bất cư thứ gì như thế này đều được?

Không. Tất cả những gì bạn có thể làm là phát hiện chuột đi vào iframe và có khả năng (mặc dù không đáng tin cậy) khi nó quay trở lại (nghĩa là cố gắng tìm ra sự khác biệt giữa con trỏ đi qua quảng cáo trên một nơi khác so với ling trên quảng cáo).

Tôi tưởng tượng một kịch bản trong đó có một div vô hình trên đầu iframe và div sẽ ngay sau đó chuyển sự kiện nhấp chuột vào iframe.

Không, không có cách nào để giả mạo một sự kiện nhấp chuột.

Bằng cách bắt mousedown, bạn sẽ ngăn nhấp chuột ban đầu vào iframe. Nếu bạn có thể xác định khi nào nút chuột sắp được nhấn, bạn có thể cố gắng đưa div vô hình ra khỏi đường để nhấp chuột sẽ đi qua ... nhưng cũng không có sự kiện nào xảy ra ngay trước khi đặt bẫy.

Bạn có thể thử đoán, ví dụ bằng cách tìm xem con trỏ đã dừng lại chưa, đoán một lần nhấp có thể sắp diễn ra. Nhưng nó hoàn toàn không đáng tin cậy và nếu bạn thất bại, bạn chỉ mất cho mình một lần nhấp.


4
Vâng, đúng vậy. Và có giải pháp crossbrowser: stackoverflow.com/a/32138108/1064513
Dmitry Kochin

1
Tôi đã kiểm tra các liên kết này và tôi nghĩ rằng câu trả lời là chính xác. Bạn chỉ có thể phát hiện một nhấp chuột bên trong iframe chứ không phải những gì đã được nhấp.
dùng568021

Tôi downvote, chỉ vì nó không hoàn toàn đúng. Hầu hết những gì bạn đang nói là đúng, nhưng có những cách giải quyết như là câu trả lời phổ biến hơn về chủ đề này.
newms87

154

Điều này là chắc chắn có thể. Điều này hoạt động trong Chrome, Firefox và IE 11 (và có thể là những người khác).

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

Câu đố


Hãy cẩn thận: Điều này chỉ phát hiện lần nhấp đầu tiên. Theo tôi hiểu, đó là tất cả những gì bạn muốn.


1
@the_joric, đó là vì đã 4 năm sau câu hỏi và mọi người thường không cuộn qua các câu trả lời đầu tiên.
Paul Draper

3
Cũng cần lưu ý là nếu bạn thay đổi các tab trình duyệt, nó sẽ kích hoạt tiêu điểm ();
Linnay

7
Nó KHÔNG hoạt động trong Firefox. JSFiddle chứa lỗi che giấu điều này: = thay vì ===. Có giải pháp crossbrowser (ngay cả trong IE8): stackoverflow.com/a/32138108/1064513
Dmitry Kochin

8
Sự kiện mờ không kích hoạt nếu người dùng không nhấp vào tài liệu chính trước! Ngoài ra, điều này không thể sử dụng để phát hiện các nhấp chuột vào nhiều iframe, vì không có sự kiện nào kích hoạt khi tiêu điểm thay đổi từ iframe này sang iframe khác ( blursự kiện của iframe không kích hoạt).
Tomáš Kafka

1
tại sao có sự phụ thuộc vào trọng tâm ();
Prasad Shinde

107

Dựa trên câu trả lời của Mohammed Radwan, tôi đã đưa ra giải pháp jQuery sau đây. Về cơ bản những gì nó làm là theo dõi những gì mọi người iFrame đang di chuột. Sau đó, nếu cửa sổ làm mờ điều đó rất có thể có nghĩa là người dùng đã nhấp vào biểu ngữ iframe.

iframe nên được đặt trong div với id, để đảm bảo bạn biết iframe nào mà người dùng đã nhấp vào:

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

vì thế:

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

... điều này giữ cho overiFrame ở -1 khi không có iFrames nào được di chuột hoặc 'bannerid' được đặt trong div gói khi một iframe được di chuột. Tất cả những gì bạn phải làm là kiểm tra xem 'overiFrame' có được đặt khi cửa sổ mờ không, như vậy: ...

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

Giải pháp rất thanh lịch với một nhược điểm nhỏ: nếu người dùng nhấn ALT-F4 khi di chuột qua iFrame, nó sẽ ghi nhật ký dưới dạng nhấp chuột. Điều này chỉ xảy ra trong FireFox, IE, Chrome và Safari đã không đăng ký nó.

Cảm ơn một lần nữa Mohammed, giải pháp rất hữu ích!


Tôi có + 1-ed câu trả lời này, mặc dù, nó có các vấn đề sau: 1. Khi có nhiều iframe, bạn nhấp vào một trong số chúng, sau đó ngay lập tức vào một câu hỏi khác - lần nhấp thứ hai không được phát hiện. 2. Nhiều lần nhấp trong iframe cũng không được tính. 3. Không hoạt động chính xác trên thiết bị di động, vì bạn không thể thực hiện sự kiện "di chuột" bằng ngón tay.
Sych

Kịch bản trên được tôi sử dụng để phát hiện các nhấp chuột từ trang web của tôi. Hầu hết các mạng quảng cáo hiện phục vụ các biểu ngữ trong khung. Nếu bạn nhấp vào một và sau đó nhanh chóng một lần khác trước khi bạn rời khỏi lần nhấp đầu tiên, về mặt kỹ thuật tôi muốn biết lần nhấp cuối cùng mà bạn thực sự để lại. Vì vậy, trong trường hợp của tôi, đó là hành vi mong muốn. Nó cũng phát hiện nhấp chuột trên các biểu ngữ di động quá. Vì vậy, di chuột phải được khởi chạy ngay trước khi nhấp chuột được thực thi
patrick

Không hoạt động trong trường hợp các phần tử svg trong nội dung iframe :( stackoverflow.com/questions/32589735/ Lời
Serhiy

@Serhiy, đó là vì bạn không thực sự thoát khỏi trang gốc khi nhấp vào iframe ...
patrick

6
Câu trả lời này là câu trả lời hay nhất trong số đó, tuy nhiên, nếu bạn muốn nhận mỗi lần nhấp vào iframe, bạn cần phải tập trung vào nó sau khi người dùng đã nhấp để theo dõi các lần nhấp tiếp theo. Điều này nên được thêm vào phần $ (window) .blur () : setTimeout(function(){ window.focus(); }, 0);. Bây giờ, người dùng nhấp, đặt tiêu điểm vào iframe, tập lệnh sẽ lấy lại tiêu điểm đó và giờ đây có thể theo dõi các thay đổi tập trung hơn nữa từ các lần nhấp trong tương lai.
HelpingHand

89

Đây là giải pháp nhỏ hoạt động trong tất cả các trình duyệt ngay cả IE8:

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

Bạn có thể kiểm tra nó ở đây: http://jsfiddle.net/oqjgzsm0/


1
Điều gì nếu bạn có một số iframe và bạn không biết id của họ?
shankshera

1
chỉ có giải pháp đáng tin cậy trên nhiều trình duyệt cũng hoạt động trong FF mới nhất! Cảm ơn nhiều. Nó xứng đáng được nâng cấp nhiều hơn
BrainOverflow

6
@shankshera Chỉ cần lấy elem.id, đó là id iframe của bạn :). Xem jsfiddle.net/oqjgzsm0/219
Tomáš Kafka

1
Tôi đang sử dụng điều này để theo dõi các nhấp chuột trên các nút như xã hội. Nhưng vì 3/4 trong số những cái tôi đang sử dụng iframe, tôi cần theo dõi các lần nhấp trong nhiều iframe. Tôi đã cập nhật fiddle để cho phép điều đó: jsfiddle.net/oqjgzsm0/273 . Nó đặt một khoảng thời gian mới để kiểm tra xem một nhấp chuột có nằm ngoài iframe được nhấp lần cuối không. Sau đó đặt lại khoảng thời gian ban đầu để kiểm tra lại lần nhấp. Nó không theo dõi nhiều lần nhấp trong cùng một iframe mà không có lần nhấp bên ngoài.
brouxhaha

14
Ngoài thực tế là sử dụng khoảng thời gian lặp liên tục ở tốc độ như vậy không phải là ý kiến ​​hay, điều này sẽ phát hiện dương tính giả nếu người dùng tập trung vào iframe thông qua điều hướng phím tab
Kaiido

36

Đoạn mã sau sẽ hiển thị cho bạn nếu người dùng nhấp / di chuột hoặc di chuyển ra khỏi 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>

Bạn cần thay thế src trong iframe bằng liên kết của riêng bạn. Hy vọng điều này sẽ giúp. Trân trọng, Mo.


1
Dựa trên thử nghiệm nhanh, ví dụ đã cho (sau khi sửa URL) dường như hoạt động trong IE 8, hơi đáng tin cậy trong Chrome 14.0.835.186 m, nhưng hoàn toàn không có trong Firefox 6.0.2.
Matthew Flaschen

Hoạt động tốt với Chrome, nhưng không hoạt động với Firefox v62, vì khi nhấp vào sự kiện làm mờ iframe không được ném
hãy xác định

11

Chỉ cần tìm giải pháp này ... Tôi đã thử nó, tôi thích nó ..

Hoạt động cho iframe tên miền cho máy tính để bàn và điện thoại di động!

Không biết nó có hoàn hảo không

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

Chúc mừng mã hóa


2
Câu trả lời tương tự này (có thể là một phiên bản tốt hơn một chút) đã được đăng một năm trước đây trên cùng trang này: stackoverflow.com/a/23231136/470749
Ryan

5

Bạn có thể đạt được điều này bằng cách sử dụng sự kiện mờ trên phần tử cửa sổ.

Đây là một plugin jQuery để theo dõi nhấp vào iframes (nó sẽ kích hoạt chức năng gọi lại tùy chỉnh khi nhấp vào iframe): https://github.com/finalclap/iframeTracker-jquery

Sử dụng nó như thế này:

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

5

xem http://jsfiddle.net/Lcy797h2/ để biết giải pháp dài hơi của tôi không hoạt động đáng tin cậy trong 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();

Người đàn ông mã hóa tuyệt vời của nó .... những gì tôi thực sự muốn ... + 1 cho @Omar Jackman .. rất hữu ích để nắm bắt nhấp vào quảng cáo youtube
saun4frsh

4

Điều này hoạt động với tôi trên tất cả các trình duyệt (bao gồm 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

Mohammed Radwan, giải pháp của bạn là thanh lịch. Để phát hiện các nhấp chuột iframe trong Firefox và IE, bạn có thể sử dụng một phương pháp đơn giản với document.activeEuity và bộ đếm thời gian, tuy nhiên ... Tôi đã tìm kiếm trên tất cả các interwebs để tìm phương pháp phát hiện các nhấp chuột trên iframe trong Chrome và Safari. Ở bờ vực từ bỏ, tôi tìm thấy câu trả lời của bạn. Cảm ơn ngài!

Một số mẹo: Tôi đã tìm thấy giải pháp của bạn đáng tin cậy hơn khi gọi hàm init () trực tiếp, thay vì thông qua AttachOnloadEvent (). Tất nhiên để làm điều đó, bạn phải gọi init () chỉ sau html iframe. Vì vậy, nó sẽ trông giống như:

<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

Bạn có thể làm điều này để tạo sự kiện bong bóng cho tài liệu gốc:

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

Chỉ cần mở rộng danh sách sự kiện cho nhiều sự kiện hơn.


Tôi đã sử dụng sự kiện 'touchend' và nó đã hoạt động! Câu trả lời của bạn đã giúp tôi rất nhiều!

3

Tôi gặp phải tình huống phải theo dõi các lần nhấp vào nút phương tiện truyền thông xã hội được kéo qua iframe. Một cửa sổ mới sẽ được mở khi nhấp vào nút. Đây là giải pháp của tôi:

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/

Chỉ cần tạo một lớp vô hình trên iframe quay trở lại khi nhấp và đi lên khi sự kiện mouseleave sẽ được kích hoạt !!
Cần jQuery

giải pháp này không truyền bá lần nhấp đầu tiên bên trong 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

Điều này chắc chắn hoạt động nếu iframe đến từ cùng một tên miền với trang web mẹ của bạn. Tôi chưa thử nghiệm nó cho các trang web tên miền chéo.

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

Không có jQuery bạn có thể thử một cái gì đó như thế này, nhưng một lần nữa tôi đã không thử cái này.

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

Bạn thậm chí có thể lọc kết quả của bạn:

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

1

Kết hợp câu trả lời ở trên với khả năng nhấp nhiều lần mà không cần nhấp vào iframe bên ngoài.

    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

Chúng tôi có thể bắt tất cả các nhấp chuột. Ý tưởng là đặt lại trọng tâm vào một yếu tố bên ngoài iFrame sau mỗi lần nhấp:

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

Câu đố


0

Tôi tin rằng bạn có thể làm một cái gì đó như:

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

sử dụng jQuery để thực hiện điều này.


0

Như đã tìm thấy ở đó: Phát hiện Nhấp vào Iframe bằng JavaScript

=> Chúng tôi có thể sử dụng 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

Dựa trên câu trả lời của Paul Draper, tôi đã tạo ra một giải pháp hoạt động liên tục khi bạn có Iframes mở tab khác trong trình duyệt. Khi bạn trả lại trang tiếp tục hoạt động để phát hiện nhấp chuột qua khung, đây là một tình huống rất phổ biến:

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

Mã rất đơn giản, sự kiện làm mờ phát hiện mất tiêu điểm khi nhấp vào iframe và kiểm tra xem phần tử hoạt động có phải là iframe không (nếu bạn có một vài iframe bạn có thể biết ai đã chọn) tình huống này thường xảy ra khi bạn có khung công khai .

Sự kiện thứ hai kích hoạt một phương thức tập trung khi bạn quay lại trang. nó được sử dụng sự kiện thay đổi tầm nhìn.


0

Đây là giải pháp sử dụng các cách tiếp cận được đề xuất với hover + Blur và các thủ thuật phần tử hoạt động, không phải bất kỳ thư viện nào, chỉ là js thuần túy. Hoạt động tốt cho FF / Chrome. Chủ yếu là sự chấp thuận giống như @Mohammed Radwan đã đề xuất, ngoại trừ việc tôi sử dụng phương pháp khác được đề xuất bởi @ area117x để theo dõi nhấp chuột iframe cho FF, vì window.f Focus không hoạt động nếu không có cài đặt người dùng bổ sung :

Làm cho một yêu cầu để đưa cửa sổ ra phía trước. Nó có thể thất bại do cài đặt của người dùng và cửa sổ không được đảm bảo ở phía trước trước khi phương thức này trở lại.

Đây là phương pháp ghép:

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

Giả định -

  1. Tập lệnh của bạn chạy bên ngoài iframe NHƯNG trong cửa sổ window.top ngoài cùng. (Đối với cửa sổ ngoài cùng, các giải pháp làm mờ khác là đủ tốt)
  2. Một trang mới được mở thay thế trang hiện tại / một trang mới trong một tab mới và điều khiển được chuyển sang tab mới.

Điều này hoạt động cho cả iframe không nguồn và chua

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

Nếu một tab mới được mở / tải cùng một trang và con trỏ chuột nằm trong Iframe, một lần nhấp được xem xét

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.