vue中iframe的使用导致IOS设备中触发事件无效
1、◎◎◎◎◎◎◎◎◎◎ 页面描述 及 示意图 ◎◎◎◎◎◎◎◎◎◎
页面布局是:标题 和 内容区
标题:返回键是定位的(定不定位与该问题无关紧要)
内容:父容器包含了iframe标签。该iframe是用原生js 动态创建 并追加给了父容器
2、◎◎◎◎◎◎◎◎◎◎ 问题描述 ◎◎◎◎◎◎◎◎◎◎
安卓手机没毛病,IOS出现以下问题:
如果iframe加载出来的内容超过了分辨率的宽,滑动页面 、点击返回 、 返回无效 ( !~ ~ )
网上的资料大部分是给父盒子 如下图的样式,然而也无济于事。
怀疑过——> 定位问题导致的? 后台提供的url 没自己适配好移动端? 滑动页面的时候头部跟着滑跑了?
其实是高度没给够,内容把父盒子的宽撑大了,在滑动的时候影响了头部。(也就是移动端页面显示的是PC页面)
.parentBox{
...
-webkit-overflow-scrolling:touch;
overflow:scroll;
}
ps. 历经三天,最终搞定。重点来了 …
3、◎◎◎◎◎◎◎◎◎◎ 解决办法 (直接上代码) ◎◎◎◎◎◎◎◎◎◎
var myiframe = document.createElement('iframe'),
parent = document.getElementById('fileContent');
myiframe.setAttribute("src", url);//填写你的url
myiframe.setAttribute("width", '100%');
myiframe.setAttribute("overflow", 'visible');
myiframe.setAttribute("frameBorder", '0');
//如此设置是为了 确保body的宽是 等于 设备分辨率的。 上面的示意图,从陈列的3个 sheet 可以看出出现bug是因为该文件是按照pc窗口加载的,其内容大小超过父元素的宽,在滑动过程文件容易乱跳,遮住了头部,导致出发头部的返回键时不管用,或是触发好多次才执行。 所以这里修改bug的方向一定与width 有关了。(此处很重要)
document.getElementsByTagName("body")[0].style.width = window.screen.width;
//给iframe的高设置成全文的高,并把头部的高度减去
myiframe.setAttribute("height", that.$refs.asideBoxEle.scrollHeight - 44 + 'px');
//onload方法 ,是iframe加载完以后执行的回调 我是没看到w3c 中写
myiframe.onLoad = that.iframeOnload()
parent.appendChild(myiframe);
iframeOnload(){//因为安卓没问题,所以该回调只用来处理IOS设备,
let u = navigator.userAgent
let isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) // ios终端
if (isiOS) {//解决返回键失效的问题
// 监听body的touchmove事件,阻止默认行为。因为当滑动文件内容以后返回,会使上一个页面的触发事件不执行
document.body.addEventListener('touchmove',this.bodyScroll,false);
}
}
let u = navigator.userAgent
let isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) // ios终端
if (isiOS) {//解决iframe父亲页滚动失效的问题
document.body.removeEventListener('touchmove',this.bodyScroll,false);
}
//有同学会问,为什么要把下面这个函数 提取?
//回答:是因为w3c规定 如果要移除事件句柄,addEventListener() 的执行函数必须使用外部函数,否则无效。(海燕啊,你可长点心吧。)
bodyScroll(event){
event.preventDefault();
}
4、◎◎◎◎◎◎◎◎◎◎ 还需要知道 ◎◎◎◎◎◎◎◎◎◎
a、为什么要动态创建iframe?
回答:跟着业务需求走吧(我这边是因为关闭该页面,重新选一个文件预览时,该文件在加载之前会显示上一个文件的内容,为了删除上一个文件的展示 原生删除不了vue里写好的元素,只能通过js删除js动态创建的元素。)
ps. 谢谢浏览,愿能帮助到你!