Обнаружение клика в Iframe с использованием JavaScript - PullRequest
111 голосов
/ 04 марта 2010

Я понимаю, что невозможно сказать, что пользователь делает внутри iframe, если он междоменный. Я хотел бы отследить, нажал ли пользователь вообще на iframe. Я представляю себе сценарий, в котором наверху iframe есть невидимый div, и div просто передаст событие click на iframe.

Возможно ли что-то подобное? Если это так, то как бы я поступил об этом? iframes - это объявления, поэтому я не могу контролировать используемые теги.

Ответы [ 18 ]

3 голосов
/ 29 января 2014

Я столкнулся с ситуацией, когда мне приходилось отслеживать клики на кнопках социальных сетей, вставленных через 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 голосов
/ 18 сентября 2016

Это работает для меня во всех браузерах (включая 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>

2 голосов
/ 10 мая 2016

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

Просто создайте невидимый слой поверх фрейма, который будет возвращаться при щелчке и подниматься, когда будет запущено событие 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 голос
/ 07 апреля 2012

Это определенно работает, если 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']).mousedown(function(event){   
  var eventId = $(event.target).attr('id');      
  if (eventId == 'the-id-you-want') {
   //  do something
  }
});
0 голосов
/ 04 октября 2018

Вот решение, использующее предложенные подходы с трюками hover + blur и active element, а не какие-либо библиотеки, только чистый 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 голосов
/ 25 августа 2018

Основываясь на ответе Пола Дрейпера, я создал решение, которое работает непрерывно, когда у вас есть 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();
            }
        });

Код прост: событие размытия обнаруживает потерю фокуса при щелчке по фрейму и проверяет, является ли активный элемент фреймом (если у вас есть несколько фреймов, вы можете знать, кто был выбран), такая ситуация часто возникает, когда вы есть рекламные рамки.

Второе событие вызывает метод фокусировки при возврате на страницу. используется событие изменения видимости.

0 голосов
/ 21 января 2018

Как там найдено: Обнаружение клика в 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 голосов
/ 12 июля 2011

Я считаю, что вы можете сделать что-то вроде:

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

с помощью jQuery для этого.

...