Detect Klicken Sie in Iframe mit JavaScript
-
24-09-2019 - |
Frage
Ich verstehe, dass es nicht möglich ist, zu sagen, was der Benutzer innerhalb eines iframe
tut, wenn es Cross-Domain ist. Was ich möchte, ist tun zu verfolgen, wenn der Benutzer überhaupt in den iframe
geklickt. Ich stelle mir ein Szenario, in dem es eine unsichtbare div
auf dem iframe
ist und der div
wird nur dann das Click-Ereignis auf den iframe
passieren.
Ist so etwas möglich? Wenn ja, dann wie würde ich über sie gehen? Die iframes
sind Anzeigen, so dass ich keine Kontrolle über die Tags, die verwendet werden.
Lösung
Ist so etwas möglich?
Nein. Alles, was Sie tun können, ist die Maus geht in die iframe erkennen und möglicherweise (aber nicht zuverlässig), wenn er wieder herauskommt (dh. Versuch über die Anzeige irgendwo anders auf dem Weg auf dem im Vergleich zu verweilenden Bestehen der Differenz zwischen dem Zeiger zu arbeiten, ad).
ich ein Szenario vorstellen, in dem es eine unsichtbare div auf der Oberseite des iframe und das div wird nur dann das Click-Ereignis auf die iframe übergeben.
Nein, es gibt keine Möglichkeit zu fälschen Click-Ereignis.
Mit dem MouseDown- fangen Sie den Original-Klick immer auf die iframe verhindern würden. Wenn Sie könnten bestimmen, wenn die Maustaste über war gedrückt werden Sie die unsichtbaren div aus dem Weg zu räumen könnten versuchen, so dass der Klick durchlaufen würde ... aber es gibt auch kein Ereignis, das ausgelöst wird kurz vor einem mousedown-.
Sie könnten versuchen, zum Beispiel zu erraten, indem Sie sehen, ob der Zeiger zur Ruhe gekommen ist, einen Klick erraten könnte, darüber zu kommen. Aber es ist völlig unzuverlässig, und wenn man Sie nicht haben, sich gerade verloren einen Click-through.
Andere Tipps
Dies ist sicherlich möglich. Dies funktioniert in Chrome, Firefox und IE 11 (und wahrscheinlich auch andere).
focus();
var listener = window.addEventListener('blur', function() {
if (document.activeElement === document.getElementById('iframe')) {
// clicked
}
window.removeEventListener('blur', listener);
});
Caveat: Dies erkennt nur den ersten Klick. Wie ich verstehe, das ist alles, was Sie wollen.
Auf der Grundlage von Mohammed Radwan Antwort kam ich mit der folgenden jQuery-Lösung auf. Im Grunde, was es tut, ist zu verfolgen, was iFrame Menschen schweben. Dann, wenn die Fenster Unschärfen, die am ehesten mittels der Benutzer die iframe Banner angeklickt wird.
die iframe sollte mit einer ID in einem div gesetzt werden, um sicherzustellen, dass Sie wissen, welche iframe der Benutzer angeklickt:
<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 bei -1, wenn keine iFrames sind schweben, oder das ‚bannerid‘ Set in der Verpackung div, wenn ein iframe schwebte wird. Alles, was Sie tun müssen, ist zu überprüfen, ob ‚overiFrame‘ gesetzt, wenn das Fenster Unschärfen, wie so ist: ...
$(window).blur( function() {
if( overiFrame != -1 )
$.post('log.php', {id:overiFrame}); /* example, do your stats here */
});
});
Sehr elegante Lösung mit einem kleinen Nachteile: Wenn ein Benutzer drückt ALT-F4, wenn die Maus über einen iFrame schweben wird es als Klick anmelden. Dies aber nur in FireFox passiert, IE, Chrome und Safari haben es nicht registrieren.
Danke nochmals Mohammed, sehr nützliche Lösung!
Dies ist kleine Lösung, die funktioniert in allen Browsern sogar 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/
Der folgende Code wird Ihnen zeigen, wenn der Benutzer klicken / schweben oder verschieben aus dem 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>
Sie müssen die src in dem Iframe mit Ihrem eigenen Link zu ersetzen. Hoffe, das wird helfen. Grüße, Mo.
gefunden Gerade diese Lösung ... Ich versuchte es, ich habe es geliebt ..
Arbeiten für Cross-Domain-Iframes für Desktop- und mobile!
Sie wissen nicht, ob es narrensicher ist noch
window.addEventListener('blur',function(){
if(document.activeElement.id == 'CrossDomainiframeId'){
//do something :-)
}
});
Happy Codierung
Sie können dies erreichen, indem die Unschärfe Ereignis auf Fensterelement verwendet wird.
Hier ist eine jQuery-Plugin für die Verfolgung Klick auf Iframes (es wird eine benutzerdefinierte Callback-Funktion ausgelöst, wenn ein iframe geklickt wird): https://github.com/finalclap/iframeTracker-jquery
Verwenden Sie es wie folgt aus:
jQuery(document).ready(function($){
$('.iframe_wrap iframe').iframeTracker({
blurCallback: function(){
// Do something when iframe is clicked (like firing an XHR request)
}
});
});
finden Sie unter http://jsfiddle.net/Lcy797h2/ für meine lange umständliche Lösung tut das nicht arbeiten zuverlässig in 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();
Mohammed Radwan, Ihre Lösung ist elegant. Zur Erkennung iframe klickt in Firefox und IE, können Sie eine einfache Methode mit document.activeElement verwenden und einem Timer, aber ... Ich habe alle über den interwebs nach einem Verfahren gesucht, die Klicks auf einem Iframe in Chrome und Safari zu erkennen. Am Rande des Aufgebens, finde ich Ihre Antwort. Vielen Dank, Sir!
Einige Tipps: Ich habe Ihre Lösung zu sein zuverlässiger beim Aufruf der Funktion init () direkt, anstatt durch attachOnloadEvent () gefunden. Natürlich, das zu tun, müssen Sie rufen init () erst nach dem iframe html. So ist es so etwas wie 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>
Sie können dies tun, um Blase Ereignisse übergeordnetes Dokument:
$('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 Veranstaltungen.
Ich lief in eine Situation, wo ich Klicks auf einer Social-Media-Taste verfolgen musste gezogen durch einen iframe. Ein neues Fenster würde geöffnet werden, wenn die Schaltfläche geklickt wurde. 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();
Dies funktioniert für mich auf allen Browsern (inklusive 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>
http://jsfiddle.net/QcAee/406/
Machen Sie eine unsichtbare Schicht über dem iframe, die zurück gehen, wenn Sie auf und gehen Sie auf, wenn mouseleave Event wird gefeuert werden !!
Need jQuery
diese Lösung nicht weitergegeben ersten Klick innerhalb 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>
Das funktioniert auf jeden Fall, wenn der iframe aus der gleichen Domäne wie Ihr übergeordneten Standort ist. Ich habe es nicht getestet für Cross-Domain-Websites.
$(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 wie dies versucht, aber auch hier habe ich nicht versucht.
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
}
});
Ich glaube, man kann so etwas tun:
$('iframe').contents().click(function(){function to record click here });
jQuery verwenden, dies zu erreichen.
gefunden Da es: Detect Klicken Sie in Iframe mit JavaScript
=> Wir verwenden 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');
}
})
Auf der Grundlage der Antwort von Paul Draper, habe ich eine Lösung, dass die Arbeit kontinuierlich, wenn Sie Iframes, dass offene andere Registerkarte im Browser. Wenn Sie die Seite zurückkehren, das Klicken auf dem Rahmen, aktiv sein weiterhin 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 Kodex einfach ist, erkennen die Unschärfe Ereignis der Fokus verloren, wenn der iframe geklickt wird, und testen, ob das aktive Element der iframe ist (wenn Sie mehrere iframe haben, können Sie wissen, wer ausgewählt wurde) ist diese Situation häufig, wenn Sie haben Werberahmen.
Der zweite Ereignis-Trigger kann eine Fokusmethode, wenn Sie auf der Seite zurück. es wird die Sichtbarkeit Änderungsereignis verwendet.
Hier Lösung vorgeschlagen Ansätze mit Hover + Unschärfe und aktives Element Tricks, keine Bibliotheken, nur reine js. Adaequat für FF / Chrome. approache ist meist gleich wie @Mohammed Radwan vorgeschlagen, mit der Ausnahme, dass ich andere Methode verwenden, vorgeschlagen von @ zone117x iframe für FF klicken zu verfolgen, weil window.focus funktioniert nicht ohne Zusatz Benutzereinstellungen :
eine Anforderung aus dem Fenster nach vorne zu bringen. Es kann auf Grund scheitern Benutzereinstellungen und das Fenster wird nicht vorderste garantiert, bevor sein Diese Methode gibt.
Hier ist die Verbindung 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;
});
}
}
oben Antwort mit der Möglichkeit, die Kombination immer wieder zu klicken, ohne außerhalb iframe klicken.
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 );
});