Rozumiem, że nie można stwierdzić, co użytkownik robi wewnątrz iframe
domeny, jeśli jest to międzydomenowe. Chciałbym śledzić, czy użytkownik w ogóle kliknął w iframe
. I wyobrazić sobie scenariusz, w którym nie jest niewidoczny div
na szczycie iframe
i The div
będą tylko wtedy przejść do zdarzenia click iframe
.
Czy coś takiego jest możliwe? Jeśli tak, to jak bym się do tego zabrał? iframes
Są reklamy, więc nie mam żadnej kontroli nad tagów, które są używane.
javascript
iframe
ads
dom-events
click-tracking
Russ Bradberry
źródło
źródło
Odpowiedzi:
Nie. Wszystko, co możesz zrobić, to wykryć mysz wchodzącą w ramkę iframe i potencjalnie (choć nie niezawodnie), kiedy wraca (np. Próbując ustalić różnicę między wskaźnikiem przechodzącym nad reklamą w drodze w innym miejscu a utrzymującym się w reklamie).
Nie, nie ma sposobu, aby sfałszować kliknięcie.
Wyłapując przycisk myszy, zapobiegasz przedostawaniu się oryginalnego kliknięcia do elementu iframe. Gdybyś mógł określić, kiedy przycisk myszy ma zostać naciśnięty, możesz spróbować usunąć niewidoczny element div z drogi, aby kliknięcie przeszło ... ale nie ma też zdarzenia, które uruchamia się tuż przed ruchem myszy.
Możesz spróbować zgadnąć, na przykład patrząc, czy wskaźnik zatrzymał się, domyślając się, że wkrótce nastąpi kliknięcie. Ale jest to całkowicie niewiarygodne, a jeśli ci się nie uda, po prostu stracisz kliknięcie.
źródło
Jest to z pewnością możliwe. Działa to w Chrome, Firefox i IE 11 (i prawdopodobnie innych).
focus(); var listener = window.addEventListener('blur', function() { if (document.activeElement === document.getElementById('iframe')) { // clicked } window.removeEventListener('blur', listener); });
JSFiddle
Uwaga: wykrywa tylko pierwsze kliknięcie. Jak rozumiem, to wszystko, czego chcesz.
źródło
blur
zdarzenie iframe nie jest uruchamiane).Na podstawie odpowiedzi Mohammeda Radwana wymyśliłem następujące rozwiązanie jQuery. Zasadniczo śledzi to, co ludzie iFrame unoszą. Jeśli okno się rozmywa, najprawdopodobniej oznacza to, że użytkownik kliknął baner iframe.
element iframe należy umieścić w elemencie div z identyfikatorem, aby upewnić się, że wiesz, który element iframe kliknął użytkownik:
<div class='banner' bannerid='yyy'> <iframe src='http://somedomain.com/whatever.html'></iframe> <div>
więc:
$(document).ready( function() { var overiFrame = -1; $('iframe').hover( function() { overiFrame = $(this).closest('.banner').attr('bannerid'); }, function() { overiFrame = -1 });
... to utrzymuje overiFrame na poziomie -1, gdy żadne elementy iFrame nie są najechane, lub „bannerid” ustawiony w opakowującym elemencie div, gdy element iframe jest najechany. Wszystko, co musisz zrobić, to sprawdzić, czy 'overiFrame' jest ustawione, gdy okno się rozmywa, na przykład: ...
$(window).blur( function() { if( overiFrame != -1 ) $.post('log.php', {id:overiFrame}); /* example, do your stats here */ }); });
Bardzo eleganckie rozwiązanie z niewielką wadą: jeśli użytkownik naciśnie klawisz ALT-F4 podczas najeżdżania myszą na ramkę iFrame, zarejestruje to jako kliknięcie. Stało się to jednak tylko w FireFox, IE, Chrome i Safari go nie zarejestrowały.
Jeszcze raz dziękuję Mohammed, bardzo przydatne rozwiązanie!
źródło
setTimeout(function(){ window.focus(); }, 0);
. Teraz użytkownik klika, umieszcza fokus w elemencie iframe, skrypt cofa fokus z powrotem i może teraz monitorować dalsze zmiany fokusu od przyszłych kliknięć.To małe rozwiązanie, które działa we wszystkich przeglądarkach nawet IE8:
var monitor = setInterval(function(){ var elem = document.activeElement; if(elem && elem.tagName == 'IFRAME'){ clearInterval(monitor); alert('clicked!'); } }, 100);
Możesz to przetestować tutaj: http://jsfiddle.net/oqjgzsm0/
źródło
Poniższy kod pokaże Ci, czy użytkownik kliknie / najedzie kursorem lub wyjdzie z ramki 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>
Musisz zastąpić src w ramce iframe własnym linkiem. Mam nadzieję, że to pomoże. Pozdrawiam, Mo.
źródło
Właśnie znalazłem to rozwiązanie ... Wypróbowałem, pokochałem ...
Działa dla międzydomenowych ramek iframe na komputery i urządzenia mobilne!
Nie wiem, czy jest jeszcze niezawodny
window.addEventListener('blur',function(){ if(document.activeElement.id == 'CrossDomainiframeId'){ //do something :-) } });
Miłego kodowania
źródło
Możesz to osiągnąć za pomocą zdarzenia blur na elemencie okna.
Oto wtyczka jQuery do śledzenia kliknięć w elementach iframe (uruchomi niestandardową funkcję zwrotną po kliknięciu elementu iframe): https://github.com/finalclap/iframeTracker-jquery
Użyj tego w ten sposób:
jQuery(document).ready(function($){ $('.iframe_wrap iframe').iframeTracker({ blurCallback: function(){ // Do something when iframe is clicked (like firing an XHR request) } }); });
źródło
zobacz http://jsfiddle.net/Lcy797h2/ dla mojego rozwlekłego rozwiązania, które nie działa niezawodnie w 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();
źródło
Działa to dla mnie we wszystkich przeglądarkach (w tym 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>
źródło
Mohammed Radwan, Twoje rozwiązanie jest eleganckie. Aby wykryć kliknięcia iframe w Firefoksie i IE, możesz użyć prostej metody z document.activeElement i licznikiem czasu, jednak ... Przeszukałem wszystkie interweb w poszukiwaniu metody wykrywania kliknięć w ramce iframe w Chrome i Safari. Na skraju rezygnacji znajduję twoją odpowiedź. Dziękuję Panu!
Kilka wskazówek: Odkryłem, że Twoje rozwiązanie jest bardziej niezawodne podczas bezpośredniego wywoływania funkcji init (), a nie przez attachOnloadEvent (). Oczywiście, aby to zrobić, musisz wywołać init () tylko po elemencie iframe html. Więc wyglądałoby to mniej więcej tak:
<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>
źródło
Możesz to zrobić, aby przenieść wydarzenia do dokumentu nadrzędnego:
$('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); }); });
Po prostu rozszerz listę wydarzeń o więcej wydarzeń.
źródło
Znalazłem się w sytuacji, w której musiałem śledzić kliknięcia przycisku mediów społecznościowych przeciągniętego przez element iframe. Po kliknięciu przycisku zostanie otwarte nowe okno. Oto moje rozwiązanie:
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();
źródło
http://jsfiddle.net/QcAee/406/
Po prostu utwórz niewidoczną warstwę na ramce iframe, która cofa się po kliknięciu i podnosi się, gdy zdarzenie mouseleave zostanie uruchomione !!
Potrzebujesz jQuery
to rozwiązanie nie propaguje pierwszego kliknięcia wewnątrz elementu 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>
źródło
To z pewnością działa, jeśli element iframe pochodzi z tej samej domeny, co Twoja witryna nadrzędna. Nie testowałem go pod kątem witryn międzydomenowych.
$(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 */ });
Bez jQuery mógłbyś spróbować czegoś takiego, ale znowu tego nie próbowałem.
window.frames['YouriFrameId'].onmousedown = function() { do something here }
Możesz nawet filtrować wyniki:
$(window.frames['YouriFrameId']).mousedown(function(event){ var eventId = $(event.target).attr('id'); if (eventId == 'the-id-you-want') { // do something } });
źródło
Połączenie powyższej odpowiedzi z możliwością wielokrotnego klikania bez klikania poza ramką 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 ); });
źródło
Możemy złapać wszystkie kliknięcia. Chodzi o to, aby po każdym kliknięciu zresetować fokus na elemencie poza 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
źródło
Wierzę, że możesz zrobić coś takiego:
$('iframe').contents().click(function(){function to record click here });
używając jQuery, aby to osiągnąć.
źródło
Jak tam znaleziono: Wykryj kliknięcie w ramkę iframe za pomocą JavaScript
=> Możemy użyć 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'); } })
źródło
Opierając się na odpowiedzi Paula Drapera, stworzyłem rozwiązanie, które działa nieprzerwanie, gdy masz ramki iframe otwierające inne karty w przeglądarce. Po powrocie strona nadal jest aktywna, aby wykryć kliknięcie w ramach, jest to bardzo częsta sytuacja:
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(); } });
Kod jest prosty, zdarzenie rozmycia wykrywa utratę fokusu po kliknięciu elementu iframe i sprawdza, czy aktywnym elementem jest iframe (jeśli masz kilka elementów iframe, możesz wiedzieć, kto został wybrany) taka sytuacja często występuje, gdy masz ramki reklamowe .
Drugie zdarzenie wyzwala metodę fokusu po powrocie na stronę. jest używane jako zdarzenie zmiany widoczności.
źródło
Oto rozwiązanie wykorzystujące sugerowane podejścia z hover + blur i triki z aktywnymi elementami, a nie żadne biblioteki, tylko czysty js. Działa dobrze na FF / Chrome. Przeważnie podejście jest takie samo, jak zaproponował @Mohammed Radwan, z wyjątkiem tego, że używam innej metody proponowanej przez @ zone117x do śledzenia kliknięć iframe dla FF, ponieważ window.focus nie działa bez dodatkowych ustawień użytkownika :
Oto metoda złożona:
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; }); } }
źródło
Założenia -
Działa to zarówno w przypadku ramek iframe źródłowych, jak i bezkośnych
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"); } });
Jeśli nowa karta jest otwarta / ta sama strona zostaje rozładowana, a wskaźnik myszy znajduje się w ramce iframe, uważa się, że kliknięcie
źródło