Обнаружение щелчка в Iframe с помощью JavaScript
Я понимаю, что невозможно сказать, что пользователь делает внутри iframe
Если это крест домена. То, что я хотел бы сделать, это отслеживать, щелкнул ли пользователь вообще в iframe
. Я представляю себе сценарий, где есть невидимый div
сверху iframe
и div
просто передаст событие click в iframe
.
возможно ли что-то подобное? Если да, то как мне это сделать? The iframes
объявления, поэтому я не контролирую теги, которые используются.
18 ответов
возможно ли что-то подобное?
нет. Все, что вы можете сделать, это обнаружить мышь, входящую в iframe, и потенциально (хотя и не надежно), когда она возвращается (т. е. попытка выяснить разницу между указателем, проходящим над объявлением по пути куда-то еще, и задержкой на объявлении).
Я представляю себе сценарий, где есть невидимый div поверх iframe, и div просто передаст событие click в фрейм.
нет, нет способа подделать событие click.
поймав 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 :-)
}
});
удачи в кодировании
вы можете достичь этого, используя событие размытия в элементе window.
вот плагин 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);
});
});
просто продлить eventlist для нескольких событий.
я столкнулся с ситуацией, когда мне пришлось отслеживать клики по кнопке социальных сетей, втянутой через iframe. При нажатии на кнопку откроется новое окно. Вот мое решение:--2-->
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 click for FF, потому что