① js无限滚动中,iOS惯性滚动停止的位置怎么确定
可以给你的webView的scrollView属性指氏碰败定delegate然后吵旦实现scrollViewDidEndDecelerating方法来监听惯性滚动停止歼颤事件,这个时候获取scrollView的滚动位置,然后通过js传到网页中
② JS实现滚动条触底加载更多
原理
1.通过监听滚动睁悔区域DOM的scroll事件, 计算出触底
// 滚动可视区域高度 + 当前滚动位置 === 整个滚动高度
scrollDom.clientHeight + scrollDom.scrollTop === scrollDom.scrollHeight
2.触底后触发列表添加, 列表添加使用createDocumentFragment, 将多次插入的DOM先存入内存, 最后烂厅一次填充进去, 提高性能, 也方便后面的MutationObserver监听
3.使用MutationObserver监听列表的DOM添加, 添加完毕后, 隐藏加载中饥早隐提示
示例
https://codepen.io/klren0312/full/dybgayL
参考资料
https://developer.mozilla.org/zh-CN/docs/Web/API/Element/clientHeight
https://developer.mozilla.org/zh-CN/docs/Web/API/Element/scrollHeight
https://developer.mozilla.org/zh-CN/docs/Web/API/Element/scrollTop
https://developer.mozilla.org/zh-CN/docs/Web/API/GlobalEventHandlers/onscroll
https://developer.mozilla.org/zh-CN/docs/Web/API/Document/createDocumentFragment
https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver
③ 物理学的 H5 应用:模拟惯性滑动
在移动端 H5 中,时间选择器( date-picker )、省市区选择器( area-picker )等组件经常会使用这样的交互效果:
这个 gif 是在【微信钱包 - 账单】中录制的 ios 原生时间选择器。可见, 当用户手指在选择器上先是滑动再从屏幕上移开,内容会继续保持一段时间的滚动效果,并且滚动的速度和持续的时间是与滑动手势的强烈程度成正比。 这种交互思路源于 ios 系统原生元素的滚动回弹( momentum-based scrolling ),来看 H5 的一个普通列表在 ios 上的滚动表现:
社区上大部分的移动端组件库的选择器组件都采取了这种交互方式,看看效果:
weui 的选择器实现了惯性滑动,但滑动动画结束得有稿掘点突兀,效果一般。
vant 的选择器压根没有做惯性滑动,当手指从屏幕上移开后,选择器的滑动会立刻停止。可见这样的交互体验是比较差的。
接下来我会从设计层面剖析和模拟惯性滑动的交互效果。
不难想象,惯性滑动非常贴合现实生活中的一些场景,如汽车刹车等。除此之外,与物理力学中的滑块模型也十分相似,由此我会参考滑块模型来剖析惯性滑动的全过程。
惯性 来源于物理学中的惯性定律(即 牛顿第一定律 ):一切物体在没有受到力的作用的时候,运动状态不会发生改变,物体所拥有的这种性质就被称为惯性。我们不妨把惯性滑动模拟成滑动滑块然后释放的过程(以下讨论中用户滑动的目标皆模拟成 滑块 ),主要划分为两个阶段:
描述滑块的惯性滑动,首先需要求出滑动的距离。在上述二阶段中,滑块受摩擦力 作 匀减速直线运动 。假设滑动距离为 ,初速度为 ,末速度为 。根据位移公式
加速度公式
可以仔昌算出惯性滑动距离
由于匀减速运动的加速度为负,不妨设一个加速度常量 ,使其满足 ,那么
这里 为正数。也就是说,我们只需要求出初始速度即可。
关注第一个阶段,假设用户滑动滑块的距离为 ,滑动的持续时间是 ,那么二阶段的初速度 可以根据位移公式求得
综上,求惯性滑动的距离我们需要记录用户滑动滑块的 距离 和 持续时间 ,并设置一个合理的 加速度常量 。念敬扒
注意,这里的距离和持续时间并不是用户滑动滑块的总距离和时长,而是触发惯性滑动范围内的距离和时长,详见【惯性滑动的启动条件】。
针对二阶段的匀减速直线运动,时间段 产生的位移差 ,其中 。也就是说时间越往后,同等时间间距下通过的位移越来越小,也就是动画的推进速度越来越慢。
这与 CSS3 transition-timing-function 中的 ease-out 速度曲线相吻合, ease-out (即 cubic-bezier(0, 0, .58, 1) )的贝塞尔曲线为
上图来自 在线绘制贝塞尔曲线网站 。图表中的纵坐标是指 动画推进的进程 ;横坐标是指 时间 ;原点坐标为 (0, 0) ,终点坐标为 (1, 1) ,假设动画持续时间为2秒, (1, 1) 坐标点则代表离动画开始2秒时动画执行完毕(100%)。根据图表可以得出,时间越往后动画进程的推进速度越慢,符合匀减速直线运动的特性。
然而这样的速度曲线过于线性平滑,减速效果不明显。我们基于 ios 滚动回弹的效果,调整贝塞尔曲线的参数为 cubic-bezier(.17, .89, .45, 1) 。
滑块滑动不是无边界的,我们来考虑这样的场景:当滑块向下滑动,其顶部正要接触容器上边界时速度还没有降到 ,此时如果让滑块瞬间停止运动,这样的交互效果是不理想的。
我们可以把上边界想象成一条与滑块紧密贴合的固定弹簧, 当滑块到达临界点而速度还没有降到 时,滑块会继续滑动并拉动弹簧使其往下形变,同时会受到弹簧的反拉力作减速运动(动能转化为内能);当滑块速度降为 ,此时弹簧的形变量最大,由于弹性特质弹簧会恢复原状(内能转化成动能),从而拉动滑块反向运动 。
回弹过程也可以分为两个阶段:
根据上述分析,回弹的第一阶段作加速度越来越大的变减速直线运动,设此阶段的初速度为 ,可以与 建立以下关系
那么回弹距离为
微积分都来了,简直没法算好吧…
我们可以根据运动模型来简化 的计算,由于该阶段的加速度大于 非回弹惯性滑动 的加速度,设 非回弹惯性滑动 的总距离为 ,那么
所以可以设置一个合理的常量 ,使其满足
整个触发回弹的惯性滑动模型包括三个运动阶段:
然而把 阶段a 和 阶段b 描绘成 CSS 动画是有一定复杂度和风险的:
出于简化的考虑,可以将 阶段a、b 合并为一个运动阶段:
对于合并后的 阶段a 末段,由于反向加速度越来越大,因此滑块减速的效率会比 非回弹惯性滑动 同期更大,对应的贝塞尔曲线末段也会更陡,参数调整为 cubic-bezier(.25, .46, .45, .94) 。
在 阶段b 中,滑块先变加速后变减速,尝试 ease-in-out 的动画曲线:
可以看出,由于 阶段b 初始的 ease-in 曲线使 阶段a、b 的衔接段稍有停留,效果体验一般。所以我们选择只描绘变减速运动这一段,调整贝塞尔曲线为 cubic-bezier(.165, .84, .44, 1) 。
一次惯性滑动可能会出现两种情况:
惯性滑动的启动需要有足够的动量。我们可以简单地认为,当用户滑动的距离足够大(大于 15px )和持续时间足够短(小于 300ms )时,即可产生惯性滑动。也就是说,最后一次 touchmove 事件触发的时间和 touchend 事件触发的时间间隔小于 300ms ,且两者产生的距离差大于 15px 时认为启动惯性滑动。
当惯性滑动未结束(包括处于回弹过程),用户再次触碰滑块时会暂停滑块的运动。原理上是通过 getComputedStyle 和 getPropertyValue 方法获取当前的 transform: matrix() 矩阵值,抽离出水平 y 轴偏移量后重新调整 translate 的位置。
demo 基于 vuejs 实现,预览地址: https://codepen.io/JunreyCen/pen/arRYem
④ 怎样用原生js获取滚动条滚动的距离
使用js获取的相关方法
//回到页面顶部
$("#goTotop").click(function(){
$('body,html').animate({scrollTop:0},1500);//点击按钮让其回到页面顶部
});
$(window).scroll(function(){
varyheight1=window.pageYOffset;//滚动条距顶端的距离
varyheight=getScrollTop();//滚动条距顶端的距离
varheight=document.documentElement.clientHeight//浏览器可视化窗口的大小
vartop=parseInt(yheight)+parseInt(height)-217;
vardivobj=$(".kf");
divobj.attr('style','top:'+top+'px;');
})
/**
*获取滚动条距离顶端的距离
*@return{}支持IE6
*/
functiongetScrollTop(){
varscrollPos;
if(window.pageYOffset){
scrollPos=window.pageYOffset;}
elseif(document.compatMode&&document.compatMode!='BackCompat')
{scrollPos=document.documentElement.scrollTop;}
elseif(document.body){scrollPos=document.body.scrollTop;}
returnscrollPos;
}
⑤ js实现图片自动的滚动效果
把你的代码放在“内容”中间就可以了 宽度600px,你自己可以改宽度
<DIV id=demoleft style="OVERFLOW: hidden; WIDTH:600px;">
<TABLE border="0" align="left" cellPadding="0" cellSpacing="0" cellspace="0">
<TBODY>
<TR>
<TD width="600" align=middle vAlign=top id=demo1left>
<!--内容-->
<table width="600" height="120" border="0" cellpadding="0" cellspacing="0">
<tr>
<%
set rs=server.CreateObject("adodb.recordset")
rs.open "select top 8 * from cp_aboutus where userid="&hid&" order by updatetime desc,articleid desc ",conn,1,1
if not rs.eof then
dim hang
hang = 0
do while not rs.eof
hang = hang + 1
%>
<td>
<table width="110" height="115" border="0" align="center" cellpadding="0" cellspacing="0" id="table12">
<tr>
<td width="110" height="87"><%if rs("headpic")<>"" then%><a href="huicpshow.asp?hid=<%=hid%>&id=<%=rs("articleid")%>" title="<%=rs("title")%>" target="_blank"><img src="<%=rs("headpic")%>" width="110" height="87" border="0" /></a><%else response.Write "<table width=110 height=87 border=0 cellpadding=0 cellspacing=0><tr><td height=23 bgcolor=#EBEBEB align=center>暂无图片</td></tr></table>" end if%></td>
</tr>
<tr>
<td align="center"><a href="huicpshow.asp?hid=<%=hid%>&id=<%=rs("articleid")%>" title="<%=rs("title")%>" target="_blank"><%=rs("title")%></a></td>
</tr>
</table>
</td>
<%
rs.movenext
loop
end if
rs.close
set rs=nothing
%>
</tr>
</table>
<!--end 内容-->
</TD>
<TD width="102" vAlign=top id=demo2left></TD>
</TR>
</TBODY>
</TABLE>
</DIV>
<SCRIPT>
var speed=18//速度数值越大速度越慢,demo2.offsetWidth=demo1.offsetWidth=固定值
var demoleft = document.getElementById("demoleft");
var demo2left = document.getElementById("demo2left");
var demo1left = document.getElementById("demo1left");
demo2left.innerHTML=demo1left.innerHTML
function Marquee(){
if(demo2left.offsetWidth-demoleft.scrollLeft<=0)//其实demo.scrollLeft是有 最大值的,和demo0.width,引用的图片的width有关系。demo过了一半(每半内容一样的),重新开始循环
demoleft.scrollLeft-=demo1left.offsetWidth
else{
demoleft.scrollLeft++//不断的增加,相当于父容器的滚动条不断是缩小;但由于OVERFLOW: hidden; (滚动条不可见)
}
}
var MyMarleft=setInterval(Marquee,speed)
demoleft.onmouseover=function() {clearInterval(MyMarleft)}
demoleft.onmouseout=function() {MyMarleft=setInterval(Marquee,speed)}
</SCRIPT>
⑥ js控制页面滚动(实例)
目标描述:多个图片排列下来,按右边的小按钮,抵达相应位置,鼠标滑动,抵达下一图,或者上一图
知识点:onmousewheel,addEventListener,scrollTo,setTimeout
过程:
1.body 宽,高钉死,100vw,100vh,overflow:hidden 使得不出现滚动条,不然不好看
2.图片放进去,排起来,(注意:默认空隙的处理,可以使用flex布局,空隙就不见了)
3.制作相对于视窗的按钮,几张图片就几个按钮,(position: fixed;计算一下高度,可以利用calc计算top使得上下居中)
4.美化一下,css写写
5.先写简单的按钮事件
6.写监听滑动事件(onmousewheel在火狐无效,DOMMouseScroll只在火狐有效)
react在componentDidMount的时候监听
7.补充写一下火狐的
9.测试检查一下。
完成啦,啦啦啦~
我的截图:
缺点:这里我是一直对页面进行监听,导致滑动过快对时候动画效果开始执行对时间延后。体现为滑动对轻,整个就流畅一点。
ps:写这种带计算带页面,我觉得是考验思维的,你可以对这里的知识点不熟练,但是你必须得能理解每一步的加加减减。
⑦ js或jquery 怎么监听由于屏幕惯性滚动而产生的距离
惯性滚动?手机端么?PC端没有惯性滚动的吧。
那么你数派手机判弊端用的什薯冲贺么?iscroll?.,不然也不会产生惯性滚动啊
⑧ js如何实现惯性滑动效果
主要思路是:鼠标当前点到下一点直接间隔计算出速度。这样就实现了惯性滑动效果。
下面是简单的js代码实现:仅供参考:
<style>
#div1{width:100px;height:100px;background:red;position:absolute;left:0px;top:0;}
</style>
<script>
window.onload=function(){
varoDiv=document.getElementById('div1');
variSpeedX=0;
variSpeedY=0;
varlastX=0;
varlastY=0;
vartimer=null;
oDiv.onmousedown=function(ev){//div的鼠标按下事件,主要计算鼠标当前位置,和移动位置。这样可以计算出鼠标移动速度。
varoEvent=ev||event;
vardisX=oEvent.clientX-oDiv.offsetLeft;
vardisY=oEvent.clientY-oDiv.offsetTop;
clearInterval(timer);
document.onmousemove=function(ev){//鼠标拖动事件。
varoEvent=ev||event;
oDiv.style.left=oEvent.clientX-disX+'px';
oDiv.style.top=oEvent.clientY-disY+'px';
iSpeedX=oEvent.clientX-lastX;
iSpeedY=oEvent.clientY-lastY;
lastX=oEvent.clientX;
lastY=oEvent.clientY;
}
document.onmouseup=function(){//当鼠标抬起后,清掉移动事件。
document.onmousemove=null;
document.onmouseup=null;
oDiv.releaseCapture&&oDiv.releaseCapture();
startMove();
}
oDiv.setCapture&&oDiv.setCapture();
returnfalse;
}
functionstartMove(){//移动函数,主要操作是计算鼠标移动速度和移动方向。
clearInterval(timer);
timer=setInterval(function(){
iSpeedY+=3;
vart=oDiv.offsetTop+iSpeedY;
varl=oDiv.offsetLeft+iSpeedX;
if(t>document.documentElement.clientHeight-oDiv.offsetHeight){
t=document.documentElement.clientHeight-oDiv.offsetHeight;
iSpeedY*=-0.8;
iSpeedX*=0.8;
}
if(t<0){
t=0;
iSpeedY*=-0.8;
iSpeedX*=0.8;
}
if(l>document.documentElement.clientWidth-oDiv.offsetWidth){
l=document.documentElement.clientWidth-oDiv.offsetWidth;
iSpeedX*=-0.8;
iSpeedY*=0.8;
}
if(l<0){
l=0;
iSpeedX*=-0.8;
iSpeedY*=0.8;
}
oDiv.style.left=l+'px';
oDiv.style.top=t+'px';
if(Math.abs(iSpeedX)<1)iSpeedX=0;
if(Math.abs(iSpeedY)<1)iSpeedY=0;
if(iSpeedX==0&&iSpeedY==0&&t==document.documentElement.clientHeight-oDiv.offsetHeight){
clearInterval(timer);
}
document.title=i++;
},30);
}
};
</script>
</head>
<body>
<divid="div1"></div>
</body>
⑨ js实现图片滚动效果
<SCRIPT language="JavaScript">
var speed=50; //设置滚动速度
demo2.innerHTML=demo1.innerHTML //复制dome1为dome2
function Marquee(){
if(demo2.offsetTop-demo.scrollTop<=0) //当滚动至dome1与dome2交界时
demo.scrollTop-=demo1.offsetHeight //dome跳到最顶端
else{
demo.scrollTop++
}
}
var MyMar=setInterval(Marquee,speed) //设置定时器
demo.onmouseover=function() {clearInterval(MyMar)}//鼠标移上时清除定时器达到滚动停止的目的
demo.onmouseout=function() {MyMar=setInterval(Marquee,speed)}//鼠标移开时重设定时器,继续滚动
</SCRIPT>
<div id="demo" style="overflow: hidden; height: 600; width: 180; background: #214984; color: #ffffff">
<div id="demo1" align="center">
<!-- 定义图片 -->
</div>
<div id="demo2" align="center"></div>
</div>
⑩ 在js中怎么设置滚动条滚动的距离
如果使用jquery的话,可以这样写:
$(window).bind("scroll", function(){
var top = $(this).scrollTop(); // 当前窗口的滚动距离
});
如果使用原生js,可以这样写(摘自网上的):
/**
* 获取滚动条距离顶端的距离
* @return {}支持IE6
*/
function getScrollTop() {
var scrollPos;
if (window.pageYOffset) {
scrollPos = window.pageYOffset; }
else if (document.compatMode && document.compatMode != 'BackCompat')
{ scrollPos = document.documentElement.scrollTop; }
else if (document.body) { scrollPos = document.body.scrollTop; }
return scrollPos;
}