上移下移扩展版 【总结】

需求


上移下移
需求:
1)点击上移就将当前的按钮的父级上移一位

2)当点击第一个时候将当前按钮的父级移动到最后一位

3)当点击最后一个时候将当前按钮的父级移动到首位

4)带过渡动画

 

需求分析:

下移:剪切所点击的条目插入到下一条目后面

上移:剪切所点击的条目插入到上一条目前面

 

过渡效果实现:CSS3的transition 或 js实现

 

实现思路:

transition实现方法,先在CSS里设置好transition: 1s top; 这个样式,然后鼠标点击修改top值触发过渡效果。

需要用js给每一个li设置top值,因为insertBefore会中断transition所以还必须设个定时器,等到过渡结束再执行DOM层面的剪切

难点:

边界的判断:当第一项点击上移是应该移动到最下面其他都上移一层

      当最后一项点击下移时应该移动到最上面其他都下移一层

insertBefore为什么会中断transition的执行???

难点解决方案:

前两项都可以解决

最后一项想不通!!!???

涉及的新知识:

element.priviousSibling

element.nextSibling

element.parentNode

element.nodeType

parentNode.insertBefore( newEle , targetEle );

优化方向:

不用定时器也能实现DOM层面和视觉层面一起上移下移且有过渡动画

修复连续点击的bug

封装成一个函数

备注:

 写完这个,稍微有点懂得【视觉层】和【行为层】分开的意义了,也稍微感觉到了一点React的数据驱动视图了。其实页面上看到的天花乱坠,DOM里可能啥都每变,看起来div在那个div的上门,其实是用css强行改变它们的默认排列的,所以要从DOM的视角看问题。

最后:为什么insertBefore会中断transition????

 

 

 

 

 

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>

<style>
    a{ text-decoration: none; }
    a:hover{ text-decoration: underline; }

ul{ position: relative; }

li{
    position: absolute;
    transition: .5s top;
}

</style>

</head>
<body>


<!-- 
上移下移
    需求:
        1)点击上移就将当前的按钮的父级上移一位
        
        2)当点击第一个时候将当前按钮的父级移动到最后一位
        
        3)当点击最后一个时候将当前按钮的父级移动到首位
        
    
    跨展板:
        移动时带动画
 -->



<ul id="oUl">
    <li>第一项 <a href="javascript:;">上移</a> <a href="javascript:;">下移</a></li>
    <li>第二项 <a href="javascript:;">上移</a> <a href="javascript:;">下移</a></li>
    <li>第三项 <a href="javascript:;">上移</a> <a href="javascript:;">下移</a></li>
    <li>第四项 <a href="javascript:;">上移</a> <a href="javascript:;">下移</a></li>
    <li>第五项 <a href="javascript:;">上移</a> <a href="javascript:;">下移</a></li>
</ul>



<script src="getId.js"></script>
<script src="doMove.js"></script>
<script src="main.js"></script>





</body>
</html>

 

 

var oUl = $('oUl');
var oLi = oUl.getElementsByTagName('li');





for(var i=0, oLen=oLi.length; i<oLen; i++){

    
    oLi[i].style.top = (i*16 + i*6) + 'px';


    //****上移按钮
    oLi[i].getElementsByTagName('a')[0].onclick = function(){


        var oldTop = null,
            nextTop = null,
            nextItem = getSiEle( this.parentNode , -1 );



        //点击第一项要做的事
        if( !nextItem ){

            nextTop = oUl.children[oUl.children.length-1].style.top;

            //2~5项向上移1格
            for( var j=oUl.children.length-1; j>0; j--  ){
                oLi[j].style.top = oLi[j-1].style.top;
            }

            this.parentNode.style.top = nextTop;

        }else{
            //如果不是最后一项就两两对换
            oldTop = this.parentNode.style.top;
            nextTop = getSiEle( this.parentNode , -1 ).style.top;
            this.parentNode.style.top = nextTop;
            getSiEle( this.parentNode , -1 ).style.top = oldTop;
        }
        

        //等0.5s的transition结束后在执行DOM剪切操作
        var _this = this;
        setTimeout(function(){
            if( !moveUp( _this.parentNode ) ){
                oUl.appendChild( _this.parentNode )
            }
        },500);





    }
    //****上移按钮结束****//






    //****下移按钮开始
    oLi[i].getElementsByTagName('a')[1].onclick = function(){

        var oldTop = null,
            nextTop = null,
            nextItem = getSiEle( this.parentNode , 1 );


        //点击最后第一项要做的事
        if( !nextItem ){

            nextTop = oUl.children[0].style.top;

            //1~4项的位置下降“1格”
            for(var j=0,oLen=oUl.children.length; j<oLen-1; j++  ){
                oLi[j].style.top = oLi[j+1].style.top
            }

            //点击项升到顶端
            this.parentNode.style.top = nextTop;

        }else{
            //如果不是最后一项就两两对换
            oldTop = this.parentNode.style.top;
            nextTop = getSiEle( this.parentNode , 1 ).style.top;
            this.parentNode.style.top = nextTop;
            getSiEle( this.parentNode , 1 ).style.top = oldTop;
        }
        

        //等0.5s的transition结束后在执行DOM剪切操作
        var _this = this;
        setTimeout(function(){
            if( !moveDown( _this.parentNode ) ){
                insertBefore( _this.parentNode , oUl.children[0] );
            }
        },500);

    }
    //****下移按钮结束****//





}

 

 

 

