iframe的詬病太多了,還好標準沒有廢棄它,其實仍是有點用的。在開發產品的時候,咱們不得不捨棄一些東西來換取效率。瀏覽器
咱們的需求是,在某些特定的場景下在現有的頁面作一個彈窗,這是常有的運營手段,雖然我以爲是一種粗魯的運營,但需求仍是得作啊。post
原有的平臺頁面:
spa
新增的運營活動頁面:
.net
合成的效果圖:
設計
看到最後這個圖不就是個簡單的彈層嗎?code
但這個彈層的邏輯很多啊,並且是由專門的系統配置生成,包括領取卡券邏輯。跟現有的頁面基本不要緊,並且只是一個臨時的運營活動。不必在主頁面的邏輯中專門加一個這樣的活動邏輯。事件
因此最好是將兩個頁面合成到一塊兒。圖片
設置這個臨時iframe的樣式使得iframe鋪滿整個瀏覽器窗口,這裏能夠先將透明度設置爲0,等到iframe徹底加載再顯示出來,以避免iframe加載失敗或者樣式抖動致使用戶體驗就不太友好:ci
.float-iframe{ position: absolute; width: 100%; height: 100%; top: 0; left: 0; border: 0; z-index: 1000; opacity: 0; }
iframe加載出來後發現並非透明的,平臺頁面的背景被遮蓋了。這裏須要設置iframe的body樣式:開發
background-color:rgb(0,0,0,0.6);
設置透明度爲0.6,能夠生成一個透明度的蒙層,這樣也能夠免去本身再去寫一個遮罩層。
在body上加上下面的樣式,能夠設置徹底透明:
background-color: transparent;
這樣就須要本身去加遮罩層,否則兩個頁面的元素視覺上看起來會疊加到一塊兒了。
作的過程發現頁面是能夠滑動的,理想的狀況固然是鎖住頁面。這個時候想到的是阻止touchmove事件
document.addEventListener('touchmove', function(e){ e.preventDefault(); },false)
發現這樣是不生效的,在iframe的頁面區域照樣能夠滑動,在主頁面卻不能滑動,說明對iframe是無效的。惟一的解釋就是發生在iframe的touch事件只在iframe內部冒泡,並不會傳遞到父頁面,因此是不能阻止父頁面的滑動,若是這個猜測成立的話,如下代碼應該會生效
iframe.onload = function(){ var doc = iframe.contentDocument; doc.addEventListener('touchmove', function(e){ e.preventDefault(); },false) };
這樣設置之後,果真就不能滑動了。
接下來的問題,怎麼去關閉iframe。在頁面上咱們設計了一個X按鈕,用來關閉。這裏要分場景來作,一種是同源,另外是不一樣源。
咱們的這兩個頁面是同源,就比較好作了,經過父頁面直接控制子頁面,徹底的控制權限。
var doc = iframe.contentDocument; doc.querySelector('#_js_close').addEventListener('click', function(){ document.body.removeChild(iframe); });
若是是不一樣源,會比較麻煩點,須要兩個頁面間的通訊。
// 父頁面 http://parent.com window.addEventListener("message", receiveMessage, false); function receiveMessage(event){ var origin = event.origin || event.originalEvent.origin; // 域名白名單 if (origin !== "http://child.com") return; if(event.data === 'closepage'){ document.body.removeChild(iframe); } } // 子頁面 http://child.com window.postMessage('closepage', 'http://parent.com');
好了,完成這樣的需求,半天都不用。若是從頭開始寫,估計要花幾天,主要不是顯示彈層邏輯,而是彈層裏自己的邏輯。用iframe雖然不是最好的方案,但對於本案例來是最佳的。
本文爲原創文章,可能會常常更新知識點以及修正一些錯誤,所以轉載請保留原出處,方便溯源,謝謝合做。
本文的博客地址:http://www.iamaddy.net/2017/0...