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