js 系列(3) 偏移量 定时器 滚动 json

Posted on Posted in js

偏移量

offsetParent:不管元素自身有没有定位,如果祖先元素有定位,偏移参考元素就是距离该元素最近的有定位的祖先元素。如果祖先元素都没有定位,偏移参考元素变成body。
offsetLeft:就是自身元素的左边框外到offsetParent的左边框内部的距离。
offsetTop与offsetLeft一样:自身元素的上边框外到offsetParent的上边框内部的距离。

offsetLeft

偏移量,参考最近上一级标签的定位,如果没有,就参考body定位

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .box1{
            width: 300px;
            height: 300px;
            padding: 50px;
            margin: 50px;
            border: 10px solid #f00;
            position: relative;
            top: 0;
            left: 0;
        }
        .box2{
            width: 160px;
            height: 160px;
            padding: 50px;
            border: 20px solid #0f0;
            position: relative;
            top: 0;
            left: 0;
        }
        .box3{
            width: 60px;
            height: 60px;
            padding: 50px;
            border: 10px solid #00f;
        }
        p{
            width: 30px;
            height: 30px;
            border: 10px solid gold;
            position: relative;
            top: 0;
            left: 0;
        }
    </style>
    <script>
        window.onload = function(){
            var op = document.getElementsByTagName("p")[0];
            var h = document.getElementsByTagName("h1")[0];
            //找偏移参考元素,和offsetLeft值
            console.log(op.offsetParent);
            console.log(op.offsetLeft);
            // IE6直接在一个元素中输入
            h.innerHTML = op.offsetParent + op.offsetLeft;
        };
    </script>
</head>
<body>  
    <h1></h1>
    <div class="box1">
        <div class="box2">
            <div class="box3">
                <p></p>
            </div>
        </div>
    </div>
</body>
</html>

offsetWidth offsetHeight

与offsetParent没有关系。自身的实际占有的宽度和高度。
offsetWidth = width + padding + border;
offsetHeight = height + padding + border;
全线浏览器兼容。
特殊情况:
不写宽度:会去继承父亲的宽度,得到的offsetWidth是具体的像素值。不会返回100%。
不写高度:靠内部的内容撑高,具体的像素值。

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        
        p{
            /*width: 30px;
            height: 30px;*/
            padding: 5px;
            border: 10px solid gold;
            position: relative;
            top: 0;
            left: 0;
            font-size: 16px;
            line-height: 22px;
        }
    </style>
    
</head>
<body>  
    <h1></h1>
    <p>
        <img src="images/cat.jpg" alt="" />
    </p>
    <script>
    
            var op = document.getElementsByTagName("p")[0];
            var h = document.getElementsByTagName("h1")[0];
            //找偏移参考元素,和offsetLeft值
            // console.log(op.offsetParent);
            // console.log(op.offsetLeft);
            // IE6直接在一个元素中输入
            // h.innerHTML = op.offsetWidth + "高度" + op.offsetHeight;
            alert(op.offsetHeight);
    </script>
</body>
</html>

谷歌浏览器的加载机制:在加载图片的时候,不会等待,先去加载JS。
得到撑高的高度时,没有图片撑高的部分,js加载完了之后,图片才会显示。
解决方法:window.onload事件去解决。

window.onload = function(){
            var op = document.getElementsByTagName("p")[0];
            var h = document.getElementsByTagName("h1")[0];         
            alert(op.offsetHeight);
        }

clientWidth clientHeight

clientWidth = width + padding; // 区别是没有border
clientHeight = height +padding; 

特殊情况:
不写宽度:会去继承父亲的宽度,得到的clientWidth是具体的像素值。不会返回100%。IE6返回0.
不写高度:靠内部的内容撑高,具体的像素值。IE6返回0.

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        
        p{
            
            padding: 5px;
            border: 10px solid gold;
            position: relative;
            top: 0;
            left: 0;
            font-size: 16px;
            line-height: 22px;
            overflow: hidden;
        }
    </style>
    
</head>
<body>  
    <h1></h1>
    <p>
        <img src="images/cat.jpg" alt="" />
    </p>
    <script>
        window.onload = function(){
            var op = document.getElementsByTagName("p")[0];
            var h = document.getElementsByTagName("h1")[0];
            //找偏移参考元素,和offsetLeft值
            // console.log(op.offsetParent);
            // console.log(op.offsetLeft);
            // IE6直接在一个元素中输入
            h.innerHTML = op.clientWidth + "高度" + op.clientHeight;
            // alert(op.offsetHeight);
        }
            
    </script>
</body>
</html>

定时器

