JavaScript를 사용하여 클릭하여 Iframe으로 감지


128

iframe교차 도메인 인 경우 사용자가 내부에서 수행중인 작업을 알 수 없다는 것을 이해 합니다. 내가하고 싶은 것은 사용자가에서를 클릭했는지 추적하는 것 iframe입니다. 나는 보이지 않는이 시나리오 상상 div의 상단을 iframe하고하여이 div바로 다음에 클릭 이벤트를 전달합니다 iframe.

이와 같은 것이 가능합니까? 그렇다면 어떻게해야합니까? 는 iframes광고입니다, 그래서 사용되는 태그를 제어 할 수 없습니다.


4
가능하고 크로스 브라우저 솔루션이 있습니다 : stackoverflow.com/a/32138108/1064513
Dmitry Kochin

답변:


39

이와 같은 것이 가능합니까?

아니요. 할 수있는 일은 iframe으로 들어가는 마우스를 감지하는 것입니다. 마우스가 다시 나올 때 (확실히 신뢰할 수는 없지만) 다른 곳에서 진행되는 방식으로 광고를 전달하는 포인터의 차이를 해결하려고 시도하는 것 광고).

iframe 위에 보이지 않는 div가 있고 div가 클릭 이벤트를 iframe으로 전달하는 시나리오를 상상합니다.

아니요, 클릭 이벤트를 위조 할 방법이 없습니다.

마우스 다운을 잡으면 원래 클릭이 iframe에 도달하지 못하게됩니다. 마우스 버튼을 언제 눌렀는지 알 수 있다면 보이지 않는 div를 벗어나서 클릭이 진행되도록 할 수 있지만 마우스 다운 직전에 발생하는 이벤트는 없습니다.

예를 들어, 포인터가 멈춰 있는지 확인하여 클릭이 다가올 수 있습니다. 그러나 그것은 완전히 신뢰할 수 없으며, 실패하면 클릭 연결을 잃어버린 것입니다.


4
그렇습니다. 그리고 크로스 브라우저 솔루션이 있습니다 : 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


주의 사항 : 첫 번째 클릭 만 감지합니다. 알다시피, 그게 당신이 원하는 전부입니다.


1
@ the_joric, 그것은 질문 후 4 년이었고, 사람들은 일반적으로 첫 커플 답변을 스크롤하지 않습니다.
Paul Draper

3
또한 브라우저 탭을 변경하면 focus ()가 실행됩니다.
Linnay

7
Firefox에서는 작동하지 않습니다. JSFiddle에는 이것을 숨기는 실수가 있습니다 : === 대신 =. (심지어 IE8에서) crossbrowser 솔루션이 있습니다 : stackoverflow.com/a/32138108/1064513는
드미트리 코친

8
사용자가 먼저 주 문서를 클릭하지 않으면 흐림 이벤트가 발생하지 않습니다! 또한 포커스가 한 iframe에서 다른 iframe으로 변경 될 때 발생하는 blur이벤트가 없으므로 (iframe의 이벤트가 실행되지 않음) 여러 iframe에 대한 클릭을 감지하는 데 사용할 수 없습니다.
Tomáš Kafka

1
focus ()에 의존하는 이유;
Prasad Shinde

107

Mohammed Radwan의 답변을 바탕으로 다음 jQuery 솔루션을 생각해 냈습니다. 기본적으로 iFrame 사람들이 어떤 항목을 가리키고 있는지 추적합니다. 그런 다음 창이 흐리게 표시되면 사용자가 iframe 배너를 클릭했음을 의미합니다.

사용자가 클릭 한 iframe을 알 수 있도록 iframe을 ID가있는 div에 배치해야합니다.

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

... iframe을 가리 키지 않으면 overiFrame을 -1로 유지하거나 iframe을 가리킬 때 래핑 div에 'bannerid'를 설정합니다. 다음과 같이 창이 흐리게 나타날 때 'overiFrame'이 설정되어 있는지 확인하면됩니다. ...

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

사소한 단점이있는 매우 우아한 솔루션 : 사용자가 iFrame 위로 마우스를 가져갈 때 ALT-F4를 누르면 클릭으로 기록됩니다. FireFox에서만 발생했지만 IE, Chrome 및 Safari는 등록하지 않았습니다.

매우 유용한 솔루션 인 Mohammed를 다시 한번 감사드립니다!


이 답변에는 +1이 있지만 다음과 같은 문제가 있습니다. 1. iframe이 여러 개인 경우 그 중 하나를 클릭하면 즉시 다른 하나를 클릭합니다. 두 번째 클릭은 감지되지 않습니다. 2. iframe 내부의 여러 클릭도 계산되지 않습니다. 3. 손가락으로 "호버"이벤트를 수행 할 수 없으므로 모바일에서 올바르게 작동하지 않습니다.
Sych

