第十节 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, {width: 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, {width: 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, {width: 300, height: 300, opacity: 100});”改为“startMove(oDiv, {width: 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, {width: 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

 

转载于:https://www.cnblogs.com/han-bky/p/10264500.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值