Domanda

ho capito che non è possibile dire ciò che l'utente sta facendo all'interno di un iframe se è di dominio croce. Quello che vorrei fare è monitorare se l'utente fa clic a tutti nella iframe. Immagino uno scenario in cui v'è una div invisibile sulla parte superiore del iframe e la div sarà solo quindi passare l'evento click al iframe.

E 'qualcosa di simile a questo possibile? Se lo è, allora come potrei fare a questo proposito? Il iframes sono annunci, quindi non ho alcun controllo sui tag che vengono utilizzati.

È stato utile?

Soluzione

  

E 'qualcosa di simile a questo possibile?

No. Tutto quello che puoi fare è di rilevare il mouse andare in iframe, e potenzialmente (anche se non in modo affidabile) quando si tratta di nuovo fuori (es. Cercando di capire la differenza tra il puntatore passa sopra l'annuncio sulla sua strada da qualche altra parte contro persistente sul annuncio).

  

Mi immagino uno scenario in cui c'è un div invisibile sulla parte superiore del iframe e il div sarà solo quindi passare l'evento click per l'iframe.

No, non c'è modo di falsificare un evento click.

Per la cattura del mousedown che ci impedisce l'originale click di raggiungere l'iframe. Se si potesse determinare quando il pulsante del mouse stava per essere premuto si potrebbe cercare di ottenere il div invisibile fuori del modo in modo che il clic sarebbe passare attraverso ... ma c'è anche nessun caso che gli incendi appena prima di un mousedown.

Si potrebbe provare a indovinare, ad esempio, cercando di vedere se il puntatore è venuto a riposare, indovinare un click potrebbe essere sul punto di venire. Ma è del tutto inaffidabile, e se non si riesce hai solo te stesso perso un click-through.

Altri suggerimenti

Questa è certamente possibile. Questo funziona in Chrome, Firefox, e IE (e probabilmente altri) 11.

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

JSFiddle


Caveat: Questo rileva solo al primo scatto. Mi pare di capire, che è tutto quello che vuoi.

In base a risposta di Mohammed Radwan mi si avvicinò con la seguente soluzione jQuery. Fondamentalmente ciò che fa è tenere traccia di quello iFrame persone sono in bilico. Poi, se le sfocature finestra che molto probabilmente significa che l'utente cliccato il banner iframe.

l'iframe dovrebbe essere messo in un div con un id, per assicurarsi di sapere che iframe l'utente fa clic su:

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

così:

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

... questo mantiene overiFrame a -1 quando non sono iFrames libravano, o 'bannerid' insieme nel div avvolgimento quando un iframe gli passa. Tutto quello che dovete fare è controllare se 'overiFrame' è impostato quando lo sfocature finestra, in questo modo: ...

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

soluzione molto elegante con un minore rovescio della medaglia: se un utente preme ALT-F4 quando si passa il mouse su un iFrame si registrerà come un click. Questo è accaduto solo in Firefox, però, IE, Chrome e Safari non hanno registrato esso.

Grazie ancora Mohammed, soluzione molto utile!

Questa è piccola soluzione che funziona in tutti i browser, anche IE8:

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

È possibile verificare qui: http://jsfiddle.net/oqjgzsm0/

Il codice seguente vi mostrerà se l'utente clicca / hover o spostare fuori dalla 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>

È necessario sostituire lo src del iframe con il proprio collegamento. Spero che questo vi aiuterà. Saluti, Mo.

Appena trovato questa soluzione ... Ho provato, mi è piaciuto ..

Opere per iframe dominio trasversali per desktop e! Mobili

Non so se è infallibile ancora

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

codifica Felice

È possibile raggiungere questo obiettivo utilizzando l'evento sfocatura elemento della finestra.

Ecco un plugin jQuery per il monitoraggio click sul iframe (che verrà generato una funzione di callback personalizzata quando un IFRAME si fa clic): https://github.com/finalclap/iframeTracker-jquery

Usa in questo modo:

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

http://jsfiddle.net/Lcy797h2/ per la mia soluzione prolisso che non lo fa funzionare in modo affidabile 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, La vostra soluzione è elegante. Per rilevare iframe scatta in Firefox e IE, è possibile utilizzare un metodo semplice con document.activeElement e un timer, però ... Ho cercato in tutto l'interwebs per un metodo per rilevare i clic su un iframe in Chrome e Safari. Al punto di rinunciare, ho trovato la risposta. Grazie, signore!

Alcuni consigli: Ho trovato la soluzione per essere più affidabile quando si chiama la funzione init () direttamente, piuttosto che attraverso attachOnloadEvent (). Naturalmente per fare questo, è necessario chiamare init () solo dopo che il codice HTML iframe. Quindi sarebbe simile:

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

Si può fare questo ad eventi bolla al documento principale:

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

Basta estendere l'EventList per più eventi.

mi sono imbattuto in una situazione in cui ho dovuto monitorare i clic su un pulsante social media tirato attraverso un iframe. Una nuova finestra potrebbe essere aperto quando il pulsante è stato premuto. Qui era la mia soluzione:

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

Questo funziona per me su tutti i browser (incluso 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/

Basta fare uno strato invisibile sopra l'iframe che vanno indietro quando cliccare e andare su quando sarà licenziato evento mouseLeave !!
Necessità jQuery

questa soluzione non si propagano primo clic all'interno 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>

Questo funziona sicuramente se l'iframe è dallo stesso dominio come il vostro sito padre. Non ho ancora testato per i siti cross-domain.

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

Senza jQuery si potrebbe provare qualcosa di simile, ma ancora una volta non ho provato questo.

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

È anche possibile filtrare i risultati:

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

Io credo che si può fare qualcosa di simile:

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

utilizzando jQuery per raggiungere questo obiettivo.

Per quanto trovato lì: rilevare Clicca in Iframe utilizzando JavaScript

=> Possiamo usare 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');
    }
})

In base nella risposta di Paul Draper, ho creato una soluzione che opera continuamente quando si ha Iframe che aprono un'altra scheda nel browser. Quando si torna alla pagina continuerà ad essere attivo per rilevare il clic sopra il quadro, questa è una situazione molto comune:

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

Il codice è semplice, l'evento sfocatura di rilevare la perdita di messa a fuoco quando l'iframe viene cliccato, e verificare se l'elemento attivo è l'iframe (se si dispone di più iframe si può sapere che è stato selezionato) questa situazione è frequente quando si hanno cornici pubblicità.

Il secondo trigger dell'evento un metodo di messa a fuoco quando si torna alla pagina. viene utilizzato l'evento di modifica visibilità.

Ecco la soluzione utilizzando approcci suggeriti con hover + sfocatura e trucchi elemento attivo, non tutte le librerie, a soli js puri. Funziona bene per FF / Chrome. Per lo più approache è lo stesso come proposto @Mohammed Radwan, se non che io uso diversa metodologia proposta da @ zone117x per tenere traccia iframe clicca per FF, perché window.focus non funziona senza aggiunta impostazioni utente :

  

fa una richiesta per portare la finestra in primo piano. Si potrebbe non riuscire a causa di   le impostazioni utente e la finestra non è garantito di essere in primo piano prima di   Questo metodo restituisce.

Ecco metodo composto:

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

La combinazione di sopra di risposta con possibilità di cliccare più volte senza fare clic iframe fuori.

    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 );
    });
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top