function $( v ){
    if(typeof v === 'function'){
        window.onload = v;
    }else if(typeof v === 'string'){
        return document.getElementById( v );
    }else if(typeof v === 'object'){
        return v;
    }
}



function getStyle( obj,attr ){
    var arr = '';
    for(var i=0; i<attr.length; i++){
        if(attr[i] != ' ')
            arr += attr[i];
    }

    return obj.currentStyle ? obj.currentStyle[arr] : getComputedStyle(obj)[arr];
} 



function $class(typeEle,attr){
    var oChild = document.getElementsByTagName(typeEle);
    var arr = [];
    for(var i=0; i<oChild.length; i++){
        if( oChild[i].className == attr ){
            arr.push(oChild[i]);
        }

    }


    return arr;

}





function getSiEle( ele , v ){


    //-1代表查找前一个兄弟元素,1代表查找后一个兄弟元素
    //开始查找前判断本元素是不是第一个元素或最后一个元素,如果是返回false
    //开始查找

    if( v === -1 ){
        v = 'previousSibling'; 

        if( ele.parentNode.children[0] == ele ){
            return false;
        }

    }

    if( v === 1 ){
        v = 'nextSibling';

        if( ele == ele.parentNode.children[ ele.parentNode.children.length-1 ] ){
            return false;
        }

    }


    
    var theParent = ele[v];
    while( theParent.nodeType != 1 ){
        theParent = theParent[v];
    }
    return theParent;
    


    
}


//重新包装一下
function insertBefore( newEle , targetEle ){

    targetEle.parentNode.insertBefore( newEle , targetEle );

}


//向targetEle后面插入一个元素节点
function insertAfter( newEle , targetEle ){

    var tNextSibling = targetEle.nextSibling;
    var targetEleParent = targetEle.parentNode;

    if( tNextSibling ){
        targetEleParent.insertBefore( newEle , tNextSibling );
    }else{
        targetEleParent.appendChild( newEle );
    }

}



//上移
function moveUp( ele ){
    var tSiEle = getSiEle( ele , -1 );

    if( !tSiEle ){
        return false;
    }

    ele.parentNode.insertBefore( ele , tSiEle );
    return true;

}


//下移
function moveDown( ele ){
    var tSiEle = getSiEle( ele , 1 );

    if( !tSiEle ){
        return false;
    }

    insertAfter( ele , tSiEle );
    console.log(555);
    return true;

}
















/*


while(true){
    if( oDiv[oDiv.length-1] != 400 ){
        FdoMove(400);
    }else{
        FdoMove(0);
    }
}




function FdoMove(endStep){


    document.onclick = function(){
        clearInterval(attrs.timer);
        attrs.timer = setInterval(function(){

            if(endStep != 0){

                if(  parseInt(oDiv[attrs.i].style.top) == endStep )
                    attrs.i++;

                if( attrs.i < oDiv.length ){
                    doMove( oDiv[attrs.i], 'top', 90, endStep );
                }else{
                    clearInterval(attrs.timer);
                    attrs.timer = null;
                }

            }else{


                if(  parseInt(oDiv[attrs.lastNum].style.top) == endStep )
                    attrs.lastNum--;

                if( attrs.lastNum >= endStep ){
                    doMove( oDiv[attrs.lastNum], 'top', 90, endStep );
                }else{
                    clearInterval(attrs.timer);
                    attrs.timer = null;
                }


            }



        },90);



    }



}*/

 

转载于:https://www.cnblogs.com/mflnhg/p/9503309.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值