자바스크립트를 이용한 I프레임 클릭 탐지
합니다 에서 사용자가 할 수 .iframe
교차 도메인인 경우.하는 것입니다.iframe
않는 가 있는 합니다.div
iframe
d.div
합니다.iframe
.
이런 일이 가능한가요?만약 그렇다면 어떻게 해야 할까요?iframes
광고가 있어서 사용되는 태그를 제어할 수 없습니다.
이것은 확실히 가능합니다.이것은 Chrome, Firefox, IE 11(그리고 아마도 다른 것들)에서 작동합니다.
const message = document.getElementById("message");
// main document must be focused in order for window blur to fire when the iframe is interacted with.
// There's still an issue that if user interacts outside of the page and then click iframe first without clicking page, the following logic won't run. But since the OP is only concerned about first click this shouldn't be a problem.
window.focus()
window.addEventListener("blur", () => {
setTimeout(() => {
if (document.activeElement.tagName === "IFRAME") {
message.textContent = "clicked " + Date.now();
console.log("clicked");
}
});
}, { once: true });
<div id="message"></div>
<iframe width="50%" height="300" src="//example.com"></iframe>
주의: 첫 번째 클릭만 감지합니다.제가 알기로는 그게 당신이 원하는 전부입니다.
IE8에서도 모든 브라우저에서 작동하는 작은 솔루션입니다.
var monitor = setInterval(function(){
var elem = document.activeElement;
if(elem && elem.tagName == 'IFRAME'){
clearInterval(monitor);
alert('clicked!');
}
}, 100);
여기서 테스트해보실 수 있습니다: http://jsfiddle.net/oqjgzsm0/
Mohammed Radwan의 답변을 바탕으로 저는 다음과 같은 jQuery 솔루션을 생각해 냈습니다.기본적으로 이것은 아이프레임 사람들이 무엇을 맴돌고 있는지를 추적하는 것입니다.그런 다음 창이 흐려지면 사용자가 iframe 배너를 클릭했을 가능성이 높습니다.
iframe은 ID가 있는 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
});
... 이것은 iFrame이 호빙되지 않을 때 iFrame을 -1로 유지하거나 iFrame이 호빙될 때 랩핑 디브에 설정된 '배너리드'를 유지합니다.윈도우가 흐려질 때 'overiFrame'이 설정되어 있는지 확인하기만 하면 됩니다: ...
$(window).blur( function() {
if( overiFrame != -1 )
$.post('log.php', {id:overiFrame}); /* example, do your stats here */
});
});
사용자가 마우스를 iFrame 위에 올려놓을 때 ALT-F4를 누르면 클릭으로 기록됩니다.이것은 파이어폭스에서만 일어났지만 IE, Chrome, Safari는 등록하지 않았습니다.
모하메드, 매우 유용한 해결책 다시 한번 감사드립니다!
이런 일이 가능한가요?
아니요. 당신이 할 수 있는 것은 마우스가 iframe에 들어가는 것을 감지하고, 마우스가 다시 나올 때(신뢰할 수는 없지만) 잠재적으로(즉, 포인터가 다른 곳으로 오는 것과 광고에 남아 있는 것의 차이를 계산하려고 노력하는 것입니다).
iframe 위에 보이지 않는 div가 있고 그 div가 클릭 이벤트를 iframe에 전달하는 시나리오를 상상합니다.
아니요, 클릭 이벤트를 가짜로 만들 방법은 없습니다.
마우스를 아래로 가져가면 원래 클릭이 iframe으로 이동하는 것을 방지할 수 있습니다.마우스 버튼을 언제 누르려고 하는지 확인할 수 있다면 보이지 않는 디브를 제거하여 클릭이 통과되도록 할 수 있습니다.마우스 다운 직전에 발화하는 사건도 없습니다
예를 들어 포인터가 정지했는지 확인하여 클릭이 곧 시작될 것이라고 추측할 수 있습니다.하지만 전혀 신뢰할 수 없고, 실패할 경우 클릭 한 번으로 자신을 잃을 뿐입니다.
다음 코드는 사용자가 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>
iframe의 src를 자신의 링크로 교체해야 합니다.이게 도움이 되길 바랍니다.안녕, 모.
방금 이 해결책을 찾았습니다...해봤어요, 너무 좋았어요..
데스크톱 및 모바일용 교차 도메인 iframe에서 작동!
그것이 완벽한지는 아직 모릅니다.
window.focus();
window.addEventListener('blur',function(){
if(document.activeElement.id == 'CrossDomainiframeId'){
//do something :-)
}
});
해피코딩
창 요소에서 블러 이벤트를 사용하여 이를 달성할 수 있습니다.
iframe 클릭을 추적하기 위한 jQuery 플러그인은 다음과 같습니다(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)
}
});
});
IE에서 안정적으로 작동하지 않는 장황한 솔루션에 대해서는 http://jsfiddle.net/Lcy797h2/ 을 참조하십시오.
$(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();
http://jsfiddle.net/QcAee/406/
클릭시 뒤로 돌아가는 iframe 위에 보이지 않는 레이어를 만들고 마우스 탈퇴 이벤트가 실행될 때 위로 올라가기만 하면 됩니다!!
이 솔루션은 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>
모든 브라우저(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>
외부 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 );
});
모하메드 라드완, 당신의 해결책은 훌륭합니다.Firefox와 IE에서 프레임 클릭을 감지하려면 document.activeElement와 타이머로 간단한 방법을 사용할 수 있습니다.Chrome과 Safari에서 iframe의 클릭을 감지할 수 있는 방법을 찾기 위해 인터넷 곳곳을 검색했습니다.포기하기 직전에 당신의 답을 찾았습니다.고맙습니다, 선생님!
몇 가지 팁:attachOnloadEvent()를 통해서가 아니라 init() 함수를 직접 호출할 때 귀사의 솔루션이 더 안정적이라는 것을 알게 되었습니다.물론 이를 위해서는 iframe html 뒤에만 init()를 호출해야 합니다.그래서 다음과 같이 보입니다.
<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);
});
});
더 많은 이벤트를 위해 이벤트 목록을 확장하기만 하면 됩니다.
아이프레임을 통해 연결된 소셜 미디어 버튼을 클릭하는 것을 추적해야 하는 상황에 처했습니다.버튼을 클릭하면 새 창이 열립니다.해결책은 다음과 같습니다.
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();
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 외부의 요소에 포커스를 재설정하는 것입니다.
<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>
가정 -
- 스크립트는 iframe 외부에서 실행되지만 최외곽 window.top window에서는 실행되지 않습니다. (최외곽 window의 경우 다른 블러 솔루션으로도 충분합니다.)
- 새 페이지가 열리고 새 탭에서 현재 페이지/새 페이지를 대체하며 컨트롤이 새 탭으로 전환됩니다.
소스가 있는 iframe과 소스가 없는 iframe에 모두 적합합니다.
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");
}
});
새 탭이 열리거나 같은 페이지가 언로드되고 마우스 포인터가 Iframe 내에 있으면 클릭으로 간주됩니다.
폴 드레이퍼의 답변을 바탕으로 브라우저에서 다른 탭을 여는 I 프레임이 있을 때 지속적으로 작동하는 솔루션을 만들었습니다.페이지를 반환하면 프레임워크를 통한 클릭을 감지하기 위해 계속 활성화됩니다. 이는 매우 일반적인 상황입니다.
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와 active element 트릭을 사용한 제안된 접근법을 사용한 해결책은 라이브러리가 아닌 순수 js입니다.FF/크롬에 적합합니다.대부분의 접근 방식은 @Mohammed Radwan이 제안한 것과 동일하지만, 제가 FF에 대해 프레임 클릭을 추적하기 위해 @zone117x에서 제안한 다른 방법을 사용한다는 것을 제외하고는 창이 있기 때문입니다.사용자 설정을 추가하지 않으면 포커스가 작동하지 않습니다.
창을 앞쪽으로 가져오도록 요청합니다.사용자 설정으로 인해 오류가 발생할 수 있으며 이 메서드가 반환되기 전에 창이 가장 앞쪽에 있어야 합니다.
복합법은 다음과 같습니다.
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;
});
}
}
동료와 저는 브라이언 트럼프셋과 비슷한 문제가 있으며 이 스레드가 매우 도움이 된다는 것을 알게 되었습니다.저희 키오스크는 iframes 안에 애니메이션이 들어있고 타이머를 설정하기 위해 페이지 활동을 추적해야 합니다.
여기서 제안하는 것처럼 클릭을 추적하는 것이 아니라 이제 클릭할 때마다 포커스 변경을 감지하고 다시 변경합니다. 다음 코드는 사파리 및 크롬이 설치된 macOS에서는 정상이지만 FireFox에서는 작동하지 않습니다(왜?).
var eventListener = window.addEventListener('blur', function() {
if (document.activeElement.classList && document.activeElement.classList[0] == 'contentiFrame') {
refresh(); //function you want to call on click
setTimeout(function(){ window.focus(); }, 1);
}
window.removeEventListener('blur', eventListener );
});
문제는 윈도우에서는 크롬이나 파이어폭스와 함께 작동하지 않기 때문에 우리의 키오스크가 작동하지 않는다는 것입니다.왜 작동이 안 되는지 아십니까?윈도우에서 작동할 수 있는 해결책이 있습니까?
거기에 있는 것과 같이 : 자바스크립트를 이용한 Iframe 클릭 검출
=> 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');
}
})
저의 접근 방식은 위의 폴 드레이퍼가 제안한 것과 유사했습니다.그러나 activeElement가 코드 실행 시간에 맞춰 업데이트되지 않아 Firefox에서는 작동하지 않았습니다.그래서 우리는 조금만 기다려요.
iframe을 탭할 경우에도 발생합니다.제 경우에는 괜찮지만, 그 키 누름은 필터링할 수 있습니다.
addEventListenerOnIframe() {
window.addEventListener('blur', this.onBlur);
}
onBlur = () => {
setTimeout(() => {
let activeElement = document.activeElement;
let iframeElement = document.querySelector('iframe');
if (activeElement === iframeElement) {
//execute your code here
//we only want to listen for the first time we click into the iframe
window.removeEventListener('blur', this.onBlur);
}
}, 500);
};
저는 당신이 다음과 같은 것을 할 수 있다고 믿습니다.
$('iframe').contents().click(function(){function to record click here });
jQuery를 사용하여 이를 수행합니다.
언급URL : https://stackoverflow.com/questions/2381336/detect-click-into-iframe-using-javascript
'programing' 카테고리의 다른 글
C 코드는 어셈블리 코드(예: 최적화 스트렐렌)를 어떻게 호출합니까? (0) | 2023.10.09 |
---|---|
Firefox의 Flexbox 오버플로 문제 (0) | 2023.10.09 |
SQL에서 처음 발생하는 이벤트 찾기 (0) | 2023.10.04 |
event.preventDefault를 다시 활성화하는 방법? (0) | 2023.10.04 |
Excel 2013의 스프레드시트 비교 스크립트를 작성하는 방법은 무엇입니까? (0) | 2023.10.04 |