2014-01-24 76 views
6

我有一個html文檔,其中包含3個表示前一頁,當前頁和下一頁的iframe。我試圖啓用頁面滑動(通過jquery touchswipe插件),但也讓點擊進入iframe中的文檔。這裏的HTML:滑過iframe,傳遞點擊事件,elementFromPoint在圖像地圖區域返回null

<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> 

當頁面-包裝元素刷卡,上一個或下一個頁面要麼成爲活動頁面。頁面大小爲100%,活動頁面填充瀏覽器的視口。一切都在同一個域內。 iframe的文檔可以包含帶有圖像映像的圖像。

不幸的是,iframe捕獲鼠標事件,禁用父頁面上的滑動功能。正如其他人所建議的,答案是覆蓋一個透明的div,使用elementFromPoint在iframe的文檔中定位目標,並手動向目標發送一個單擊事件。

我實現了這個使用coverIframes plugin

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

雖然這種方法適用於大多數的元素,它並不適用於圖像映射的領域這樣做 - 至少在Chrome瀏覽器中(版本32)。在這些情況下,它返回null。在試圖找到一個解決方法,這裏有浮現在腦海3個questons:

  1. 是否有對父直接傳送點擊事件到 IFRAME窗口,讓它準確地處理該事件的方式,如果用戶有 點擊窗口? (即,窗口發現目標,並通過 DOM的元素,直到氣泡該事件。)

  2. 是否有類似elementFromPoint該 可靠地返回目標元素的任何替代功能?

  3. 如果我想手動處理上的一個區域空的結果,是有一個 現有的JavaScript函數或jQuery插件,將決定是否 給定的點是地圖的區域內? (我已經看到了一些功能 一個多邊形中找到一個點。)

感謝您能提供任何見解!

回答

1

我不會告訴你如何使用透明覆蓋和事件捕獲。我已經這樣做了,它可以工作,但這不值得。

但是別擔心,好消息是:我們有AJAX!

請勿使用iframe;您可以輕鬆消除具有多個窗口對象的所有麻煩。如果所有頁面與您所說的位於同一個域中,請使用$.ajax({url:'XXX.html'})獲取內容並將其加載到<div id='page1'></div>

就像這個例子:https://jsfiddle.net/q69d0L63/

思考:

1)請求的頁面可能會需要CORS標題,如果他們不在同一個域(但你說的同一個域,所以沒有problemo)。

2)請求的URL的內容不一定是一個完整的HTML文檔,它可能只是HTML文檔片段。

示例代碼(不會對SO由於頭工作,但工作在的jsfiddle要驗證,監控JS控制檯和網絡流量的同時單擊):

var urls = ['page1.html', 'page2.html', 'page3.html']; // just an example; test data 
 
var curIdx = -1; 
 
swipe = function(e) { 
 
    getNextPage(); 
 
} 
 
getNextPage = function() { 
 
    curIdx = (curIdx + 1) % 3; 
 
    var url = urls[curIdx]; 
 
    $("#page_content").html('Loading...'); 
 
    $.ajax({ 
 
    url: url, 
 
    async: true, 
 
    success: function(data) { 
 
     var html = $(data).find("span:first"); // filter input if desired 
 
     $("#page_content").html(html.html()); 
 
    }, 
 
    error: function(jqXHR, status, error) { 
 
     $("#page_content").html([status, error].join(': ')); 
 
    } 
 
    }); 
 
} 
 
getNextPage();
#page_content { 
 
    background-color: #eee; 
 
    padding: 10px; 
 
    font-family: 'Segoe UI', Arial; 
 
    font-size: 20px; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<input type='button' value='Touch or click to simulate swipe' onclick='swipe();' /> 
 

 
<h3>Content loaded by AJAX</h3> 
 

 
<div id='page_content'></div>