setInterval : 每隔一段时间执行某一个函数。
语法:window.setInterval(函数,间隔时间毫秒);

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        div{
            width: 100px;
            height: 100px;
            background: pink;
            position: absolute;
            top: 100px;
            left: 0;
        }
    </style>
    
</head>
<body>  
    <div></div>
    <script>
        //获得div标签
        var box = document.getElementsByTagName("div")[0];
        //全局变量累加
        var nowleft = 0;
        window.setInterval(function(){
            //每次执行函数都让nowleft递加
            nowleft += 20;
            //赋值给left属性值
            box.style.left = nowleft + "px";
        },1000);
        window.setInterval(shuchu,100);
        function shuchu(){
            console.log(1);
        }
    </script>
</body>
</html>

简单运动

视觉暂留:视觉残留。人的视觉有一个残留时间0.1秒-0.4秒
间隔时间在一秒钟内让函数执行几次,次数可以叫做帧频,frame percent second,每秒执行几帧,简称fps。一个运动的帧频是24fps,指的是一秒钟动24次。

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        div{
            width: 100px;
            height: 100px;
            background: pink;
            position: absolute;
            top: 100px;
            left: 0;
        }
    </style>
    
</head>
<body>  
    <div></div>
    <script>
        //获得div标签
        var box = document.getElementsByTagName("div")[0];
        //全局变量累加
        var now = 100;
        //定义定时器,让宽度每隔100毫秒变宽一点
        setInterval(move,20);
        function move(){
            now += 30;
            //给元素宽度赋值
            box.style.width = now + "px";
        }
    </script>
</body>
</html>

清除定时器

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        div{
            width: 100px;
            height: 100px;
            background: pink;
            position: absolute;
            top: 100px;
            left: 0;
        }
    </style>
</head>
<body>
    <input type="button" value="开始" />  
    <input type="button" value="结束" />  
    <div></div>

    <script>
        //获得div标签
        var box = document.getElementsByTagName("div")[0];
        var start = document.getElementsByTagName("input")[0];
        var end = document.getElementsByTagName("input")[1];
        //全局变量累加
        var now = 100;
        //为了关闭定时器,要将定时器放在一个变量里。
        var timer;
        start.onclick = function(){
            //防骚扰操作:每开启一个定时器之前,先停止一次定时器。设表先关。
            clearInterval(timer);
            timer = setInterval(move,100);
        };
        end.onclick = function(){
            //关闭定时器
            clearInterval(timer);
        };
        function move(){
            now += 10;
            //给元素宽度赋值
            box.style.width = now + "px";
        }
    </script>
</body>
</html>

解决固定步长

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        div{
            width: 100px;
            height: 100px;
            background: pink;
            position: absolute;
            top: 100px;
            left: 0;
        }
    </style>
    
</head>
<body>
    <input type="button" value="开始" />  
    <div></div>

    <script>
        //获得div标签
        var box = document.getElementsByTagName("div")[0];
        var start = document.getElementsByTagName("input")[0];
        var end = document.getElementsByTagName("input")[1];
        //全局变量累加
        var now = 0;
        //元素向右走动,走到500位置停止。
        var timer;
        start.onclick = function(){
            timer = setInterval(move, 50);
            
        }
        function move(){
                //设置步长
                now += 13;
                // 给元素属性赋值
                //后验收
                if(now > 500){
                //先将变量判断,if语句的后验收,如果大于终点值,强制给变量赋值,再停止定时器。拉终停表。
                    now = 500;
                    clearInterval(timer);
                }
                box.style.left = now + "px";
                console.log(now);

            }
    </script>
</body>
</html>

简单无缝滚动

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .box{
            width: 840px;
            height: 130px;
            border: 10px solid #000;
            margin: 100px auto;
            overflow: hidden;
        }
        .box .scroll{
            position: relative;
            top: 0;
            left: 0;
        }
        .box .scroll .m_unit{
            list-style: none;
            width: 5000px;
            height: 130px;
            position: absolute;
            top: 0;
            left: 0;
        }
        .box .scroll .m_unit li{
            float: left;
            width: 200px;
            margin-right: 10px;
            height: 130px;
        }
        .box .scroll .m_unit li img{
            display: block;
        }
    </style>
