修改了scrollTop的值,不会触发onscroll事件不触发吗

后使用快捷导航没有帐号?
只需一步,快速开始
查看: 2520|回复: 5
一个可以随滚动条滚动固定在屏幕上的一个拖拽效果
在写一个拖拽效果时出现的BUG,解决不了,希望能得到老师的帮助,
代码在附件中,打开页面可以看到一个小球和一个红块,这两个都是一个拖拽,小球是可以随滚动条滚动固定在屏幕上的。
发现的BUG:在火狐下小球不会出现震动,但IE下就不可以了,我尝试过用fixed固定定位来做(在附件代码里注释了),但IE下还是有闪动,不知怎么解决这问题,让他不会闪。
还有一个BUG,就是,把文件在浏览器打开,然后把垂直滚动条拉下,然后在出现滚动条的情况下刷新页面,在火狐下那个小球的位置是不对的,但在IE下,位置还是在左上角,是对的,这是为什么呢?ie刷新怎么还固定下来了,?
(18.01 KB, 下载次数: 614)
13:44 上传
点击文件名下载附件
没人吗?...
把帖子顶上去~~
把帖子顶上去~~
没太仔细看你的代码,只是就你所说的问题简单看了一下,问题出现的原因在fixedScroll()这个函数里:
fixeL=x-preLeft+scrollL
fixeT=y-preTop+scrollT
这两行代码你是想用来计算拖拽对象的left值和top值,从而让它可以始终保持在可见范围之内的吧,这个逻辑上看似没问题,但是不同浏览器对于刷新之后对页面的处理方式是不一样的,就拿滚动条位置来说,在ie和chrome下,在刷新页面之前会记录下滚动条的位置,当刷新页面的时候,会先让它回到顶部,再恢复到刷新之前的位置,这个过程中会触发onscroll事件。而ff却不这样,ff并不会重置滚动条的位置,滚动条移动到哪了,刷新的时候还是在那,因为滚动条没有动,所以自然就不会触发onscroll事件,这个是关键。那么我们可以作个对比,看看刷新前刷新后你上面的preTop 和 scrollTop的值是怎么变化的:
假如现在把滚动条的位置拉到了800,那么:
ie,chrome 下:
& & & & preTop : 0& &scrollTop : 800
fireforx下 :
& & & & preTop : 0&&scrollTop : 800
ie,chrome 下:
& & & & preTop : 0& &scrollTop : 800
fireforx下 :
& & & & preTop : 800&&scrollTop : 800
上面说过,在ie和chrome下刷新会触发onscroll事件,而ff不会。所以ie和chrome刷新之后,会计算一次拖拽对象的left和top值,根据上面的对比,对象的top值就是: y-preTop+scrollTop ,&&y为0,preTop 为0,scrollTop为800,结果就是800,这样对象的top就会被设置成800px,因为滚动条的位置正好也在800,所以用户还能看到拖拽对象是在左上角位置; 而ff刷新不会触发onscroll事件,也就不会重新设置top值,top仍然在0的位置,但是滚动条却在800的位置,这样用户自然就看不到拖拽对象。
那如果刷新之后再滚动页面,不是就会触发onscroll事件么,为什么ff下还是看不到呢?原因在于preTop,上面看到了刷新之后,ff下preTop的值和scrollTop的值是相等的,当滚动页面的时候,拖拽对象的值就是 y-preTop+scrollTop,假设滚动条刷新之后是在800,那么当再次滚动页面,拖拽对象始终都会上去800px而没办法看到,至于为什么,你可以自己思考一下。
其实你这里计算 left 和 top 值的方式是有问题的,所以才导致了这个bug, 正确的计算方式应该页面刷新或者滚动页面都直接把滚动高度赋给拖拽对象,因为如果你想保持对象始终在左上角,当页面有滚动条的时候,其实就只需要把滚动高度作为top值就行了,具体的原理可以参考远程课堂第五课的最后所讲的那个实例,原理是一样的。
另外关于闪动,那是浏览器渲染方式不同所引起的。如果用fixed定位,除了ie6,其它浏览器是可以解决,不会再闪。至于你所说的ie还会闪,不知道你具体是怎么实现的,可以把代码也打包上来看看。
没太仔细看你的代码,只是就你所说的问题简单看了一下,问题出现的原因在fixedScroll()这个函数里:
谢谢,老师的解答~~辛苦了~学习了~
Powered byiframe在移动端的限制及其应对策略
iframe使用于移动端其实不少,只是可见的iframe很少。以往我都是用iframe来实现无刷新登录和跨域通信,用来显示内容的地方就是登录那一块。而对于登录来说,登录界面无非,3-4个输入框和1~2个按钮,手机一屏内完全可以显示,所以其实对iframe显示多内容的问题没有过多研究,只知道有以下特性:
2.3的原生浏览器下iframe不仅不可以被控制高度,它同时不会被它外围的div的overflow:hidden
最近由于微信禁止了分享接口的任意调用,需要在规定的域名内才可以调用分享接口。因为公司有公众号,可以正常调用接口,但是测试环境的域名却在允许之外,为保持测试的质量,想通过iframe嵌套的方式实现分享接口调用(其实也可以实现其它接口的调用,同时也可以实现手Q的分享接口调用)。
我的思路如下:
测试的结果是,接口是可以完美调用的。不过,却意外发现一个问题。在ios下,iframe内的页面不能滚动(也不存在滚动条)!!!!
如果只是针对轻APP的H5页是可以完美兼容的,但是对于普通带滚动条的页面来说却是个坏消息。需要写个应对策略。首先,要弄清楚,iframe对页面的实际影响有多大,会不会对iframe的所有元素的内部滚动都造成影响了,如果没有没有,就可以考虑把滚动的任务将于节点body完成,而非window完成。
测试的结果是,iframe只对iframe的contentwindow产生不可滚动不带滚动条的影响,而不对contentwindow内的元素造成任何影响。这是个好消息,我可以通过以下代码实现在ios下iframe页面也可以滚动了:
html,body{width: 100%; height: 100%; overflow:}
body{-webkit-overflow-scrolling: overflow-y:}
有了以上代码基本上就解决了ios下iframe不能滚动的问题了。不过,这里会有一个问题,就是如果iframe页面里使用了window.onscroll事件的话,这个onscroll事件会失效。所以需要写一个统一方法来实现在iframe页面下window.onscroll事件可以被激活,其实,只要判断条件,重写一下window.onscroll事件即可
,以下是重写onscroll的代码段
if(top!=window){
//处于iframe中
if(navigator.userAgent.indexOf('AppleWebKit')&=0){
//ios系统,需要兼容一下window没有滚动条和不能滚动的问题
var iosStyle=document_createElement_x_x_x_x_x_x_x('style');
iosStyle.setAttribute('type','text/css');
iosStyle.innerHTML='\
&&&&&&&&&&&
html,body{width: 100%; height: 100%; overflow:}\
&&&&&&&&&&&
body{-webkit-overflow-scrolling: overflow-y:}\
document.getElementsByTagName_r('head')[0].a(iosStyle);
//当body.onscroll时,触发window.onscroll
var scrollEv=document_createEvent('HTMLEvents');
scrollEv.initEvent('scroll',true,true);
document.body.addEventListener('scroll',function(e){
&&&&&&&&&&&
&&&&&&&&&&&
window.dispatchEvent(scrollEv);
&&&&&&&&&&&
window.onscroll&&window.onscroll();
以上代码可以实现document.body.onscroll时,触发window.onscroll事件。不过,很可惜,测试时发现document.body,document.documentElement对象的scrollLeft,scrollTop属性无论怎么读写结果都是0(非iframe下也有这个问题)。对于,需要判断document.body.scrollTop的滚动加载来说,这是个问题。
造成,document.body.scrollTop和document.documentElement.scrollTop读写为0的原因恰恰是:
html,body{width: 100%; height: 100%; overflow:}
body{-webkit-overflow-scrolling: overflow-y:}
其实,主要原因是:html,body{width: 100%; height: 100%; overflow:
可以写一个长页面,然后加上上述的样式,你会发现,window.onscroll永远不会被触发。
继续观察,还会发现一个有意思的地方,如下代码
html,body{width: 100%; height: 100%; overflow:}
body{-webkit-overflow-scrolling: overflow-y:}
.tt{position: left:0; top:1000}
window.onscroll=function(){
console.log(document.body.scrollTop);
setTimeout(function(){document.body.scrollTop=300},3000);
当sto触发scrollTop赋值时,window.onscroll事件会被触发两次,可以观测到的数字如下:
但是观察的情况是看不到网页有跳动,这说明一个问题,就是当html的样式被设置为height:100%;
overflow:时,ios是强制性地让document.body.scrollTop值保持0,一旦外部js改变document.body.scrollTop值时,onscroll事件就会被触发,但是ios不会执行滚动而只是将值由非零改为0,这个时候因为document.body.scrollTop值的改变,window.onscroll事件再试被触发,这时,document.body.scrollTop保持在0,window.onscroll事件不被触发。这就是上面观测到的window.onscroll被触发两次的根本原因。
要改变上述情况的办法是,把html属性的overflow:去掉即可,因为body那里设置也height:100%;
overflow-y:了,html的overflow:本身就是多余的,即:
html{width: 100%; height: 100%;}
body{width: 100%; height: 100%; overflow:
-webkit-overflow-scrolling: overflow-y:}
但是这种方法只能解决在非iframe环境下的问题,在iframe下,用上述样式,页面无法滚动。来分析原因,先在页面中加入
setTimeout(function(){
&&&&&alert(document.documentElement.clientHeight);
&&&},3000);
观察输出会发现,输出的数字远大于手机屏幕的高度,document.body.clientHeight和document.body.scrollHeight是一样大的,这表明了,html和body都没有滚动条存在。因为iframe是用iframe元素来表示原来用浏览器窗口的window,浏览器的window会强制document.documentElement.clientHeight为可见区域的高度,而iframe就没有这个限制了,它可以是大于0的任意值。解决方案目前是有一个,不过是我最不喜欢的一个方案,把body节点内的所有节点都放在一个div中,
,然后使用以下的样式:
html,body{width: 100%; height: 100%; overflow:}\
.DOMWrap{width: 100%; height: 100%;
-webkit-overflow-scrolling: overflow-y:}
js代码如下:
if(top!=window){
//处于iframe中
if(navigator.userAgent.indexOf('AppleWebKit')&=0){
//ios系统,需要兼容一下window没有滚动条和不能滚动的问题
var iosStyle=document_createElement_x_x_x_x_x_x_x('style');
iosStyle.setAttribute('type','text/css');
iosStyle.innerHTML='\
&&&&&&&&&&&
html,body{width: 100%; height: 100%; overflow:}\
&&&&&&&&&&&
.DOMWrap{width: 100%; height: 100%;
-webkit-overflow-scrolling: overflow-y:}\
document.getElementsByTagName_r('head')[0].a(iosStyle);
//因为给document.body.scrollTop赋值时,window.onscroll会被触发,所以createEvent可以不用了
var scrollEv=document_createEvent('HTMLEvents');
//scrollEv.initEvent('scroll',true,true);
DOMWrap.addEventListener('scroll',function(e){
&&&&&&&&&&&document.body.scrollTop=this.scrollT
&&&&&&&&&&&
//window.dispatchEvent(scrollEv);
&&&&&&&&&&&
//window.onscroll&&window.onscroll();
以上代码可以解决ios下的iframe滚动和iframe里的window.onscroll事件兼容问题。不过,还是希望可以不用到DOMWrap这个节点,直接在html,body上就可以完成的方式。--在ios5下不行,因为document.body.scrollTop永远为0
为了更深入了解iframe在ios和android下的显示行为,我写了一个单例来观测记录iframe的各位行为,以下是观测的记录:
通过这个观测记录的总结,竟然得出一个结果:通过createEvent可以触发window.onscroll事件,但是却没办法强改
document.body.scrollTop的值!所以带document.body.scrollTop判断的内嵌页会出问题(ios8还好,因为document.body.scrollTop会有数值0-&x-&0变动)。
虽然没办法做出一个完全兼容的iframe内嵌组件,但是,如果一开始就知道自己做的是一个内嵌页面,那么上述问题就可以解决了,只需要把document.body.scrollTop或window.scrollY改一下就可以了。像如果是使用一个DIV把所有元素包括进去的写法,只需要把document.body.scrollTop改成DOMWrap.scrollTop即可。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。1被浏览141分享邀请回答0添加评论分享收藏感谢收起博客分类:
onselectstart与onscroll事件 (1)Onselectstart:在用户选取网页中文档中内容时发生,如果在这个事件处理程序中返回false,就可以禁止用户在网页文档中选取内容;从而阻止用户复制网页文档中的内容; (2)Onscroll :用户在拖动窗口的滚动条的时候发生的事件,处理onscroll事件可以实现如下的功能:无论用户怎样拖动浏览器窗口的滚动条,网页中的某个区域中的内容不会随着滚动条的移动而移动,总是漂浮显示在网页中的某个位置上;默认情况下,网页中的内容都会随着滚动条的拖动而移动;但是在body标签的onscroll事件处理程序中根据滚动条移动到的位置,将某个漂浮区域有移回到原来的位置上;就会让人感觉这个区域并没有随着滚动条的移动而移动; 2:应用举例: &script language="javascript"& function dealscroll() { it315.style.top=document.body.scrollTop+50; it315.style.left=document.body.scrollL } &/script& &body onscroll=" dealscroll()" onselectstart="return false"& 试试看,你能不能复制这个网页文档中的内容; &textarea rows="500" cols="500" id="textarea1" name="textarea1"& &/textarea& &a id=it315 href="http://www.it315.org" style='position:LEFT:0;top:50;word-break:keep-all'& IT资讯交流网&/a& &/body&
浏览: 4604 次
来自: 西安
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'如何获取网页滚动条滚动事件_百度知道
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。
如何获取网页滚动条滚动事件
如何获取网页滚动条滚动事件
在做js返回顶部的效果时,要监听网页滚动条滚动事件,这个事件就是:window.onscroll。当onscroll事件发生时,用js获得页面的scrollTop值,判断scrollTop为一个设定值时,显示“返回面部”js网页滚动条滚动事件&style type=&text/css&& #top_div{
display: } &/style& &script type=&text/javascript&& window.onscroll = function(){
var t = document.documentElement.scrollTop || document.body.scrollT
var top_div = document.getElementById( &top_div& );
if( t &= 300 ) {
top_div.style.display = &inline&;
top_div.style.display = &none&;
} } &/script& &a name=&top&&顶部&a& &div id=&top_div&&&a href=&#top&&返回顶部&/a&&/div& &br /& &br /& &div& 这里尽量多些&br /&以便页面出现滚动条,限于篇幅本文此处略去 &/div&例子语法解释在 style 标签中首先定义 top_div css 属性:position:display: 是关键javascript 语句中,t 得到滚动条向下滚动的位置,|| 是为了更好兼容性考虑当滚动超过 300 (像素)时,将 top_div css display 属性设置为显示(inline),反之则隐藏(none)必须设定 DOCTYPE 类型,在 IE 中才能利用 document.documentElement 来取得窗口的宽度及高度
采纳率:73%
来自团队:
.window.onscroll=function{
本回答被提问者采纳
//和&///滚动条下斜面和右面颜色设 SCROLLBAR-3DLIGHT-COLOR: #head&gt! 此代码放到&head&STYLE& 加入网页的时候把//滚动条斜面和左面颜色设 SCROLLBAR-SHADOW-COLOR: #fcfcfc。 } &/滚动条下边和右边的边沿颜色设定;///滚动条两端箭头颜色设定 SCROLLBAR-TRACK-COLOR: #滚动条底版颜色设定 SCROLLBAR-DARKSHADOW-COLOR: #48486c;滚动条上边和左边的边沿颜色 SCROLLBAR-ARROW-COLOR: #240024;///// SCROLLBAR-HIGHLIGHT-COLOR: #6c6c90;滚动条页面颜色设定;// BODY { SCROLLBAR-FACE-COLOR: #fcfcfc&&STYLE&“文字” 去掉哟! 具体颜色你试着改吧;之间&quot
window.onscroll=function{代码}网页是构成网站的基本元素,是承载各种网站应用的平台。通俗地说,您的网站就是由网页组成的,如果您只有域名和虚拟主机而没有制作任何网页的话,您的客户仍旧无法访问您的网站。网页是一个包含HTML标签的纯文本文件,它可以存放在世界某个角落的某一台计算机中,是万维网中的一“页”,是超文本标记语言格式(标准通用标记语言的一个应用,文件扩展名为.html或.htm)。网页通常用图像档来提供图画。网页要通过网页浏览器来阅读。
其他1条回答
为您推荐:
其他类似问题
滚动条的相关知识
换一换
回答问题,赢新手礼包

我要回帖

更多关于 scroll事件触发多次 的文章

 

随机推荐