解决iframe在iPad内不能滚动的问题

在iPad1及iPad2里面浏览含有iframe的Web页面,会出现一个很抓狂的问题,就是iframe内引用的页面内容不能上下滑动(滚动),测试了一下其他的设备,这个问题也同样出现在了Android平台的浏览器上,大部分移动设备都存在这个问题,我估计开发商的初衷是为了方便用户浏览页面,而使iframe的宽度和高度自动匹配其内容尺寸,但是对于iframe内的touch事件却支持不完善,因此出现了iframe滑动无响应的现象。

在网上一艘,这方面的解决方法不少,但是内容和方法似乎都差不多,大多是通过给iframe内的window对象绑定事件,发生touch事件时即时改变iframe上级元素的scrollTop和scrollLeft值来实现,下面是我的实现方法:

1. HTML

1
2
3
<div id="iframeBox">
<iframe src="http://luozhihua.com" width="320" height="240"></iframe>
</div>

2. CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#iframeBox{
border:1px solid #000;
width:400px;
height:320px;
overflow:auto;
}

#iframeBox iframe{
/* 在iPad及部分Android浏览器内下面的width、height无效 */
width:100%;
height:100%;
overflow:auto;
margin:0px; border:0px;
}

3. JavaScript:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**
* @param iframeID iframe的id或者iframeElement[Doc Object]
* @param iframeWrapper 用于包装iframe的元素
*/
function scrollIframeForIOS(iframe, iframeWrapper) {
if (!navigator.userAgent.match(/iPad|iPhone/i)) {
return false;
}

truevar touchY = 0,
true touchX = 0;

trueiframe = typeof(iframe)=="string"
truetrue? document.getElementById(iframe)
truetrue: iframe;

trueiframe.onload = function() {

truetruevar ifrWin = iframe.contentWindow,
truetrue ifrDoc = ifrWin.document;

truetrue// iframe的上一级节点
truetrueiframeWrapper = iframeWrapper||ifrWin.frameElement.parentNode;

truetrue// 记录手指按下的位置
truetrueifrDoc.body.addEventListener("touchstart", function(event) {
truetruetruetouchX = event.targetTouches[0].pageX;
truetruetruetouchY = event.targetTouches[0].pageY;
truetrue});

truetrueifrDoc.body.addEventListener("touchmove", function(event) {
truetruetruee.preventDefault(); // 阻止整个页面拖动

truetruetruevar moveX = (touchX - event.targetTouches[0].pageX),
truetruetrue moveY = (touchY - event.targetTouches[0].pageY);

truetruetrueiframeWrapper.scrollLeft += moveX;
truetruetrueiframeWrapper.scrollTop += moveY;
truetrue});
true}

return true;
};

// 调用方法:body onload="scrollIframeForIOS('iframeBox');"