Обнаружение щелчка в Iframe с помощью JavaScript
Я понимаю, что невозможно сказать, что пользователь делает внутри iframe Если это крест домена. То, что я хотел бы сделать, это отслеживать, если пользователь нажал на все в iframe. Я представляю себе сценарий, где есть невидимый div сверху iframe и div просто передаст событие click в iframe.
возможно ли что-то подобное? Если это так, то как бы я это сделал? Элемент iframes являются объявления, так что я не имею никакого контроля над теги, которые используются.
18 ответов:
возможно ли что-то подобное?
нет. Все, что вы можете сделать, это обнаружить мышь, входящую в iframe, и потенциально (хотя и не надежно), когда она возвращается (т. е. попытка выяснить разницу между указателем, проходящим над объявлением на своем пути куда-то еще, и задержкой на объявлении).
Я представляю себе сценарий, в котором есть невидимый div поверх iframe, и div просто передаст событие click в iframe фрейм.
нет,нет никакого способа подделать событие щелчка.
поймав mousedown вы бы предотвратить оригинальный щелчок от попадания в iframe. Если бы вы могли определить, когда кнопка мыши должна была быть нажата, вы могли бы попытаться убрать невидимый div с пути, чтобы щелчок прошел... но также нет события, которое срабатывает непосредственно перед mousedown.
вы можете попробовать угадать, например, посмотрев, есть ли указатель приходите отдохнуть, предполагая, что щелчок может вот-вот прийти. Но это совершенно ненадежно, и если вы потерпите неудачу, вы просто потеряли себя щелчком мыши.
на основе ответа Мохаммеда Радвана я придумал следующее решение jQuery. В основном то, что он делает, - это отслеживать, что люди iframe парят. Затем, если окно размывается, что, скорее всего, означает, что пользователь нажал баннер iframe.
iframe должен быть помещен в div с идентификатором, чтобы убедиться, что вы знаете, какой iframe пользователь нажал на:
<div class='banner' bannerid='yyy'> <iframe src='http://somedomain.com/whatever.html'></iframe> <div>так:
$(document).ready( function() { var overiFrame = -1; $('iframe').hover( function() { overiFrame = $(this).closest('.banner').attr('bannerid'); }, function() { overiFrame = -1 });... это сохраняет overiFrame в -1, когда никакие iFrames не зависают, или 'bannerid' устанавливается в обертку div, когда iframe завис. Все, что вам нужно сделать, это проверить, установлен ли "overiFrame", когда окно размывается, например: ...
$(window).blur( function() { if( overiFrame != -1 ) $.post('log.php', {id:overiFrame}); /* example, do your stats here */ }); });очень элегантное решение с небольшим недостатком: если пользователь нажимает ALT-F4 при наведении мыши на iFrame, он будет регистрировать его как щелчок. Это произошло только в FireFox, хотя, IE, Chrome и Safari не зарегистрировали его.
еще раз спасибо Мохаммед, очень полезное решение!
Это, конечно, возможно. Это работает в Chrome, Firefox и IE 11 (и, вероятно, другие).
focus(); var listener = window.addEventListener('blur', function() { if (document.activeElement === document.getElementById('iframe')) { // clicked } window.removeEventListener('blur', listener); });
предостережение:это только обнаруживает первый щелчок. Как я понимаю, это все, что вам нужно.
Это небольшое решение, которое работает во всех браузерах, даже в IE8:
var monitor = setInterval(function(){ var elem = document.activeElement; if(elem && elem.tagName == 'IFRAME'){ clearInterval(monitor); alert('clicked!'); } }, 100);вы можете проверить его здесь: http://jsfiddle.net/oqjgzsm0/
следующий код покажет вам, если пользователь нажмет / наведет курсор или выйдет из 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>вам нужно заменить src в iframe с вашей собственной ссылкой. Надеюсь, это поможет. С уважением, Миссури.
только что нашел это решение... Я попробовал, мне понравилось..
работает для кросс-доменных iframes для настольных и мобильных устройств!
Не знаю, если он является надежным еще
window.addEventListener('blur',function(){ if(document.activeElement.id == 'CrossDomainiframeId'){ //do something :-) } });удачи в кодировании
вы можете достичь этого с помощью события размытия на элементе окна.
вот плагин jQuery для отслеживания нажатия на iframes (он будет запускать пользовательскую функцию обратного вызова при нажатии на iframe) : https://github.com/finalclap/iframeTracker-jquery
используйте его так:
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/ для моего длинного намотанного решения, которое не работает надежно в 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();
Мохаммед Радван, Ваше решение является элегантным. Чтобы обнаружить клики iframe в Firefox и IE, вы можете использовать простой метод с документом.activeElement и таймер, однако... Я искал по всей сети метод для обнаружения кликов на iframe в Chrome и Safari. На грани того, чтобы сдаться, я нахожу ваш ответ. Спасибо, сэр!
некоторые советы: Я нашел ваше решение более надежным при вызове функции init() напрямую, а не через attachOnloadEvent (). Конечно, чтобы сделать это, вы должны вызвать init() только после iframe html. Так это будет выглядеть примерно так:
<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>
вы можете сделать это, чтобы пузырь событий родительского документа:
$('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); }); });просто расширить список событий для большего количества событий.
я столкнулся с ситуацией, когда мне пришлось отслеживать клики по кнопке социальных сетей, втянутой через 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();
это работает для меня на всех браузерах (включая 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/
просто сделайте невидимый слой над iframe, который возвращается при щелчке и поднимается, когда событие 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>
Это определенно работает, если 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'].onmousedown = function() { do something here }вы даже можете фильтровать результаты:
$(window.frames['YouriFrameId']).mousedown(function(event){ var eventId = $(event.target).attr('id'); if (eventId == 'the-id-you-want') { // do something } });
Я считаю, что вы можете сделать что-то вроде:
$('iframe').contents().click(function(){function to record click here });используя jQuery для достижения этой цели.
Как там нашел : обнаружение щелчка в 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'); } })
основываясь на ответе пола Дрейпера, я создал решение, которое работает непрерывно, когда у вас есть 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(); } });код прост, событие размытия обнаруживает потерю фокуса при нажатии iframe и проверяет, является ли активный элемент iframe (если у вас есть несколько iframe, вы можете знать, кто был выбран) это ситуация часто, когда у вас есть рекламные кадры.
второе событие запускает метод фокуса при возврате на страницу. используется событие изменения видимости.
вот решение, использующее предлагаемые подходы с помощью hover + blur и трюков с активными элементами, а не каких-либо библиотек, просто чистый js. Отлично работает для FF / Chrome. В основном подход такой же, как и предложенный @Mohammed Radwan, за исключением того, что я использую другой метод, предложенный @zone117x для отслеживания клика iframe для FF, потому что
Comments