Javascript 在iframe上滑动,传递click事件,elementFromPoint在imagemap区域上返回null

Javascript 在iframe上滑动,传递click事件,elementFromPoint在imagemap区域上返回null,javascript,jquery,iframe,swipe,imagemap,Javascript,Jquery,Iframe,Swipe,Imagemap,我有一个html文档,其中包括3个表示上一页、当前页和下一页的iFrame。我试图启用页面滑动(通过jQueryTouchSwipe插件),但也允许单击iframe中的文档。以下是HTML: <body> <div id="pages-wrapper"> <div id="page1" class="page-div previous-page"> <iframe id="frame1" class="pa

我有一个html文档,其中包括3个表示上一页、当前页和下一页的iFrame。我试图启用页面滑动(通过jQueryTouchSwipe插件),但也允许单击iframe中的文档。以下是HTML:

<body>
    <div id="pages-wrapper">
        <div id="page1" class="page-div previous-page">
            <iframe id="frame1" class="page-frame"></iframe>
        </div>
        <div id="page2" class="page-div active-page">
           <iframe id="frame2" class="page-frame"></iframe>
        </div>
        <div id="page3" class="page-div next-page">
           <iframe id="frame3" class="page-frame"></iframe>
        </div>                      
    </div> 
</body>

当滑动pages包装器元素时,上一页或下一页将成为活动页。页面大小为100%,活动页面填充浏览器的视口。一切都在同一个领域内。iframe的文档可以包含带有imagemaps的图像

不幸的是,iFrame捕获了鼠标事件,禁用了父页面上的滑动功能。正如其他人所建议的,答案是覆盖一个透明的div,使用elementFromPoint在iframe的文档中定位目标,然后手动向目标发送一个click事件

我已经使用以下工具实现了这一点:

$.fn.coverIframes=函数(){
$。每个($(“iframe”,this),函数(i,v){
变量ifr=$(v);
var-wr=$(“”);
如果之前(wr);
wr.高度(ifr.高度());
wr.点击(功能(事件){
var iframe=ifr.get(0);
变量iframeDoc=(iframe.contentDocument)?iframe.contentDocument:iframe.contentWindow.document;
//查找单击位置(坐标)
var x=事件补偿x;
变量y=event.offsetY;
//在iframe内触发单击
var link=iframeDoc.elementFromPoint(x,y);
var newEvent=iframeDoc.createEvent('HTMLEvents');
initEvent('click',true,true);
link.dispatchEvent(newEvent);
});
})
};
尽管这种方法适用于大多数元素,但它不适用于imagemap的区域——至少在Chrome浏览器(ver 32)中是如此。在这些情况下,它返回null。在试图找到解决办法时,我想到了三个问题:

  • 是否有办法将父级中的单击事件直接传递给 iframe窗口,并让它像处理用户 点击窗口?(即,窗口找到目标,并且 通过dom的元素使事件冒泡。)

  • 有没有类似于elementFromPoint的替代函数 可靠地返回目标元素

  • 如果我想手动处理某个区域的空结果,是否有 现有的javascript函数或jquery插件将确定 给定的点在地图的区域内?(我已经看到了 在多边形中查找点。)


  • 感谢您提供的任何见解

    我不会告诉您如何使用透明覆盖和事件捕获。我已经这样做了,它可以工作,但不值得

    但别担心,好消息是:我们有AJAX

    不要为此使用
    iframe
    ;您可以轻松消除拥有多个窗口对象的所有麻烦。如果所有页面都像您所说的一样位于同一个域中,则使用
    $.ajax({url:'XXX.html'})
    获取内容并将其加载到

    如本例所示:

    想法:

    1) 如果请求的页面不在同一个域中(但您说的是同一个域,所以没有问题),则可能需要CORS头

    2) 请求的URL的内容不必是完整的HTML文档,它只能是HTML文档片段

    示例代码(由于标头的原因,不适用于SO,但适用于JSFIDLE。要进行验证,请在单击时监视JS控制台和网络流量):

    var url=['page1.html','page2.html','page3.html'];//只是一个例子;测试数据
    var curIdx=-1;
    滑动=功能(e){
    getNextPage();
    }
    getNextPage=函数(){
    curIdx=(curIdx+1)%3;
    var url=url[curIdx];
    $(“#page_content”).html('Loading…');
    $.ajax({
    url:url,
    async:true,
    成功:功能(数据){
    var html=$(数据).find(“span:first”);//根据需要筛选输入
    $(“#页面内容”).html(html.html());
    },
    错误:函数(jqXHR、状态、错误){
    $(“#页面内容”).html([状态,错误].join(':');
    }
    });
    }
    getNextPage()
    
    #页面内容{
    背景色:#eee;
    填充:10px;
    字体系列:“Segoe UI”,Arial;
    字体大小:20px;
    }
    
    由AJAX加载的内容
    
    $.fn.coverIframes = function(){
        $.each($("iframe",this),function(i,v){
            var ifr = $(v);
            var wr = $("<div id='wr"+new Date().getTime()+i+"' style='z-index: 999999; opacity: 0; position:absolute; width:100%;'></div>");
            ifr.before(wr);
            wr.height(ifr.height());
            wr.click(function(event){
               var iframe = ifr.get(0);
               var iframeDoc = (iframe.contentDocument) ? iframe.contentDocument : iframe.contentWindow.document;
               // Find click position (coordinates)
               var x = event.offsetX;
               var y = event.offsetY;
               // Trigger click inside iframe
               var link = iframeDoc.elementFromPoint(x, y);
               var newEvent = iframeDoc.createEvent('HTMLEvents');
               newEvent.initEvent('click', true, true);
               link.dispatchEvent(newEvent);
            });
        })
    };