</head>
<body>
    <div class="box" id="box">
        <div class="scroll">
            <ul class="m_unit" id="m_unit">
                <li><img src="images/shuzi/0.png" alt="" /></li>
                <li><img src="images/shuzi/1.png" alt="" /></li>
                <li><img src="images/shuzi/3.png" alt="" /></li>
                <li><img src="images/shuzi/4.png" alt="" /></li>
                <li><img src="images/shuzi/5.png" alt="" /></li>
                <li><img src="images/shuzi/6.png" alt="" /></li>
                <li><img src="images/shuzi/7.png" alt="" /></li>
                <li><img src="images/shuzi/0.png" alt="" /></li>
                <li><img src="images/shuzi/1.png" alt="" /></li>
                <li><img src="images/shuzi/3.png" alt="" /></li>
                <li><img src="images/shuzi/4.png" alt="" /></li>
                <li><img src="images/shuzi/5.png" alt="" /></li>
                <li><img src="images/shuzi/6.png" alt="" /></li>
                <li><img src="images/shuzi/7.png" alt="" /></li>
            </ul>
        </div>
    </div>
    <script>
        //获得要运动的元素
        var mUnit = document.getElementById("m_unit");
        var box = document.getElementById("box");
        //信号量
        var now = 0;
        //临界点,如果now走到临界点,瞬间变为0
        var maxNow = 1470;
        //代码执行时,就开启了一个定时器
        var timer = setInterval(move,50);
        //鼠标移上停止定时器timer
        box.onmouseover = function(){
            clearInterval(timer);
        };
        //鼠标移出事件必须是在鼠标移上事件之后,所以不用再清楚定时器
        box.onmouseout = function(){
            timer = setInterval(move,50);
        };
        function move(){
            // 向做移动left要减小
            now -= 20;
            //判断是否走到了临界点,瞬间拉回
            if(now <= -maxNow){
                now = 0;
            }
            mUnit.style.left = now + "px";
        }
    </script>
</body>
</html>

图片加载机制

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .box{
            width: 840px;
            height: 130px;
            border: 10px solid #000;
            margin: 100px auto;
            overflow: hidden;
        }
        .box .scroll{
            position: relative;
            top: 0;
            left: 0;
        }
        .box .scroll .m_unit{
            list-style: none;
            width: 5000px;
            height: 130px;
            position: absolute;
            top: 0;
            left: 0;
        }
        .box .scroll .m_unit li{
            float: left;
            width: 200px;
            margin-right: 10px;
            height: 130px;
        }
        .box .scroll .m_unit li img{
            display: block;
        }
    </style>
</head>
<body>
    <div class="box" id="box">
        <div class="scroll">
            <ul class="m_unit" id="m_unit">
                <li><img src="images/shuzi/0.png" alt="" /></li>
                <li><img src="images/shuzi/1.png" alt="" /></li>
                <li><img src="images/shuzi/3.png" alt="" /></li>
                <li><img src="images/shuzi/4.png" alt="" /></li>
                <li><img src="images/shuzi/5.png" alt="" /></li>
                <li><img src="images/shuzi/7.png" alt="" /></li>
                <li><img src="images/shuzi/8.png" alt="" /></li>
                <li><img src="images/shuzi/9.png" alt="" /></li>
                <li><img src="images/shuzi/10.png" alt="" /></li>
                <li><img src="images/shuzi/2.png" alt="" /></li>
            </ul>
        </div>
    </div>
    <script>
        //获得所有图片
        var imgs = document.getElementsByTagName("img");
        //全局变量,累加器
        var sum = 0;
        //批量给imgs添加onload事件,每加载完一个就sum加1
        for(var i = 0 ; i < imgs.length ; i++){
            imgs[i].onload = function(){
                //加载一张图片,会触发事件
                sum++;
                if(sum == imgs.length){
                    alert("加载完毕" + sum);
                }
            };
        }
    </script>
</body>
</html>

高级无缝滚动

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .box{
            width: 840px;
            height: 130px;
            border: 10px solid #000;
            margin: 100px auto;
            overflow: hidden;
        }
        .box .scroll{
            position: relative;
            top: 0;
            left: 0;
        }
        .box .scroll .m_unit{
            list-style: none;
            width: 5000px;
            height: 130px;
            position: absolute;
            top: 0;
            left: 0;
        }
        .box .scroll .m_unit li{
            float: left;
            margin-right: 10px;
            height: 130px;
        }
        .box .scroll .m_unit li img{
            display: block;
        }
    </style>
