js-BOM之offset家族、移动函数的封装升级(轮播图)
Obj.style.width/obj.style.height与obj.offsetWidth/obj.offsetHeight的区别:
<style>
#div1{
height: 200px;
background-color: red;
}
#div2{
width: 200px;
height: 200px;
background-color: green;
}
</style>
</head>
<body>
<div style="width: 200px" id="div1"></div>
<div id="div2"></div>
<script>
var div1=document.getElementById("div1");
var div2=document.getElementById("div2");
console.log(div1.style.width); //结果:200px
console.log(div2.style.height); // 空
console.log(div1.offsetWidth); //200
console.log(div2.offsetHeight); //200
</script>
由此得出结论:Obj.style.width/obj.style.height只能获得行内样式的宽高数据,而不能获得内嵌式宽高数据。(带单位)(可以更改宽高的值)
obj.offsetWidth/obj.offsetHeight可以获得宽高数据(不带单位)(只能够读取不能够更改)
Obj.style.left/obj.style.top与offsetLeft/offsetTop的区别:
Obj.style.left/obj.style.top只能获取行内式数据
offsetLeft/offsetTop 只能读取;Obj.style.left/obj.style.top 可读可写入
offsetLeft/offsetTop是一个数值(不带单位)
Obj.style.left/obj.style.top 是一个字符串(带单位)
如果不加定位:Obj.style.left/obj.style.top的数据是无效的无意义的
在没有父盒子的情况下
offsetLeft/offsetTop是以body的左上角为基准的
Obj.style.left/obj.style.top 则以margin的左上角为基准。。
<style>
* {
margin: 0;
padding: 0;
}
.d {
width: 300px;
height: 300px;
padding: 30px;
border: 20px solid #000;
background-color: blue;
margin: 50px;
/*position: absolute;*/
}
#demo {
width: 100px;
padding: 20px;
border: 10px solid #000;
/*margin: 30px;*/
background-color: red;
}
</style>
</head>
<body>
<div class="d">
<div id="demo" style="height: 100px"></div>
</div>
<script>
var demo = document.getElementById("demo");
console.log(demo.offsetLeft);
//结果是100 因为父盒子没有定位所以子盒子相对body而言,offsetWidth的值是父盒子的margin+父盒子左边border+父盒子padding
// 定位影响到了offsetLeft,offsetLeft的值与定位的父盒子有关,如果父盒子没有定位,则默认是以浏览器或是body左边为准
// offsetLeft 是当前盒子的外边框与定位的父盒子的内边框之间的距离 ,如果父盒子没有定位,则默认是以浏览器或是body // offset家庭是可读的,不可写 // style.left
</script>
有父盒子的情况且父盒子设置了定位
offsetLeft/offsetTop 的值是子盒子的内边框到父盒子内边框的距离
<style>
* {
margin: 0;
padding: 0;
}
.d {
width: 300px;
height: 300px;
padding: 30px;
border: 20px solid #000;
background-color: blue;
margin: 50px;
position: absolute;
}
#demo {
width: 100px;
padding: 20px;
border: 10px solid #000;
/*margin: 30px;*/
background-color: red;
}
</style>
</head>
<body>
<div class="d">
<div id="demo" style="height: 100px"></div>
</div>
<script>
var demo = document.getElementById("demo");
console.log(demo.offsetLeft);
//结果是30 父盒子定位了所以他的值是父盒子的padding值
// 定位影响到了offsetLeft,offsetLeft的值与定位的父盒子有关,如果父盒子没有定位,则默认是以浏览器或是body左边为准
// offsetLeft 是当前盒子的外边框与定位的父盒子的内边框之间的距离 ,如果父盒子没有定位,则默认是以浏览器或是body // offset家庭是可读的,不可写 // style.left
</script>
点击按钮让div向右移动
<style>
*{
margin: 0;
padding: 0;
}
div {
height: 200px;
background-color: red;
position: absolute;/*加定位,让元素脱标,left才有意义*/
left: 20px;
top:20px;
}
</style>
</head>
<body>
<button id="btn">向右移动按钮</button>
<div id="demo" style="width:200px;"></div>
<script>
var demo = document.getElementById("demo");
var btn = document.getElementById("btn");
// console.log(demo.style.left); // 只能获得行内 的,如果 是left的话,最好有定位,要不然元素设置left没有意义
// console.log(demo.offsetLeft);// 可以获得行内的样式,也可以获取内嵌的,但是没有单位,而且是可读的,不可写 btn.onclick = function(){
var step = 10;
//首先先定义一个移动步长
var leader = demo.offsetLeft;
//获取当前demo距离body左侧的距离
console.log(leader);
leader = leader + step;
//不断给leader增加步长
demo.style.left = leader + 'px';
//定位的left的最终值就是累加后的leader值(注意加上单位)
}
只有每次点击btn按钮时,元素才能够移动,这样太麻烦了,我们可以结合定时器,让元素每隔一段时间就向右移动一段距离。
btn.onclick=function(){
setInterval(function(){
var step=5;
var leader=demo.offsetTop;
leader=leader+step;
demo.style.top=leader+"px";
},50);
}
为了解决按钮点击之后,元素一直不停向右移动,我们需要给他设置一个条件,让他到达指定的距离之后就将定时器清除。这样与元素就不会一直向右移动了。
btn.onclick = function(){
//此处设置一个timerId用来存储表示定时器的名称。
var timerId= setInterval(function(){
var step = 10;// 每次要移动的像素
// 先要获得原来的距离左侧的位置
var leader = demo.offsetLeft;
leader = leader + step;
// 到达200的时候停止定时器
if(leader <=200){
//当元素距离起始位置的值小于200时让leader继续赋值给left属性,超过或等于200px时就清除定时器。
demo.style.left = leader + 'px';
}else {
clearInterval(timerId);//清除定时器
}
},30)
}
最后为了重复利用让元素移动的这个功能,我们有必要对这个代码段进行封装,以便下次直接调用,优化代码。
function animate(obj,target){
var timerId= setInterval(function(){
var step = 10;// 每次要移动的像素
// 先要获得原来的距离左侧的位置
var leader = obj.offsetLeft;
leader = leader + step;
// console.log(123);
if(leader <= target){
obj.style.left = leader + 'px';
}else {
clearInterval(timerId);//清除定时器
}
},30)
}
进一步封装升级:
function animate(obj,target){
clearInterval(obj.timerId);//这里解决了每次执行函数时都会开启一个定时器的问题-即每次运行之前先清除定时器。
obj.timerId= setInterval(function(){
var step=8;
var leader=obj.offsetLeft; //获得当前距离浏览器左边的距离
step=leader<target?step:-step;//三元运算符判断当前位置与目标位置的长短
leader=leader+step;
if(Math.abs(leader-target)>Math.abs(step)){
// 当前位置与目标位置有相当的距离的时候,才会让当前对象的offsetLeft不断的加步长,做匀速运动
obj.style.left=leader+"px";
}
else{
clearInterval(obj.timerId);
obj.style.left=target+"px";
}
},10)
offsetParent:
<style>
div {
width: 100px;
height: 100px;
background-color: red;
}
#d1 {
/*position: absolute;*/
position: relative;
}
</style>
</head>
<body>
<div id="d1">
<div id="d2">
<div id="d3"></div>
</div>
</div>
<script>
var d1 = document.getElementById("d1");
var d2 =document.getElementById("d2");
var d3=document.getElementById("d3");
console.log(d2.offsetParent); // 与父级元素的有无定位有关系,如果当前元素的父级元素有定位,则为父级元素,如果当前父级元素没有定位,则会一直往上找有定位的元素,直到body为止
console.log(d2.parentNode);
</script>
练习案例:简单轮播图,左右焦点图,无缝滚动原理,最后制作一下完整的轮播图。
js-BOM之offset家族、移动函数的封装升级(轮播图)的更多相关文章
- vue.js学习之better-scroll封装的轮播图初始化失败
vue.js学习之better-scroll封装的轮播图初始化失败 问题一:slider组件初始化失败 原因:页面异步获取数据很慢,导致slider初始化之后,数据还未获取到,导致图片还未加载 解决方 ...
- JavaScript动画:offset和匀速动画详解(含轮播图的实现)
本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. offset简介 我们知道,三大家族包括:offset/scroll/c ...
- js原生代码实现轮播图案例
一.轮播图是现在网站网页上最常见的效果之一,对于轮播图的功能,要求不同,效果也不同! 我们见过很多通过不同的方式,实现这一效果,但是有很多比较麻烦,而且不容易理解,兼容性也不好. 在这里分享一下,用j ...
- JavaScript动画:offset家族和匀速动画详解(含轮播图的实现)
本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. offset家族简介 我们知道,三大家族包括:offset/scroll ...
- JS —— 轮播图中的缓动函数的封装
轮播图的根本其实就是缓动函数的封装,如果说轮播图是一辆跑动的汽车,那么缓动函数就是它的发动机,今天本文章就带大家由简入繁,封装属于自己的缓动函数~~ 我们从需求的角度开始,首先给出一个简单需求: 1. ...
- Js封装的动画函数实现轮播图
---恢复内容开始--- 效果图说明:当鼠标移到哪一个按钮上的时候会自动跳转到某一张图片上,并且按钮会以高亮显示 项目目录结构 用到的js封装的animate()动画 function ...
- 手把手原生js简单轮播图
在团队带人,突然被人问到轮播图如何实现,进入前端领域有一年多了,但很久没自己写过,一直是用大牛写的插件,今天就写个简单的适合入门者学习的小教程.当然,轮播图的实现原理与设计模式有很多种,我这里讲的是用 ...
- 原生js简单轮播图 代码
在团队带人,突然被人问到轮播图如何实现,进入前端领域有一年多了,但很久没自己写过,一直是用大牛写的插件,今天就写个简单的适合入门者学习的小教程.当然,轮播图的实现原理与设计模式有很多种,我这里讲的是用 ...
- js焦点轮播图
汇集网上焦点轮播图的实现方式,自己试了下,不过鼠标悬浮停止动画和鼠标离开动画播放好像没生效,不太明白,最后两行代码中,为什么可以直接写stop和play.不用加括号调用函数么?求懂的大神指点! 所用知 ...
随机推荐
- 35. Binary Tree Level Order Traversal && Binary Tree Level Order Traversal II
Binary Tree Level Order Traversal OJ: https://oj.leetcode.com/problems/binary-tree-level-order-trave ...
- [转]CABasicAnimation用法
CABasicAnimation用法 CABasicAnimation 自己只有三个property fromValue toValue ByValue 当你创建一个 CABasicAni ...
- js实现日历卡
效果图如下 首先先添加简单的样式 <style type="text/css"> *{padding:0;margin:0;} #tab { margin:0 auto ...
- Spring:No bean named 'beanScope' is defined
初学Spring,“No bean named 'beanScope' is defined”这个问题困扰了我好几个小时,查资料无果后,重写好几遍代码后发现问题居然是配置文件不能放在包里...要放在s ...
- namke 命令行编译
简介 大家已经习惯于微软提供的功能强大的IDE,已经很少考虑手动编连项目了,所谓技多不压身,有空的时候还是随我一块了解一下命令行编译. C/C++/VC++程序员或有Unix/Linux编程经验应该很 ...
- Provisional headers are shown,本地测试成功,服务器运行却失败
基于MVC的项目 具体情况是一个页面在访问的时候进不了首页,但详细页面却可以进去 下面说说解决方法和思路,以便找出问题所在 第一:把服务器代码下载到本地运行,代码是否出错,出错了,问题找到了,没出错接 ...
- Reactjs 入门基础(一)
实例中我们引入了三个库: react.min.js .react-dom.min.js 和 browser.min.js: 1,react.min.js -React 的 核心库 2,react-do ...
- 8.11 CSS知识点4
边框样式 1.边框宽度 border-width:medium | thin | thick | length border-top-width 设置上边框宽度 border-bottom-widt ...
- PHP生成静态页
代码如下: <? function makedir($mudir) //创建目录 { $file = "./$mudir"; @mkdir($file,07 ...
- python json学习之路2-认识python种的json模块
1.从python原始类型向json类型的转化过程,具体的转化对照如下: 2.从json到python的类型转化对照如下: 3.json提供四个功能:dumps, dump, loads, load ...