سؤال

أفهم أنه لا يمكن معرفة ما يفعله المستخدم داخل iframe إذا كان المجال المتقاطع. ما أود القيام به هو المسار إذا نقر المستخدم على الإطلاق في iframe. أتصور سيناريو حيث يوجد غير مرئي div على قمة iframe و div بعد ذلك فقط تمرير حدث النقر إلى iframe.

هل أمر مثل هذا ممكن؟ إذا كان الأمر كذلك ، فكيف يمكنني القيام بذلك؟ ال iframes هي الإعلانات ، لذلك ليس لدي أي سيطرة على العلامات المستخدمة.

هل كانت مفيدة؟

المحلول

هل أمر مثل هذا ممكن؟

لا. كل ما يمكنك فعله هو اكتشاف الماوس الذي يدخل في الإطارات ، وربما (وإن لم يكن موثوقًا) عندما يعود (أي محاولة تحديد الفرق بين المؤشر الذي يمر عبر الإعلان في طريقه إلى مكان آخر مقابل مستمر على الإعلان).

أتصور سيناريو حيث يوجد div غير مرئي أعلى iFrame وسيقوم Div فقط بتمرير حدث النقر إلى iframe.

كلا ، لا توجد طريقة لتزييف حدث نقرة.

عن طريق اصطياد Mousedown ، ستمنع النقر الأصلي من الوصول إلى iframe. إذا تمكنت من تحديد متى كان زر الماوس على وشك الضغط ، فيمكنك محاولة إخراج div غير المرئي من الطريق حتى تمر النقر ... ولكن لا يوجد أيضًا حدث يطلق عليه الحرائق قبل موسى.

يمكنك محاولة التخمين ، على سبيل المثال من خلال البحث عن ما إذا كان المؤشر قد وصل إلى الراحة ، فقد يكون تخمين نقرة على وشك القدوم. لكنه غير موثوق به تمامًا ، وإذا فشلت ، فقد فقدت نفسك نقرة.

نصائح أخرى

هذا بالتأكيد ممكن. هذا يعمل في Chrome و Firefox و IE 11 (وربما الآخرين).

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

JSfiddle


التحذير: هذا يكتشف فقط النقر الأول. كما أفهم ، هذا هو كل ما تريد.

بناءً على إجابة محمد رادوان ، توصلت إلى حل jQuery التالي. في الأساس ما تفعله هو تتبع ما يحومه الناس. ثم إذا كانت النافذة تطمس على الأرجح أن المستخدم نقر على لافتة 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 ، على الرغم من ذلك ، لم يسجل Chrome و Safari.

شكرا مرة أخرى محمد ، حل مفيد جدا!

هذا حل صغير يعمل في جميع المتصفحات حتى 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 Cross Domain لسطح المكتب والجوال!

لا أعرف ما إذا كانت مضمونة حتى الآن

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

ترميز سعيد

يمكنك تحقيق ذلك باستخدام حدث Blur على عنصر النافذة.

فيما يلي مكون إضافي 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/ لحالتي الطويلة التي لا تعمل بشكل موثوق في أي

        $(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 ، يمكنك استخدام طريقة بسيطة مع المستند. في حافة الاستسلام ، أجد إجابتك. شكرا لك سيدي!

بعض النصائح: لقد وجدت أن الحل الخاص بك أكثر موثوقية عند استدعاء وظيفة init () مباشرة ، وليس من خلال atcheonloadevent (). بالطبع للقيام بذلك ، يجب عليك الاتصال بـ init () فقط بعد HTML IFRAME. لذلك سيبدو شيئًا مثل:

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

استنادًا إلى إجابة Paul Draper ، قمت بإنشاء حل يعمل بشكل مستمر عندما يكون لديك 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();
            }
        });

الكود بسيط ، ويكتشف حدث Blur فقدان التركيز عند النقر على iframe ، واختبار ما إذا كان العنصر النشط هو IFRAME (إذا كان لديك العديد .

الحدث الثاني يؤدي إلى طريقة تركيز عند العودة إلى الصفحة. يتم استخدامه حدث تغيير الرؤية.

فيما يلي الحل باستخدام الأساليب المقترحة مع Hover+Blur وحيل العناصر النشطة ، وليس أي مكتبات ، فقط JS Pure. يعمل بشكل جيد ل FF/Chrome. في الغالب ، هو نفسه مثل @mohammed readwan المقترح ، باستثناء أنني أستخدم طريقة مختلفة مقترحة من @Zone117x لتتبع Iframe انقر فوق FF ، لأن window.focus لا يعمل بدون إضافة إعدادات المستخدم:

يقدم طلبًا لإحضار النافذة إلى الأمام. قد تفشل بسبب إعدادات المستخدم ولا تضمن النافذة في المقدمة قبل إرجاع هذه الطريقة.

هنا طريقة المركب:

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

الجمع بين الإجابة أعلاه مع القدرة على النقر مرارًا وتكرارًا دون النقر فوق 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 );
    });
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top