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>

练习案例:简单轮播图,左右焦点图,无缝滚动原理,最后制作一下完整的轮播图。

时间: 2024-11-03 05:27:55

js-BOM之offset家族、移动函数的封装升级(轮播图)的相关文章

JavaScript动画:offset和匀速动画详解(含轮播图的实现)

本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. offset简介 我们知道,三大家族包括:offset/scroll/client.今天来讲一下offset,以及与其相关的匀速动画. offset的中文是:偏移,补偿,位移. js中有一套方便的获取元素尺寸的办法就是offset家族.offset家族包括: offsetWidth offsetHight offsetLeft offsetTop offsetParen

原生js实现的3个小特效(时钟、轮播图、选项卡)

时钟: <p id="timeTxt"></p>  //将获取到的时间显示在timeTxt这里面        <button onclick="startTime()">关闭</button>        <!--时钟-->        function startTime(){  //创建startTime()函数            var today=new Date();  //定义一个对象

利用函数制作简单的轮播图

2016年11月29日,星期二    一.样式代码: 样式图: 二.设置DIV(left,center,right),script,JS链接: 三.函数代码: 四.完成图:         

JS 无缝轮播图1-节点操作

无缝轮播图 (使用节点操作) <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> *{ padding:0; margin:0; } body{ background:#F5F5F5; } #content{ width:300px; height:200px;

手把手原生js简单轮播图

在团队带人,突然被人问到轮播图如何实现,进入前端领域有一年多了,但很久没自己写过,一直是用大牛写的插件,今天就写个简单的适合入门者学习的小教程.当然,轮播图的实现原理与设计模式有很多种,我这里讲的是用面向过程函数式编程去实现,相对于面向对象设计模式,代码难免会显得臃肿冗余.但没有面向对象的抽象却很适合新手理解与学习.已经在BAT的同学看到希望少喷点.另外可以多提意见. 轮播图的原理: 一系列的大小相等的图片平铺,利用CSS布局只显示一张图片,其余隐藏.通过计算偏移量利用定时器实现自动播放,或通过

原生js简单轮播图 代码

在团队带人,突然被人问到轮播图如何实现,进入前端领域有一年多了,但很久没自己写过,一直是用大牛写的插件,今天就写个简单的适合入门者学习的小教程.当然,轮播图的实现原理与设计模式有很多种,我这里讲的是用面向过程函数式编程去实现,相对于面向对象设计模式,代码难免会显得臃肿冗余.但没有面向对象的抽象却很适合新手理解与学习.已经在BAT的同学看到希望少喷点.另外可以多提意见. 轮播图的原理: 一系列的大小相等的图片平铺,利用CSS布局只显示一张图片,其余隐藏.通过计算偏移量利用定时器实现自动播放,或通过

08第二种定时器_封装动画函数_轮播图_offset系列

前面复习: 下面会说第二种定时器. 第二种定时器: 第一种的定时器回顾: 另一个定时器 setTimeout() 它是一个一次性的定时器: 因为,代码是从上往下执行的,btn 还没有生成,所以getElementById("btn").onclick = 肯定是会报错的. 它是一次性的定时器,如果没有取消的话,它会一直占着空间,所以一般都要写按钮btn 去取消timeId  . 1 <!DOCTYPE> 2 <html lang="en">

js实现轮播图效果(附源码)--原生js的应用

1.js实现轮播图效果 <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="Author" content="奇客艺术"> <meta name="keyword" content="关键字"> <meta name=

JS之轮播图自动切换效果

1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>焦点轮播图</title> 6 <style type="text/css"> 7 *{ margin: 0; padding: 0; text-decoration: none;} 8 body { padding: 20px;} 9 #con