위의 스크립트는 내 사이트에서 발생하는 클릭을 감지하는 데 사용됩니다. 대부분의 광고 네트워크는 이제 프레임으로 배너를 제공합니다. 첫 번째 클릭을 떠나기 전에 하나를 클릭 한 다음 빠르게 다른 하나를 클릭하면 기술적으로 실제로 마지막으로 클릭 한 것을 알고 싶습니다. 그래서 제 경우에는 원하는 행동입니다. 모바일 배너의 클릭도 잘 감지합니다. 클릭이 실행되기 직전에 호버를 시작해야합니다
patrick

iframe 콘텐츠에 svg 요소의 경우 작동하지 않습니다 :( stackoverflow.com/questions/32589735/…
Serhiy

@Serhiy, iframe을 클릭 할 때 실제로 원본 페이지를 종료하지 않기 때문입니다.
patrick

6
이 답변이 가장 좋습니다. 그러나 iframe에 대한 모든 클릭을 받으려면 사용자가 클릭한 번 더 클릭하면 더 많은 클릭을 모니터링하기 위해 초점을 맞춰야 합니다. $ (window) .blur () 섹션에 추가해야합니다 setTimeout(function(){ window.focus(); }, 0);. 이제 사용자가 클릭하고 iframe에 포커스를두면 스크립트가 해당 포커스를 다시 가져오고 향후 클릭에서 추가 포커스 변경을 모니터링 할 수 있습니다.
HelpingHand

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 ID입니다. :). jsfiddle.net/oqjgzsm0/219
Tomáš Kafka

1
이 버튼을 사용하여 소셜 버튼과 같은 클릭을 추적하고 있습니다. 그러나 내가 사용하는 것 중 3/4은 iframe을 사용하기 때문에 여러 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>

iframe의 src를 자신의 링크로 교체해야합니다. 이것이 도움이되기를 바랍니다. 감사합니다.


1
빠른 테스트를 기반으로 주어진 예제 (URL 수정 후)는 IE 8에서 작동하지만 Chrome 14.0.835.186 m에서는 다소 안정적이지만 Firefox 6.0.2에서는 전혀 작동하지 않습니다.
Matthew Flaschen

Chrome에서는 제대로 작동하지만 iframe 블러 이벤트를 클릭 할 때 발생하지 않기 때문에 Firefox v62에서는 작동하지 않습니다.
slesh

11

방금이 솔루션을 찾았습니다 ... 시도해 보았습니다.

데스크톱 및 모바일 용 도메인 간 iframe에서 작동합니다!

그것이 아직 완전하지 않은지 모른다

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

행복한 코딩


2
이 같은 답변 (약간 더 나은 버전 일 수도 있음)이 같은 페이지에 1 년 전에 여기에 게시되었습니다 : stackoverflow.com/a/23231136/470749
Ryan

5

window 요소에서 blur 이벤트를 사용하여이를 달성 할 수 있습니다.

다음은 iframe 클릭을 추적하기위한 jQuery 플러그인입니다 (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

IE에서 안정적으로 작동하지 않는 긴 솔루션 은 http://jsfiddle.net/Lcy797h2/ 를 참조하십시오.

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

Mohammed Radwan, 솔루션은 우아합니다. Firefox 및 IE에서 iframe 클릭을 감지하려면 document.activeElement 및 타이머와 함께 간단한 방법을 사용할 수 있지만 Chrome 및 Safari에서 iframe의 클릭을 감지하는 방법을 웹 전체에서 검색했습니다. 포기 직전, 나는 당신의 대답을 찾습니다. 감사합니다!

몇 가지 팁 : 귀하의 솔루션이 attachOnloadEvent ()를 통하지 않고 init () 함수를 직접 호출 할 때보 다 신뢰할 수있는 것으로 나타났습니다. 물론 그렇게하려면 iframe html 이후에만 init ()를 호출해야합니다. 따라서 다음과 같이 보일 것입니다.

<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 위에 보이지 않는 레이어를 만들어 클릭하면 다시 돌아가고 마우스 리브 이벤트가 발생하면 위로 올라갑니다!
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

발견 된대로 : JavaScript를 사용하여 Iframe으로 클릭 감지

=> 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의 답변에 따라 브라우저의 다른 탭을 여는 Iframe이있을 때 지속적으로 작동하는 솔루션을 만들었습니다. 프레임 워크를 통한 클릭을 감지하기 위해 페이지를 계속 활성화하면 매우 일반적인 상황입니다.

          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에 적합합니다. window.focus 가 추가 사용자 설정 없이 작동하지 않기 때문에 @ zone117x에서 제안한 다른 방법을 사용하여 FF에 대한 iframe 클릭을 추적한다는 점을 제외하고는 대부분 접근 방식은 @Mohammed Radwan과 동일합니다 .

창을 앞으로 가져 오도록 요청합니다. 사용자 설정으로 인해 실패 할 수 있으며이 메소드가 리턴되기 전에 창이 가장 앞쪽에있는 것은 아닙니다.

복합 방법은 다음과 같습니다.

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.