it-swarm.com.de

Erkennen Sie das Klicken in Iframe mithilfe von JavaScript

Ich verstehe, dass es nicht möglich ist zu erkennen, was der Benutzer in einer iframe tut, wenn es sich um eine domänenübergreifende Domäne handelt. Was ich tun möchte, ist zu verfolgen, ob der Benutzer überhaupt auf die Variable iframe geklickt hat. Ich stelle mir ein Szenario vor, in dem sich eine unsichtbare div auf der iframe befindet und die div das Click-Ereignis dann an die iframe übergeben. 

Ist so etwas möglich? Wenn ja, wie würde ich dann vorgehen? Die iframes sind Anzeigen, daher habe ich keine Kontrolle über die verwendeten Tags.

103
Russ Bradberry

Ist so etwas möglich?

Nein. Alles, was Sie tun können, ist zu erkennen, wie die Maus in den iframe geht, und möglicherweise (wenn auch nicht zuverlässig), wenn sie wieder herauskommt (z. B. versuchen, den Unterschied zwischen dem Zeiger zu ermitteln, der die Anzeige auf einem anderen Weg passiert, im Vergleich zum Verweilen auf der Anzeige).

Ich stelle mir ein Szenario vor, in dem sich ein unsichtbares div über dem iframe befindet und das div das click -Ereignis dann an den iframe übergeben wird.

Nein, es gibt keine Möglichkeit, ein Klickereignis zu fälschen.

Indem Sie die Maus abfangen, verhindern Sie, dass der ursprüngliche Klick in den Iframe gelangt. Wenn Sie bestimmen könnten, wann die Maustaste gedrückt werden sollte, könnten Sie versuchen, das unsichtbare Div aus dem Weg zu räumen, damit der Klick durchgeht ... aber es gibt auch kein Ereignis, das unmittelbar vor einem Mausedown ausgelöst wird.

Sie könnten versuchen zu raten, indem Sie beispielsweise nachsehen, ob der Zeiger zur Ruhe gekommen ist. Vermutlich ist ein Klick zu erwarten. Aber es ist absolut unzuverlässig, und wenn Sie versagen, haben Sie sich selbst einen Klick verloren.

36
bobince

Das ist sicherlich möglich. Dies funktioniert in Chrome, Firefox und IE 11 (und wahrscheinlich auch anderen).

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

JSFiddle


Achtung: Dies erkennt nur den ersten Klick. Soweit ich weiß, ist das alles, was Sie wollen.

116
Paul Draper

Basierend auf Mohammed Radwans Antwort kam ich mit der folgenden jQuery-Lösung. Im Grunde behalten Sie den Überblick darüber, was iFrame-Leute gerade halten. Wenn das Fenster verschwimmt, bedeutet dies höchstwahrscheinlich, dass der Benutzer auf das iframe-Banner geklickt hat.

der Iframe sollte in ein Div mit einer ID eingefügt werden, um sicherzustellen, dass Sie wissen, auf welchen Iframe der Benutzer geklickt hat:

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

so:

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

... Dies hält overiFrame auf -1, wenn keine iFrames schwebend sind, oder die 'bannerid', die im Umbruch-div festgelegt ist, wenn ein iframe schwebend ist. Alles, was Sie tun müssen, ist zu prüfen, ob 'overiFrame' eingestellt ist, wenn das Fenster wie folgt verwischt: ...

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

Sehr elegante Lösung mit einem kleinen Nachteil: Wenn ein Benutzer ALT-F4 drückt, wenn Sie den Mauszeiger über einen iFrame bewegen, wird er als Klick protokolliert. Dies geschah jedoch nur bei FireFox, IE, Chrome und Safari registrierten es jedoch nicht. 

Nochmals vielen Dank, Mohammed, sehr nützliche Lösung!

103
patrick

Dies ist eine kleine Lösung, die in allen Browsern funktioniert, auch im IE8:

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

Sie können es hier testen: http://jsfiddle.net/oqjgzsm0/

71
Dmitry Kochin

Der folgende Code zeigt an, ob der Benutzer auf den iframe klickt/bewegt oder ihn verlässt: -

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

Sie müssen die src im iframe durch Ihren eigenen Link ersetzen. Ich hoffe, das wird helfen .... Grüße.... Mo.

35
Mohammed Radwan

Ich habe diese Lösung gefunden ... Ich habe es versucht, ich habe es geliebt.

Funktioniert für domänenübergreifende Iframes für Desktop und Mobile!

Weiß nicht, ob es noch narrensicher ist

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

Glückliche Kodierung

