• 第十节 JS运动中级


    链式运动框架、

      回调函数

        运动停止时,执行函数

        运动停止时,开始下一次运动

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>运动框架</title>
        <style>
            #div1{
                width: 100px;
                height: 100px;
                background: red;
                filter: alpha(opacity:30);
                opacity: 0.3;
            }
        </style>
        <script src="32.js"></script>
        <script>
            window.onload = function(){
                var oDiv = document.getElementById('div1');
    
                //链式运动——收缩展开运动
                oDiv.onmouseover = function(){
                    startMove(oDiv, 'width', 300, function(){
                        // alert('宽度已变大!');
                        startMove(oDiv, 'height', 300, function () {
                            startMove(oDiv, 'opacity', 100);
                        });
                    });
                };
                oDiv.onmouseout = function(){
                    startMove(oDiv, 'opacity', 30, function(){
                        // alert('宽度已变大!');
                        startMove(oDiv, 'height', 100, function () {
                            startMove(oDiv, 'width', 100);
                        });
                    });
                };
            };
        </script>
    </head>
    <body>
        <div id="div1"></div>
    </body>
    </html>
    View Code
    function getStyle(obj, name) {
        if (obj.currentStyle) {
            return obj.currentStyle[name];
        } else {
            return getComputedStyle(obj, false)[name];
        }
    }
    
    function startMove(obj, attr, iTarget, fnEnd) {
        clearInterval(obj.timer);
        obj.timer = setInterval(function () {
            var cur = 0;
    
            if (attr == 'opacity') {
                cur = Math.round(parseFloat(getStyle(obj, attr))*100);  //乘以100符合咱们平时对opacity的设置
            } else {
                cur = parseInt(getStyle(obj, attr));
            }
    
            var speed = (iTarget-cur)/6;
            speed = speed>0?Math.ceil(speed):Math.floor(speed);
    
            if (cur==iTarget) {
                clearInterval(obj.timer);
    
                if (fnEnd) fnEnd();//当参数传进来且运动结束后被调用
            } else {
                if (attr == 'opacity') {
                    obj.style.filter = 'alpha(opacity:'+(cur+speed)+')';    //IE透明度
                    obj.style.opacity = (cur+speed)/100;
    
                    var oTxt = document.getElementById('txt1');
                    oTxt.value = obj.style.opacity;
                } else {
                    obj.style[attr] = cur+speed+'px';
                }
    
            }
        }, 30);
    }
    32.js

        例子:土豆天气预报弹窗(已下架)    由于图片没有调好就没有写,有兴趣可根据上述代码自行写出

    完美运动框架

      多个值同时变化(首先是出错情况)

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>运动框架小问题</title>
        <style>
            #div1{width: 100px;
                height: 100px;
                background: red;
            }
        </style>
        <script src="32.js"></script>
        <script>
            window.onload = function(){
                var oBtn = document.getElementById('btn1');
                var oDiv = document.getElementById('div1');
    
                oBtn.onclick = function () {
                    startMove(oDiv, 'width', 300);
                    startMove(oDiv, 'height', 300);
                };
                //问题来了,如果不加此句“startMove(oDiv, 'height', 300);” 则div变宽,好像没什么问题;
                //但是如果加上此句“startMove(oDiv, 'height', 300);” div只变长了,而未变宽,所以也就是说,
                //不能让多个值同时变化,否则会出错,解决办法是:用json循环来修改运动框架
            };
        </script>
    </head>
    <body>
    <input id="btn1" type="button" value="运动"/>
    <div id="div1"></div>
    </body>
    </html>
    View Code

         setStyle同时设置多个属性

          参数传递:JSon的使用,for in遍历属性

          var json = {a:12, b:5};
          for (var i in json){ //json循环
            alert(i+'='+json[i]);
          }

          运用到运动框架

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>运动框架小问题</title>
        <style>
            #div1{width: 100px;
                height: 100px;
                background: red;
                filter: alpha(Opacity=30);
                opacity: 0.3;
            }
        </style>
        <script src="33.js"></script>
        <script>
            window.onload = function(){
                var oBtn = document.getElementById('btn1');
                var oDiv = document.getElementById('div1');
    
                oBtn.onclick = function () {
                    // startMove(oDiv, 'width', 300);
                    // startMove(oDiv, 'height', 300);
                    startMove(oDiv, { 300, height: 300, opacity: 100});     //此时长和宽是同时运动的
                };
                //问题来了,如果不加此句“startMove(oDiv, 'height', 300);” 则div变宽,好像没什么问题;
                //但是如果加上此句“startMove(oDiv, 'height', 300);” div只变长了,而未变宽,所以也就是说,
                //不能让多个值同时变化,否则会出错,解决办法是:用json循环来修改运动框架,解决如上
            };
        </script>
    </head>
    <body>
    <input id="btn1" type="button" value="运动"/>
    <div id="div1"></div>
    </body>
    </html>
    View Code
    function getStyle(obj, name) {
        if (obj.currentStyle) {
            return obj.currentStyle[name];
        } else {
            return getComputedStyle(obj, false)[name];
        }
    }
    
    //32.js的改进版,json循环的使用
    //startMove(oDiv, { 400, height: 400})
    
    function startMove(obj, json, fnEnd) {
        clearInterval(obj.timer);
        obj.timer = setInterval(function () {
            for (var attr in json) {
                var cur = 0;
    
                if (attr == 'opacity') {
                    cur = Math.round(parseFloat(getStyle(obj, attr))*100);  //乘以100符合咱们平时对opacity的设置
                } else {
                    cur = parseInt(getStyle(obj, attr));
                }
    
                var speed = (json[attr]-cur)/6;
                speed = speed>0?Math.ceil(speed):Math.floor(speed);
    
                if (cur==json[attr]) {
                    clearInterval(obj.timer);
    
                    if (fnEnd) fnEnd();//当参数传进来且运动结束后被调用
                } else {
                    if (attr == 'opacity') {
                        obj.style.filter = 'alpha(opacity:'+(cur+speed)+')';    //IE透明度
                        obj.style.opacity = (cur+speed)/100;
    
                        var oTxt = document.getElementById('txt1');
                        oTxt.value = obj.style.opacity;
                    } else {
                        obj.style[attr] = cur+speed+'px';
                    }
    
                }
            }
        }, 30);
    }
    33.js

      说“33.js”是一个完美运动框架,那是因为在一般应用情况下,该运动框架是不会出现什么错误,但是若我们把“startMove(oDiv, { 300, height: 300, opacity: 100});”改为“startMove(oDiv, { 101, height: 300, opacity: 100});”也就是说,宽度只增加一个像素,高度仍然增加200像素,此时运行时,高度的增加会出现一些小错误,即不会增加到300px,原因是,系统不会自己搜索每个状态是不是已经达到目标值,而是只要有一个达到目标值,系统就把定时器关掉了,所以才会出现错误,改进方法如下:(其中改进版的“33-1.js”,才是真正意义上的完美运动框架)

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>完美运动框架</title>
        <style>
            #div1{width: 100px;
                height: 100px;
                background: red;
                filter: alpha(Opacity=30);
                opacity: 0.3;
            }
        </style>
        <script src="33-1.js"></script>
        <script>
            window.onload = function(){
                var oBtn = document.getElementById('btn1');
                var oDiv = document.getElementById('div1');
    
                oBtn.onclick = function () {
                    startMove(oDiv, { 101, height: 300, opacity: 100}, function () {  //此时长、宽和透明度同时运动
                        alert("定时器已全部关闭!");     //该函数是检验程序是否运行完成的。
                    });     
                };
            };
        </script>
    </head>
    <body>
    <input id="btn1" type="button" value="运动"/>
    <div id="div1"></div>
    </body>
    </html>
    View Code
    function getStyle(obj, name) {
        if (obj.currentStyle) {
            return obj.currentStyle[name];
        } else {
            return getComputedStyle(obj, false)[name];
        }
    }
    
    function startMove(obj, json, fnEnd) {
        clearInterval(obj.timer);
        obj.timer = setInterval(function () {
    
            var bStop = true;   //假设所有的值都已经到了
    
            for (var attr in json) {
                var cur = 0;
    
                if (attr == 'opacity') {
                    cur = Math.round(parseFloat(getStyle(obj, attr))*100);  //乘以100符合咱们平时对opacity的设置
                } else {
                    cur = parseInt(getStyle(obj, attr));
                }
    
                var speed = (json[attr]-cur)/6;
                speed = speed>0?Math.ceil(speed):Math.floor(speed);
    
                if (cur != json[attr])      //如果有一个值不等于目标值
                    bStop = false;
    
                // if (cur==json[attr]) {
                //     clearInterval(obj.timer);
                //
                //     if (fnEnd) fnEnd();//当参数传进来且运动结束后被调用
                // } else {
    
                // 改进提前关定时器的代码如下,先把之前关定时器的代码注释掉
                    if (attr == 'opacity') {
                        obj.style.filter = 'alpha(opacity:'+(cur+speed)+')';    //IE透明度
                        obj.style.opacity = (cur+speed)/100;
                    } else {
                        obj.style[attr] = cur+speed+'px';
                    }
    
                    obj.style[attr] = cur+speed+'px';
                // }
            }
    
            if (bStop) {    //如果bStop还是保持为true的话
                clearInterval(obj.timer);
    
                if (fnEnd) fnEnd();
            }
        }, 30);
    }
    33-1.js

      检测运动停止(标志变量)    例子:伸缩同时淡入淡出的菜单,如上

    运动框架总结:

      运动框架的演变过程:

        startMove(iTarget)  运动框架  //学习入门

        startMove(obj, iTarget)  多物体  //多出的参数“obj”可以任意指定让那个物体动起来

        startMove(obj, attr, iTarget)  任意值  //可以任意指定一个物体动起来

        startMove(obj, attr, iTarget, fn)  链式运动  //参数“fn”为当 前一次 运动结束之后,我们可以用“fn”再做一次运动

        startMove(obj, json)  多值运动  //可以把多个值同时运动

        startMove(obj, json, fn)  完美运动框架  //可以多值、多物体同时运动了

    运动框架应用:

      例:幻灯片

        思想是:overflow=hidden,当显示 第0张图片时,top=0;当显示第1张图片时,第0张的top=-150;……当显示第n张图片时,第0张的top=-150*n;

      链式运动:新浪微博

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>li淡出淡入</title>
        <style>
            *{margin: 0;  padding: 0;}
            #ul1{
                width: 400px;
                height: 400px;
                border: 1px solid black;
                margin: 10px auto;
                overflow: hidden;
            }
            #ul1 li{
                border-bottom: 1px #999 dashed;
                padding: 4px;
                list-style: none;
                overflow: hidden;
                filter: alpha(opacity:0);
                opacity: 0;
            }
        </style>
        <script src="33-1.js"></script>
        <script>
            window.onload = function () {
                var oBtn = document.getElementById('btn1');
                var oUl = document.getElementById('ul1');
                var oTxt = document.getElementById('txt1');
    
                oBtn.onclick = function () {
                    var oLi = document.createElement('li');
    
                    oLi.innerHTML = oTxt.value;
                    oTxt.value = '';
    
                    if (oUl.children.length>0){
                        oUl.insertBefore(oLi, oUl.children[0]);
                    } else {
                        oUl.appendChild(oLi);
                    }
    
                    //运动
                    var iHeight = oLi.offsetHeight;
                    //先让高度展开
                    oLi.style.height = '0';
    
                    //链式运动的应用
                    startMove(oLi, {height: iHeight}, function () {     //先是高度展开,然后淡出
                        startMove(oLi, {opacity: 100});
                    });
    
                };
            };
        </script>
    </head>
    <body>
        <textarea id="txt1" rows="4" cols="40"></textarea>
        <button id="btn1">发布</button>
        <ul id="ul1">
            <li>asldfjkba</li>
        </ul>
    </body>
    </html>
    View Code
  • 相关阅读:
    input 蓝边
    4.【ac自动机】模式串匹配
    3.【二叉树】最近公共祖先
    2.【动态规划】最长回文子串
    1. 【线段树】
    DbUtil
    oauth2
    cas
    Spring-security-web
    JSON Web Tokens
  • 原文地址:https://www.cnblogs.com/han-bky/p/10264500.html
Copyright © 2020-2023  润新知