</head>
<body>
    <div class="box" id="box">
        <div class="scroll">
            <ul class="m_unit" id="m_unit">
                <li><img src="images/shuzi/0.png" alt="" /></li>
                <li><img src="images/shuzi/1.png" alt="" /></li>
                <li><img src="images/shuzi/2.png" alt="" /></li>
                <li><img src="images/shuzi/3.png" alt="" /></li>
                <li><img src="images/shuzi/4.png" alt="" /></li>
                <li><img src="images/shuzi/5.png" alt="" /></li>
                <li><img src="images/shuzi/6.png" alt="" /></li><!-- 
                <li><img src="images/shuzi/7.png" alt="" /></li>
                <li><img src="images/shuzi/8.png" alt="" /></li> -->
            </ul>
        </div>
    </div>
    <script>
        //获得元素
        var mUnit = document.getElementById("m_unit");
        var lis = mUnit.getElementsByTagName("li");
        var imgs = mUnit.getElementsByTagName("img");
        var box = document.getElementById("box");
        //先获得原来图片数量
        var imgLength = imgs.length;

        //复制一份ul里的内容,添加在ul后面
        mUnit.innerHTML = mUnit.innerHTML + mUnit.innerHTML;
        //全局变量,信号量
        var nowLeft = mUnit.offsetLeft;
        // console.log(nowLeft);
        //临界点,累加器,动态添加li的长度
        var maxLeft = 0;
        //定义图片加载计数的累加器
        var count = 0;
        //定义定时器变量
        var timer;
        //设置时间间隔
        var interval = 30;
        //通过图片的加载过程,得到临界点,
        for(var i = 0 ; i < imgLength ; i++){
            //自定义属性存下标
            imgs[i].index = i;
            imgs[i].onload = function(){
                count++;                
                //图片每加载一张,就可以获得对应的li的宽度。
                maxLeft += lis[this.index].clientWidth + parseFloat(getStyle(lis[this.index],"margin-right"));
                //判断累加器什么时候等于图片的个数
                if(count == imgLength){
                    //图片加载完之后做的
                    // console.log(maxLeft);
                    //开启定时器
                    timer = setInterval(move,interval);
                    //鼠标移上和移出事件也要放在图片加载完后,避免提前开启定时器
                    box.onmouseover = function(){
                        clearInterval(timer);
                    };
                    box.onmouseout = function(){
                        timer = setInterval(move,interval);
                    };
                }
            };
        }
        
        function move(){
            nowLeft -= 20;
            if(nowLeft <= -maxLeft){
                nowLeft = 0;
            }
            mUnit.style.left = nowLeft + "px";
        }
        //获得属性值函数
        function getStyle(obj,property){
                //兼容高版本和低版本浏览器,能力测试
                if(window.getComputedStyle){
                    //属性名必须是css写法,人为规范输入的属性名
                    property = property.replace(/([A-Z])/g,function(match,$1){
                        return "-" + $1.toLowerCase();
                    });
                    return window.getComputedStyle(obj)[property];
                }else if(obj.currentStyle){
                    //属性名必须是驼峰写法,人为规范输入的属性名
                    property = property.replace(/\-([a-z])/gi,function(match,$1){
                        return $1.toUpperCase();
                    });
                    return obj.currentStyle[property];
                }
            }
    </script>
</body>
</html>

json

json 对象

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>Document</title>
    <script>
        var json = {
            "name" : "nan",
            "age" : 18,
            "sex" : "男",
            "tall" : 100,
            "weight" : 178,
            "couple" : {
                "name" : "nv",
                "age" : 17,
                "sex" : "女",
                "tall" : 160,
                "weight" : 90
            }
        };
        // console.log(typeof json);
        //调用
        // console.log(json.name);
        // console.log(json.age);
        // console.log(json.sex);
        // console.log(json.tall);
        // console.log(json["weight"]);
        // console.log(json.couple);
        // console.log(json.couple.tall);
        //修改
        // json.tall = 170;
        // console.log(json);
        //删除
        // delete json.couple;
        // console.log(json);
        //添加
        json.hobby = "台球";
        console.log(json);
    </script>
</head>
<body>
    
</body>
</html>

json 遍历

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>Document</title>
    <script>
        var json = {
            "name" : "nan",
            "age" : 18,
            "sex" : "男",
            "tall" : 100,
            "weight" : 178,
            "couple" : {
                "name" : "nv",
                "age" : 17,
                "sex" : "女",
                "tall" : 160,
                "weight" : 90
            }
        };
        //输出每一个属性值,需要遍历JSON对象
        for(var k in json){
            console.log(json[k]);
        }
    </script>
</head>
<body>
    
</body>
</html>

json 拷贝

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>Document</title>
    <script>
        var json = {
            "name" : "nan",
            "age" : 18,
            "sex" : "男",
            "tall" : 100,
            "weight" : 178,
            "couple" : {
                "name" : "nv",
                "age" : 17,
                "sex" : "女",
                "tall" : 160,
                "weight" : 90
            }
        };
        //过程:新的JSON对象接收复制来的数据。给新对象添加新属性,新属性等于原对象属性,再给新属性赋值,值等于原对象属性的值。
        var newJson = {};   //必须是空的JSON对象
        for(var k in json){
            //定义新属性并赋值
            newJson[k] = json[k];
        }
        //循环完之后得到一个新的JSON
        console.log(newJson);
    </script>
</head>
<body>
    
</body>
</html>

Leave a Reply

Your email address will not be published. Required fields are marked *

6 + 10 =