10
Tony

siehe http://jsfiddle.net/Lcy797h2/ für meine langatmige Lösung, die im IE nicht zuverlässig funktioniert

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

Sie können dies erreichen, indem Sie das Blur-Ereignis für das Fensterelement verwenden.

Hier ist ein jQuery-Plugin zum Verfolgen von Klicken auf Iframes (es wird eine benutzerdefinierte Rückruffunktion ausgelöst, wenn ein Iframe angeklickt wird): https://github.com/finalclap/iframeTracker-jquery

Verwenden Sie es so:

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

Mohammed Radwan, ... Ihre Lösung ist elegant. Um iframe-Klicks in Firefox und IE zu erkennen, können Sie eine einfache Methode mit document.activeElement und einen Timer verwenden. Allerdings habe ich in allen Interwebs nach einer Methode gesucht, um Klicks auf einem iframe in Chrome und Safari zu erkennen. Am Rande des Aufgebens finde ich Ihre Antwort. Danke mein Herr!

Einige Tipps: Ich habe festgestellt, dass Ihre Lösung zuverlässiger ist, wenn Sie die init () - Funktion direkt aufrufen, anstatt über attachOnloadEvent (). Natürlich müssen Sie init () nur nach dem iframe-HTML-Code aufrufen. Es würde also ungefähr so ​​aussehen:

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

Dies funktioniert für mich in allen Browsern (enthaltenes 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
sidanmor

Ich bin in eine Situation geraten, in der ich Klicks auf einen Social-Media-Button verfolgen musste, der durch einen Iframe eingezogen wurde. Ein neues Fenster wird geöffnet, wenn Sie auf die Schaltfläche klicken. Hier war meine Lösung:

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

Sie können dies tun, um Ereignisse in das übergeordnete Dokument zu blasen:

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

Erweitern Sie einfach die Ereignisliste für weitere Ereignisse.

3
Taner Topal

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

Machen Sie einfach eine unsichtbare Ebene über dem Iframe, die beim Klicken zurückgeht, und gehen Sie nach oben, wenn das Mouseleave-Ereignis ausgelöst wird !!
Brauchen Sie jQuery

diese Lösung verbreite nicht den ersten Klick innerhalb von 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>

2
r1si

Dies funktioniert definitiv, wenn der iframe aus derselben Domäne stammt wie Ihre übergeordnete Site. Ich habe es nicht für domänenübergreifende Sites getestet.

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

Ohne jQuery könnte man so etwas versuchen, aber ich habe es noch nicht probiert.

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

Sie können sogar Ihre Ergebnisse filtern:

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

Wie dort zu finden: Detect Click in Iframe mit JavaScript

=> Wir können iframeTracker-jquery verwenden:

$('.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
Mickaël

Hier ist eine Lösung mit vorgeschlagenen Ansätzen mit Schwebeflug + Unschärfe und aktiven Elementtricks, keine Bibliotheken, nur reine js. Funktioniert gut für FF/Chrome. Meistens ist die Vorgehensweise identisch mit der von @Mohammed Radwan vorgeschlagenen Methode, mit der Ausnahme, dass ich die von @ zone117x vorgeschlagene Methode zum Verfolgen von iframe-Klicks für FF verwende, da window.focus nicht ohne Zusatz Benutzereinstellungen funktioniert:

Fordert das Fenster nach vorne. Es kann aufgrund von .__ fehlschlagen. Benutzereinstellungen und es ist nicht garantiert, dass sich das Fenster vor .__ befindet. diese Methode kehrt zurück.

Hier ist die zusammengesetzte Methode:

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
slesh

Ich glaube, du kannst so etwas tun:

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

verwenden Sie dazu jQuery.

0
Daniel Sellers

Basierend auf der Antwort von Paul Draper habe ich eine Lösung entwickelt, die kontinuierlich funktioniert, wenn Sie über Iframes verfügen, die andere Registerkarten im Browser öffnen. Wenn Sie die Seite weiterhin aktiv anzeigen, um das Klicken über das Framework zu erkennen, ist dies eine sehr häufige Situation:

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

Der Code ist einfach, das Unschärfereignis erkennt den Fokusverlust, wenn der Iframe angeklickt wird, und testet, ob das aktive Element der Iframe ist (wenn Sie mehrere Iframes haben, wissen Sie, wer ausgewählt wurde) .

Das zweite Ereignis löst eine Fokusmethode aus, wenn Sie zur Seite zurückkehren. Es wird das Ereignis zum Ändern der Sichtbarkeit verwendet.

0
freedeveloper