Encapsulation, implementation and optimization of display layer (no animation + css3 animation + js animation)

Keywords: Javascript css3 JQuery Attribute

showhide.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>showhide</title>
    <link rel="stylesheet" href="../css/base.css">
    <style>
        body{
            width:400px;
            margin:0 auto;
        }
        button{
            width:50%;
            height:30px;
            background: #abcdef;
        }
        .box{
            width:360px;
            height:260px;
            background-color:pink;
            padding:20px;
        }
    </style>
</head>
<body>
    <button id="btn-show" class="btn">display</button><button id="btn-hide" class="btn">hide</button>
    <div class="box"></div>

    <script src="../js/jquery.js"></script>
    <script>
        var silent={
            show:function($elem,showCall,shownCall){
                if(typeof showCall === "function") showCall();
                $elem.show();
                if(typeof shownCall === "function") shownCall();
            },
            hide:function($elem,hideCall,hiddenCall){
                if(typeof showCall === "function") hideCall();
                $elem.hide();
                if(typeof shownCall === "function") hiddenCall();
            }
        }
        var css3={
            fade:{
            },
            slideUpDown:{
            },
            slideLeftRight:{
            },
            fadeSlideUpDown:{
            },
            fadeSlideLeftRight:{
            }
        }
        var js={
            fade:{
            },
            slideUpDown:{
            },
            slideLeftRight:{
            },
            fadeSlideUpDown:{
            },
            fadeSlideLeftRight:{
            }
        }

        var box=$(".box");
        var btnShow=$("#btn-show");
        var btnHide=$("#btn-hide");

        btnShow.on("click",function(){
            silent.show(box,function(){
                box.html("I want to show");
            },function(){
                setTimeout(function(){
                    box.html(box.html()+" I've shown");
                },1000)            
            });
        });

        btnHide.on("click",function(){
            silent.hide(box,function(){

            },function(){
        
            });
        });

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

Design sketch

 

 

One disadvantage of this method is that it is not suitable for multi-person cooperation

So we choose the way of publish and subscribe, and use the trigger of jquery to trigger the event

Realize multi person cooperation without interference

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>showhide</title>
    <link rel="stylesheet" href="../css/base.css">
    <style>
        body{
            width:400px;
            margin:0 auto;
        }
        button{
            width:50%;
            height:30px;
            background: #abcdef;
        }
        .box{
            width:360px;
            height:260px;
            background-color:pink;
            padding:20px;
        }
    </style>
</head>
<body>
    <button id="btn-show" class="btn">display</button><button id="btn-hide" class="btn">hide</button>
    <div class="box"></div>

    <script src="../js/jquery.js"></script>
    <script>
        var silent={
            show:function($elem){
                $elem.trigger("show");
                $elem.show();
                $elem.trigger("shown");
            },
            hide:function($elem){
                $elem.trigger("hide");
                $elem.hide();
                $elem.trigger("hidden");
            }
        }
        var css3={
            fade:{
            },
            slideUpDown:{
            },
            slideLeftRight:{
            },
            fadeSlideUpDown:{
            },
            fadeSlideLeftRight:{
            }
        }
        var js={
            fade:{
            },
            slideUpDown:{
            },
            slideLeftRight:{
            },
            fadeSlideUpDown:{
            },
            fadeSlideLeftRight:{
            }
        }

        var box=$(".box");

        $("#btn-show").on("click",function(){
            silent.show(box);
        });
        $("#btn-hide").on("click",function(e){
            silent.hide(box);
        });

        // Simulate multi person collaboration, A Operation text
        box.on("show shown",function(e){
            //console.log(e.type);
            if(e.type==="show"){
                box.html("I want to show");
            }
            if(e.type==="shown"){
                setTimeout(function(){
                    box.html(box.html()+"I've shown");
                },1000);                
            }
        });

        // Simulate multi person collaboration, B Operation background color
        box.on("show shown",function(e){
            if(e.type==="show"){
                box.css("background-color","lightgreen");
            }
            if(e.type==="shown"){
                setTimeout(function(){
                    box.css("background-color","orange");
                },1000);                
            }
        });


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

Design sketch

 

 

 

 

 

A judgment mechanism needs to be added. When it is already displayed, clicking display will no longer trigger the display event to avoid performance waste

Solve the situation of continuous clicking and multiple triggering

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>showhide</title>
    <link rel="stylesheet" href="../css/base.css">
    <style>
        body{
            width:400px;
            margin:0 auto;
        }
        button{
            width:50%;
            height:30px;
            background: #abcdef;
        }
        .box{
            width:360px;
            height:260px;
            background-color:pink;
            padding:20px;
        }
    </style>
</head>
<body>
    <button id="btn-show" class="btn">display</button><button id="btn-hide" class="btn">hide</button>
    <div class="box"></div>

    <script src="../js/jquery.js"></script>
    <script>
        var silent={
            show:function($elem){
                // No more repeated display in display state
                if($elem.data("status")==="show") return;
                if($elem.data("status")==="shown") return;

                // By setting data-status To determine the current status
                $elem.data("status","show").trigger("show");
                $elem.show();
                $elem.data("status","shown").trigger("shown");
            },
            hide:function($elem){
                if($elem.data("status")==="hide") return;
                if($elem.data("status")==="hidden") return;

                $elem.data("status","hide").trigger("hide");
                $elem.hide();
                $elem.data("status","hidden").trigger("hidden");
            }
        }
        var css3={
            fade:{
            },
            slideUpDown:{
            },
            slideLeftRight:{
            },
            fadeSlideUpDown:{
            },
            fadeSlideLeftRight:{
            }
        }
        var js={
            fade:{
            },
            slideUpDown:{
            },
            slideLeftRight:{
            },
            fadeSlideUpDown:{
            },
            fadeSlideLeftRight:{
            }
        }

        var box=$(".box");

        $("#btn-show").on("click",function(){
            silent.show(box);
        });
        $("#btn-hide").on("click",function(e){
            silent.hide(box);
        });

        box.on("show shown",function(e){
            //console.log(e.type);
            if(e.type==="show"){
                box.html("I want to show");
            }
            if(e.type==="shown"){
                setTimeout(function(){
                    box.html(box.html()+"I've shown");
                },1000);                
            }
        });

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

But since the box did not set the data status property initially, it can always be executed at least once

Therefore, it is necessary to introduce the initialization operation and add the initial data status attribute according to the status of the element

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>showhide</title>
    <link rel="stylesheet" href="../css/base.css">
    <style>
        body{
            width:400px;
            margin:0 auto;
        }
        button{
            width:50%;
            height:30px;
            background: #abcdef;
        }
        .box{
            width:360px;
            height:260px;
            background-color:pink;
            padding:20px;
        }
    </style>
</head>
<body>
    <button id="btn-show" class="btn">display</button><button id="btn-hide" class="btn">hide</button>
    <div class="box"></div>

    <script src="../js/jquery.js"></script>
    <script>
        var silent={
            init:function($elem){
                // elem.is(":hidden")Determine whether the element is hidden
                if($elem.is(":hidden")){
                    $elem.data("status","hidden");
                }else{
                    $elem.data("status","shown");
                }
            },
            show:function($elem){
                // No more repeated display in display state
                if($elem.data("status")==="show") return;
                if($elem.data("status")==="shown") return;

                // By setting data-status To determine the current status
                $elem.data("status","show").trigger("show");
                $elem.show();
                $elem.data("status","shown").trigger("shown");
            },
            hide:function($elem){
                if($elem.data("status")==="hide") return;
                if($elem.data("status")==="hidden") return;

                $elem.data("status","hide").trigger("hide");
                $elem.hide();
                $elem.data("status","hidden").trigger("hidden");
            }
        }
        var css3={
            fade:{
            },
            slideUpDown:{
            },
            slideLeftRight:{
            },
            fadeSlideUpDown:{
            },
            fadeSlideLeftRight:{
            }
        }
        var js={
            fade:{
            },
            slideUpDown:{
            },
            slideLeftRight:{
            },
            fadeSlideUpDown:{
            },
            fadeSlideLeftRight:{
            }
        }

        var box=$(".box");
        silent.init(box);
        
        $("#btn-show").on("click",function(){
            silent.show(box);
        });
        $("#btn-hide").on("click",function(e){
            silent.hide(box);
        });

        box.on("show shown",function(e){
            //console.log(e.type);
            if(e.type==="show"){
                box.html("I want to show");
            }
            if(e.type==="shown"){
                setTimeout(function(){
                    box.html(box.html()+"I've shown");
                },1000);                
            }
        });

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

Separate the encapsulated methods showhide.js

These are non animated displays

Let's try to show and hide the animation effect of css3

First add a transition transition transition to the element

css part add

        .transition{
            -webkit-transition:all .5s;
            -moz-transition:all .5s;
            -ms-transition:all .5s;
            -o-transition:all .5s;
            transition:all .5s;
        }

html part plus transition class

<div class="box transition"></div>

showhide.js

// css3 Animation mode
var css3={
    fade:{
        init:function($elem){
            // elem.is(":hidden")Determine whether the element is hidden
            if($elem.is(":hidden")){
                $elem.data("status","hidden");
            }else{
                $elem.data("status","shown");
            }
        },
        show:function($elem){
            // No more repeated display in display state
            if($elem.data("status")==="show") return;
            if($elem.data("status")==="shown") return;

            // By setting data-status To determine the current status
            $elem.data("status","show").trigger("show");
            $elem.show();
            $elem.data("status","shown").trigger("shown");
        },
        hide:function($elem){
            if($elem.data("status")==="hide") return;
            if($elem.data("status")==="hidden") return;

            $elem.data("status","hide").trigger("hide");
            $elem.hide();
            $elem.data("status","hidden").trigger("hidden");
        }
    },
    slideUpDown:{
    },
    slideLeftRight:{
    },
    fadeSlideUpDown:{
    },
    fadeSlideLeftRight:{
    }
}

Invocation time

    <script src="../js/showhide.js"></script>
    <script>
        var box=$(".box");
        silent.init(box);

        $("#btn-show").on("click",function(){
            css3.fade.show(box);
        });
        $("#btn-hide").on("click",function(e){
            css3.fade.hide(box);
        });

        box.on("show shown",function(e){
            //console.log(e.type);
            if(e.type==="show"){
                box.html("I want to show");
            }
            if(e.type==="shown"){
                setTimeout(function(){
                    box.html(box.html()+"I've shown");
                },1000);                
            }
        });

    </script>

The test found that there is still no animation effect, because there is no animation by default when the display:block or display:none of the elements are hidden

One solution is to use opacity to control animation

The disadvantage is that when opacity is set to 0, the element is still occupied and can respond to events

The problem of responding to events can be solved by visibility, and the problem of occupying space can be solved by absolute positioning

showhide.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>showhide</title>
    <link rel="stylesheet" href="../css/base.css">
    <style>
        body{
            width:400px;
            margin:0 auto;
        }
        button{
            width:50%;
            height:30px;
            background: #abcdef;
        }
        .box{
            position: absolute;/*Address occupancy issues*/
            width:360px;
            height:260px;
            background-color:pink;
            padding:20px;
        }
        .transition{
            -webkit-transition:all .5s;
            -moz-transition:all .5s;
            -ms-transition:all .5s;
            -o-transition:all .5s;
            transition:all .5s;
        }
    </style>
</head>
<body>
    <button id="btn-show" class="btn">display</button><button id="btn-hide" class="btn">hide</button>
    <div class="box transition"></div>
    <button class="btn">Test occupancy issues</button>

    <script src="../js/jquery.js"></script>
    <script src="../js/showhide.js"></script>
    <script>
        var box=$(".box");
        silent.init(box);

        $("#btn-show").on("click",function(){
            css3.fade.show(box);
        });
        $("#btn-hide").on("click",function(e){
            css3.fade.hide(box);
        });

        box.on("show shown",function(e){
            //console.log(e.type);
            if(e.type==="show"){
                box.html("I want to show");
            }
            if(e.type==="shown"){
                setTimeout(function(){
                    box.html(box.html()+"I've shown");
                },1000);                
            }
        });

        //Test found opacity 0 can still respond to events
        box.on("click",function(){
            alert("I can also respond to events~");
        })

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

showhide.js

// No animation mode
var silent={
    init:function($elem){
        // elem.is(":hidden")Determine whether the element is hidden
        if($elem.is(":hidden")){
            $elem.data("status","hidden");
        }else{
            $elem.data("status","shown");
        }
    },
    show:function($elem){
        // No more repeated display in display state
        if($elem.data("status")==="show") return;
        if($elem.data("status")==="shown") return;

        // By setting data-status To determine the current status
        $elem.data("status","show").trigger("show");
        $elem.show();
        $elem.data("status","shown").trigger("shown");
    },
    hide:function($elem){
        if($elem.data("status")==="hide") return;
        if($elem.data("status")==="hidden") return;

        $elem.data("status","hide").trigger("hide");
        $elem.hide();
        $elem.data("status","hidden").trigger("hidden");
    }
}
// css3 Animation mode
var css3={
    fade:{
        init:function($elem){
            // elem.is(":hidden")Determine whether the element is hidden
            if($elem.is(":hidden")){
                $elem.data("status","hidden");
            }else{
                $elem.data("status","shown");
            }
        },
        show:function($elem){
            // No more repeated display in display state
            if($elem.data("status")==="show") return;
            if($elem.data("status")==="shown") return;

            // By setting data-status To determine the current status
            $elem.data("status","show").trigger("show");
            $elem.css({
                "opacity":1,
                "visibility":"visible"
            });
            $elem.data("status","shown").trigger("shown");
        },
        hide:function($elem){
            if($elem.data("status")==="hide") return;
            if($elem.data("status")==="hidden") return;

            $elem.data("status","hide").trigger("hide");
            $elem.css({
                "opacity":0,
                "visibility":"hidden"//Solve the problem of responding to events
            });
            $elem.data("status","hidden").trigger("hidden");
        }
    },
    slideUpDown:{
    },
    slideLeftRight:{
    },
    fadeSlideUpDown:{
    },
    fadeSlideLeftRight:{
    }
}
// js Animation mode
var js={
    fade:{
    },
    slideUpDown:{
    },
    slideLeftRight:{
    },
    fadeSlideUpDown:{
    },
    fadeSlideLeftRight:{
    }
}

Design sketch

 

 

But it's not the ideal solution

The following solution is to combine display with show hide

showhide.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>showhide</title>
    <link rel="stylesheet" href="../css/base.css">
    <style>
        body{
            width:400px;
            margin:0 auto;
        }
        button{
            width:50%;
            height:30px;
            background: #abcdef;
        }
        .box{
            width:360px;
            height:260px;
            background-color:pink;
            padding:20px;
        }
        .transition{
            -webkit-transition:all .5s;
            -moz-transition:all .5s;
            -ms-transition:all .5s;
            -o-transition:all .5s;
            transition:all .5s;
        }
        .fadeOut{
            opacity: 0;
            visibility: hidden;
        }
    </style>
</head>
<body>
    <button id="btn-show" class="btn">display</button><button id="btn-hide" class="btn">hide</button>
    <div class="box transition"></div>
    <button class="btn">Test occupancy issues</button>

    <script src="../js/jquery.js"></script>
    <script src="../js/showhide.js"></script>
    <script>
        var box=$(".box");
        css3.fade.init(box);

        $("#btn-show").on("click",function(){
            css3.fade.show(box);
        });
        $("#btn-hide").on("click",function(e){
            css3.fade.hide(box);
        });

        box.on("show shown hide hidden",function(e){
            //console.log(e.type);
            if(e.type==="show"){
                console.log("show");
            }
            if(e.type==="shown"){
                console.log("shown");        
            }
            if(e.type==="hide"){
                console.log("hide");                        
            }
            if(e.type==="hidden"){
                console.log("hidden");                    
            }
        });


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

showhide.js

// css3 Animation mode
var css3={
    fade:{
        init:function($elem){
            // elem.is(":hidden")Determine whether the element is hidden
            if($elem.is(":hidden")){
                $elem.data("status","hidden");
            }else{
                $elem.data("status","shown");
            }
        },
        show:function($elem){
            if($elem.data("status")==="show") return;
            if($elem.data("status")==="shown") return;

            $elem.data("status","show").trigger("show");
            $elem.show();
            // transitionend Events only need to be added once, not every time
            // Therefore use one Instead of on
            $elem.one("transitionend",function(){//Execute after animation execution shown
                $elem.data("status","shown").trigger("shown");
            })
            //Use delay to achieve asynchronous effect
            //in use transition When the animation effect is not achieved, you can try to make synchronization asynchronous
            setTimeout(function(){
                $elem.removeClass("fadeOut");
            },20);        
            
        },
        hide:function($elem){
            if($elem.data("status")==="hide") return;
            if($elem.data("status")==="hidden") return;

            $elem.data("status","hide").trigger("hide");            
            //transitionend yes jquery Events to judge the execution completion status of animation
            //Hide elements after animation
            $elem.one("transitionend",function(){
                $elem.hide();
                $elem.data("status","hidden").trigger("hidden");
            })
            $elem.addClass("fadeOut");
                    
        }
    },
    slideUpDown:{
    },
    slideLeftRight:{
    },
    fadeSlideUpDown:{
    },
    fadeSlideLeftRight:{
    }
}

There is a problem in the above code, that is, when you click to display and click to hide immediately, the displayed animation will continue without stopping to hide immediately

Therefore, you need to unbind the previous transitionend before binding the transitionend event

// css3 Animation mode
var css3={
    fade:{
        init:function($elem){
            $elem.addClass("transition");
            // elem.is(":hidden")Determine whether the element is hidden
            if($elem.is(":hidden")){
                $elem.data("status","hidden");
                $elem.addClass("fadeOut");
            }else{
                $elem.data("status","shown");
            }
        },
        show:function($elem){
            if($elem.data("status")==="show") return;
            if($elem.data("status")==="shown") return;

            $elem.data("status","show").trigger("show");
            $elem.show();
            // transitionend Events only need to be added once, not every time
            // Therefore use one Instead of on
            $elem.off("transitionend").one("transitionend",function(){//Execute after animation execution shown
                $elem.data("status","shown").trigger("shown");
            })
            //Use delay to achieve asynchronous effect
            //in use transition When the animation effect is not achieved, you can try to make synchronization asynchronous
            setTimeout(function(){
                $elem.removeClass("fadeOut");
            },20);        
            
        },
        hide:function($elem){
            if($elem.data("status")==="hide") return;
            if($elem.data("status")==="hidden") return;

            $elem.data("status","hide").trigger("hide");            
            //transitionend yes jquery Events to judge the execution completion status of animation
            //Hide elements after animation
            $elem.off("transitionend").one("transitionend",function(){
                $elem.hide();
                $elem.data("status","hidden").trigger("hidden");
            })
            $elem.addClass("fadeOut");
                    
        }
    },
    slideUpDown:{
    },
    slideLeftRight:{
    },
    fadeSlideUpDown:{
    },
    fadeSlideLeftRight:{
    }
}

Because there is a lot of code redundancy in the css3 mode and the default animation free mode, the repeated part is extracted into a common function

The following is the result of the code's slimming:

showhide.js

// public init
function init($elem,hiddenCall){
    if($elem.is(":hidden")){
        $elem.data("status","hidden");
        if(typeof hiddenCall==="function") hiddenCall();
    }else{
        $elem.data("status","shown");
    }    
}
//public show
function show($elem,callback){
    if($elem.data("status")==="show") return;
    if($elem.data("status")==="shown") return;

    $elem.data("status","show").trigger("show");
    callback();
}
// public hide
function hide($elem,callback){
    if($elem.data("status")==="hide") return;
    if($elem.data("status")==="hidden") return;

    $elem.data("status","hide").trigger("hide");
    callback();
}
// No animation mode
var silent={
    init:init,
    show:function($elem){
        show($elem,function(){
            $elem.show();
            $elem.data("status","shown").trigger("shown");
        });
    },
    hide:function($elem){
        hide($elem,function(){
            $elem.hide();
            $elem.data("status","hidden").trigger("hidden");
        });
    }
}
// css3 Animation mode
var css3={
    fade:{
        init:function($elem){
            $elem.addClass("transition");
            init($elem,function(){
                $elem.addClass("fadeOut");
            });
        },
        show:function($elem){
            show($elem,function(){
                $elem.off("transitionend").one("transitionend",function(){//Execute after animation execution shown
                    $elem.data("status","shown").trigger("shown");
                })
                $elem.show();
                setTimeout(function(){
                    $elem.removeClass("fadeOut");
                },20);        
            });
        },
        hide:function($elem){
            hide($elem,function(){
                $elem.off("transitionend").one("transitionend",function(){
                    $elem.hide();
                    $elem.data("status","hidden").trigger("hidden");
                })
                $elem.addClass("fadeOut");
            });
        }
    },
    slideUpDown:{
    },
    slideLeftRight:{
    },
    fadeSlideUpDown:{
    },
    fadeSlideLeftRight:{
    }
}
// js Animation mode
var js={
    fade:{
    },
    slideUpDown:{
    },
    slideLeftRight:{
    },
    fadeSlideUpDown:{
    },
    fadeSlideLeftRight:{
    }
}

 

 

There is a compatibility problem with transitionend, which requires compatibility processing (not supported under IE9)

Create a transition.js

(function(){
    //judge transition Property exists
    //Existence: empty string
    //Non-existent: undefined
    //console.log(document.body.style.transition);
    var transitionName={
        transition:"transitionend",
        mozTransition:"transitionend",
        webkitTransition:"webkitTransitionEnd",
        oTransition:"oTransitionEnd otransitionend"
    };

    var transitionEnd="";
    var isSupport=false;

    for(var name in transitionName){
        if(document.body.style[name]!="undefined"){
            //Explain existence
            transitionEnd=transitionName[name];
            isSupport=true;
            break;
        }
    }
    //Take a local variable as an attribute of a global variable
    window.mt=window.mt || {};//If it exists, it will continue to exist. If it does not exist, an empty object will be created
    window.mt.transition=transitionEnd;
    window.mt.isSupport=isSupport;

})();

Test in page

    <script src="../js/jquery.js"></script>
    <script src="../js/transition.js"></script>
    <script src="../js/showhide.js"></script>
    <script>
        console.log(window.mt.transition);//transitionend
        console.log(window.mt.isSupport);//true
    </script>

 

showhide.js modify

var transition=window.mt.transition;

// public init
function init($elem,hiddenCall){
    if($elem.is(":hidden")){
        $elem.data("status","hidden");
        if(typeof hiddenCall==="function") hiddenCall();
    }else{
        $elem.data("status","shown");
    }    
}
//public show
function show($elem,callback){
    if($elem.data("status")==="show") return;
    if($elem.data("status")==="shown") return;

    $elem.data("status","show").trigger("show");
    callback();
}
// public hide
function hide($elem,callback){
    if($elem.data("status")==="hide") return;
    if($elem.data("status")==="hidden") return;

    $elem.data("status","hide").trigger("hide");
    callback();
}
// No animation mode
var silent={
    init:init,
    show:function($elem){
        show($elem,function(){
            $elem.show();
            $elem.data("status","shown").trigger("shown");
        });
    },
    hide:function($elem){
        hide($elem,function(){
            $elem.hide();
            $elem.data("status","hidden").trigger("hidden");
        });
    }
}
// css3 Animation mode
var css3={
    fade:{
        init:function($elem){
            $elem.addClass("transition");
            init($elem,function(){
                $elem.addClass("fadeOut");
            });
        },
        show:function($elem){
            show($elem,function(){
                $elem.off(transition).one(transition,function(){//Execute after animation execution shown
                    $elem.data("status","shown").trigger("shown");
                })
                $elem.show();
                setTimeout(function(){
                    $elem.removeClass("fadeOut");
                },20);        
            });
        },
        hide:function($elem){
            hide($elem,function(){
                $elem.off(transition).one(transition,function(){
                    $elem.hide();
                    $elem.data("status","hidden").trigger("hidden");
                })
                $elem.addClass("fadeOut");
            });
        }
    },
    slideUpDown:{
    },
    slideLeftRight:{
    },
    fadeSlideUpDown:{
    },
    fadeSlideLeftRight:{
    }
}
// js Animation mode
var js={
    fade:{
    },
    slideUpDown:{
    },
    slideLeftRight:{
    },
    fadeSlideUpDown:{
    },
    fadeSlideLeftRight:{
    }
}

Implementation of up and down scrolling in css3

First, add the style of shrink state in css

/*Contraction style*/
.slideUpDownCollapse{
    height:0 !important;/*Avoid failure to take effect due to insufficient priority*/
}

Add code to showhide.js

// css3 Animation mode
var css3={
    fade:{
        init:function($elem){
            $elem.addClass("transition");
            init($elem,function(){
                $elem.addClass("fadeOut");
            });
        },
        show:function($elem){
            show($elem,function(){
                $elem.off(transition).one(transition,function(){//Execute after animation execution shown
                    $elem.data("status","shown").trigger("shown");
                })
                $elem.show();
                setTimeout(function(){
                    $elem.removeClass("fadeOut");
                },20);        
            });
        },
        hide:function($elem){
            hide($elem,function(){
                $elem.off(transition).one(transition,function(){
                    $elem.hide();
                    $elem.data("status","hidden").trigger("hidden");
                })
                $elem.addClass("fadeOut");
            });
        }
    },
    slideUpDown:{
        init:function($elem){
            $elem.addClass("transition");
            init($elem,function(){
                $elem.addClass("slideUpDownCollapse");
            });
        },
        show:function($elem){
            show($elem,function(){
                $elem.off(transition).one(transition,function(){//Execute after animation execution shown
                    $elem.data("status","shown").trigger("shown");
                })
                $elem.show();
                setTimeout(function(){
                    $elem.removeClass("slideUpDownCollapse");
                },20);        
            });
        },
        hide:function($elem){
            hide($elem,function(){
                $elem.off(transition).one(transition,function(){
                    $elem.hide();
                    $elem.data("status","hidden").trigger("hidden");
                })
                $elem.addClass("slideUpDownCollapse");
            });
        }
    },
    slideLeftRight:{
    },
    fadeSlideUpDown:{
    },
    fadeSlideLeftRight:{
    }
}

call

    <script src="../js/jquery.js"></script>
    <script src="../js/transition.js"></script>
    <script src="../js/showhide.js"></script>
    <script>
        //console.log(window.mt.transition);//transitionend
        //console.log(window.mt.isSupport);//true

        var box=$(".box");
        css3.slideUpDown.init(box);

        $("#btn-show").on("click",function(){
            css3.slideUpDown.show(box);
        });
        $("#btn-hide").on("click",function(e){
            css3.slideUpDown.hide(box);
        });

        box.on("show shown hide hidden",function(e){
            //console.log(e.type);
            if(e.type==="show"){
                console.log("show");
            }
            if(e.type==="shown"){
                console.log("shown");        
            }
            if(e.type==="hide"){
                console.log("hide");                        
            }
            if(e.type==="hidden"){
                console.log("hidden");                    
            }
        });


    </script>

This is achieved by modifying the height of the element. It is possible that the element itself does not have height, but is supported by padding top and padding bottom, such as:

        .box{
            width:400px;
            /*height:300px;*//*height Distraction*/    
            padding:150px 0;/*padding Distraction*/        
            background-color:pink;
        }

This is to set padding to 0 in the shrink class

        /*Contraction style*/
        .slideUpDownCollapse{
            height:0 !important;/*Avoid failure to take effect due to insufficient priority*/
            padding-top:0 !important;
            padding-bottom:0 !important;
        }

Sometimes the element is not set with height or padding, but is spread by the content of the element

In this case, you need to obtain the height of the element after it is spread by the content in initialization, and then set the height of the element to this height

Note that the container needs to be set to hide overflow

        .box{
            width:400px;
            /*height:300px;*//*height Distraction*/    
            /*padding:150px 0;*//*padding Distraction*/        
            background-color:pink;
            overflow:hidden;/*The height of being opened by content needs to be set to hide overflow*/
        }

In the initialization of showhide.js, add:

init:function($elem){
            $elem.height($elem.height());//Get the height of the element being opened by the content, and set the height dynamically
            $elem.addClass("transition");
            init($elem,function(){
                $elem.addClass("slideUpDownCollapse");
            });
        },

It can be found that there are a lot of duplicate code in different methods of css3, so it is necessary to extract the code again

Extract the common part of css3. Inside css3, you can use the beginning of _ (beginning of underscore) for naming

slideLeftRight: similar to slideUpDown, change the related operation of height to width, and the related operation of padding top / padding bottom to padding left / padding right

fadeSlideUpDown: similar to slideUpDown, add fadeOut and slideUpDown collapse classes

fadeSlideLeftRight: similar to slideLeftRight, add fadeOut and slideLeftRightCollapse classes

At this point, all animation styles of css3 are completed:

showhide.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>showhide</title>
    <link rel="stylesheet" href="../css/base.css">
    <style>
        body{
            width:400px;
            margin:0 auto;
        }
        button{
            width:50%;
            height:30px;
            background: #abcdef;
        }
        .box{
            width:400px;
            /*height:300px;*//*height Distraction*/    
            /*padding:150px 0;*//*padding Distraction*/        
            background-color:pink;
            overflow:hidden;/*The height of being opened by content needs to be set to hide overflow*/
        }
        .transition{
            -webkit-transition:all .5s;
            -moz-transition:all .5s;
            -ms-transition:all .5s;
            -o-transition:all .5s;
            transition:all .5s;
        }
        .fadeOut{
            opacity: 0;
            visibility: hidden;
        }
        /*Contraction style*/
        .slideUpDownCollapse{
            height:0 !important;/*Avoid failure to take effect due to insufficient priority*/
            padding-top:0 !important;
            padding-bottom:0 !important;
        }
        .slideLeftRightCollapse{
            width:0 !important;/*Avoid failure to take effect due to insufficient priority*/
            padding-left:0 !important;
            padding-right:0 !important;
        }
    </style>
</head>
<body>
    <button id="btn-show" class="btn">display</button><button id="btn-hide" class="btn">hide</button>
    <div class="box">
        //content<br>
        //Distraction<br>
        //height<br>
    </div>
    <button class="btn">Test occupancy issues</button>

    <script src="../js/jquery.js"></script>
    <script src="../js/transition.js"></script>
    <script src="../js/showhide.js"></script>
    <script>
        //console.log(window.mt.transition);//transitionend
        //console.log(window.mt.isSupport);//true

        var box=$(".box");
        css3.fadeSlideLeftRight.init(box);

        $("#btn-show").on("click",function(){
            css3.fadeSlideLeftRight.show(box);
        });
        $("#btn-hide").on("click",function(e){
            css3.fadeSlideLeftRight.hide(box);
        });

        box.on("show shown hide hidden",function(e){
            //console.log(e.type);
            if(e.type==="show"){
                console.log("show");
            }
            if(e.type==="shown"){
                console.log("shown");        
            }
            if(e.type==="hide"){
                console.log("hide");                        
            }
            if(e.type==="hidden"){
                console.log("hidden");                    
            }
        });


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

showhide.js

// css3 Animation mode
var css3={
    _init:function($elem,className){
        $elem.addClass("transition");
        init($elem,function(){
            $elem.addClass(className);
        });        
    },
    _show:function($elem,className){
        $elem.off(transition).one(transition,function(){//Execute after animation execution shown
            $elem.data("status","shown").trigger("shown");
        })
        $elem.show();
        setTimeout(function(){
            $elem.removeClass(className);
        },20);            
    },
    _hide:function($elem,className){
        $elem.off(transition).one(transition,function(){
            $elem.hide();
            $elem.data("status","hidden").trigger("hidden");
        })
        $elem.addClass(className);
    },
    //Fade in and fade out
    fade:{
        init:function($elem){
            css3._init($elem,"fadeOut");
        },
        show:function($elem){
            show($elem,function(){
                css3._show($elem,"fadeOut");    
            });
        },
        hide:function($elem){
            hide($elem,function(){
                css3._hide($elem,"fadeOut");
            });
        }
    },
    //Sliding up and down
    slideUpDown:{
        init:function($elem){        
            $elem.height($elem.height());//Get the height of the element being opened by the content, and set the height dynamically
            css3._init($elem,"slideUpDownCollapse");
        },
        show:function($elem){
            show($elem,function(){
                css3._show($elem,"slideUpDownCollapse");        
            });
        },
        hide:function($elem){
            hide($elem,function(){
                css3._hide($elem,"slideUpDownCollapse");
            });
        }
    },
    //Sliding left and right
    slideLeftRight:{
        init:function($elem){        
            $elem.width($elem.width());//Get the height of the element being opened by the content, and set the height dynamically
            css3._init($elem,"slideLeftRightCollapse");
        },
        show:function($elem){
            show($elem,function(){
                css3._show($elem,"slideLeftRightCollapse");        
            });
        },
        hide:function($elem){
            hide($elem,function(){
                css3._hide($elem,"slideLeftRightCollapse");
            });
        }
    },
    //Fade in fade out slide up and down
    fadeSlideUpDown:{
        init:function($elem){        
            $elem.height($elem.height());//Get the height of the element being opened by the content, and set the height dynamically
            css3._init($elem,"fadeOut slideUpDownCollapse");
        },
        show:function($elem){
            show($elem,function(){
                css3._show($elem,"fadeOut slideUpDownCollapse");        
            });
        },
        hide:function($elem){
            hide($elem,function(){
                css3._hide($elem,"fadeOut slideUpDownCollapse");
            });
        }
    },
    //Fade in and fade out slide left and right
    fadeSlideLeftRight:{
        init:function($elem){        
            $elem.width($elem.width());//Get the height of the element being opened by the content, and set the height dynamically
            css3._init($elem,"fadeOut slideLeftRightCollapse");
        },
        show:function($elem){
            show($elem,function(){
                css3._show($elem,"fadeOut slideLeftRightCollapse");        
            });
        },
        hide:function($elem){
            hide($elem,function(){
                css3._hide($elem,"fadeOut slideLeftRightCollapse");
            });
        }
    }
}

 

Next is the js animation part

First of all, fadeIn(fn) fadeOut(fn) slideDown(fn) slideUp(fn) is encapsulated by jquery, just use it directly

// js Animation mode
var js={
    fade:{
        init:function($elem){
            $elem.removeClass("transition");
            //If used js The elements of the animation are set transition Property, which will cause animation disorder
            //You need to make sure that the element does not transition attribute
            init($elem);
        },
        show:function($elem){
            show($elem,function(){
                //jquery Packaged fadeIn(fn)
                $elem.stop().fadeIn(function(){
                    $elem.data("status","shown").trigger("shown");
                });            
            });
        },
        hide:function($elem){
            hide($elem,function(){
                //jquery Packaged fadeOut(fn)
                $elem.stop().fadeOut(function(){
                    $elem.data("status","hidden").trigger("hidden");
                });            
            });
        }        
    },
    slideUpDown:{
        init:function($elem){
            $elem.removeClass("transition");
            //If used js The elements of the animation are set transition Property, which will cause animation disorder
            //You need to make sure that the element does not transition attribute
            init($elem);
        },
        show:function($elem){
            show($elem,function(){
                //jquery Packaged slideDown(fn)
                $elem.stop().slideDown(function(){
                    $elem.data("status","shown").trigger("shown");
                });
            });
        },
        hide:function($elem){
            hide($elem,function(){
                $elem.stop().slideUp(function(){
                    $elem.data("status","hidden").trigger("hidden");
                });                
            });
        }    
    },
    slideLeftRight:{
    },
    fadeSlideUpDown:{
    },
    fadeSlideLeftRight:{
    }
}

According to international practice, it is still to extract the public part

// js Animation mode
var js={
    _init:function($elem){
        $elem.removeClass("transition");
        init($elem);        
    },
    _show:function($elem,mode){
        show($elem,function(){
            $elem.stop()[mode](function(){
                $elem.data("status","shown").trigger("shown");
            });            
        });        
    },
    _hide:function($elem,mode){
        hide($elem,function(){
            $elem.stop()[mode](function(){
                $elem.data("status","hidden").trigger("hidden");
            });            
        });        
    },
    fade:{
        init:function($elem){
            js._init($elem);
        },
        show:function($elem){
            js._show($elem,"fadeIn");
        },
        hide:function($elem){
            js._hide($elem,"fadeOut");
        }        
    },
    slideUpDown:{
        init:function($elem){
            js._init($elem);
        },
        show:function($elem){
            js._show($elem,"slideDown");
        },
        hide:function($elem){
            js._hide($elem,"slideUp");
        }    
    },
    slideLeftRight:{
    },
    fadeSlideUpDown:{
    },
    fadeSlideLeftRight:{
    }
}

slideLeftRight has no encapsulated jquery method, so you need to write your own

The general idea is to change width padding left padding right

    slideLeftRight:{
        init:function($elem){
            //Get the style attribute at the beginning of the element
            var styles={};
            styles["width"]=$elem.css("width");
            styles["padding-left"]=$elem.css("padding-left");
            styles["padding-right"]=$elem.css("padding-right");
            $elem.data("styles",styles);//If not saved, then styles Local, cannot be used in other functions

            $elem.removeClass("transition");

            init($elem,function(){
                $elem.css({
                    "width":0,
                    "padding-left":0,
                    "padding-right":0
                });
            });
        },
        show:function($elem){
            show($elem,function(){
                var styles=$elem.data("styles");

                $elem.show();
                //Use animate Animate            
                $elem.stop().animate({
                    "width":styles["width"],
                    "padding-left":styles["padding-left"],
                    "padding-right":styles["padding-right"]
                },function(){//Callback after animation
                    $elem.data("status","shown").trigger("shown");
                });
            });
        },
        hide:function($elem){
            hide($elem,function(){
                //Use animate Animate            
                $elem.stop().animate({
                    "width":0,
                    "padding-left":0,
                    "padding-right":0
                },function(){//Callback after animation
                    $elem.hide();
                    $elem.data("status","hidden").trigger("hidden");
                });
            });
        }            
    },

fadeSlideUpDown is similar to slideLeftRight, except that width padding left padding right is replaced by height padding top padding bottom, plus opacity

    slideLeftRight:{
        init:function($elem){
            //Get the style attribute at the beginning of the element
            var styles={};
            styles["width"]=$elem.css("width");
            styles["padding-left"]=$elem.css("padding-left");
            styles["padding-right"]=$elem.css("padding-right");
            $elem.data("styles",styles);//If not saved, then styles Local, cannot be used in other functions

            $elem.removeClass("transition");

            init($elem,function(){
                $elem.css({
                    "width":0,
                    "padding-left":0,
                    "padding-right":0
                });
            });
        },
        show:function($elem){
            show($elem,function(){
                var styles=$elem.data("styles");

                $elem.show();
                //Use animate Animate            
                $elem.stop().animate({
                    "width":styles["width"],
                    "padding-left":styles["padding-left"],
                    "padding-right":styles["padding-right"]
                },function(){//Callback after animation
                    $elem.data("status","shown").trigger("shown");
                });
            });
        },
        hide:function($elem){
            hide($elem,function(){
                //Use animate Animate            
                $elem.stop().animate({
                    "width":0,
                    "padding-left":0,
                    "padding-right":0
                },function(){//Callback after animation
                    $elem.hide();
                    $elem.data("status","hidden").trigger("hidden");
                });
            });
        }            
    },
    fadeSlideUpDown:{
        init:function($elem){
            //Get the style attribute at the beginning of the element
            var styles={};
            styles["opacity"]=$elem.css("opacity");
            styles["height"]=$elem.css("height");
            styles["padding-top"]=$elem.css("padding-top");
            styles["padding-bottom"]=$elem.css("padding-bottom");
            $elem.data("styles",styles);//If not saved, then styles Local, cannot be used in other functions

            $elem.removeClass("transition");

            init($elem,function(){
                $elem.css({
                    "opacity":0,
                    "height":0,
                    "padding-top":0,
                    "padding-bottom":0
                });
            });
        },
        show:function($elem){
            show($elem,function(){
                var styles=$elem.data("styles");

                $elem.show();
                //Use animate Animate            
                $elem.stop().animate({
                    "opacity":styles["opacity"],
                    "height":styles["height"],
                    "padding-top":styles["padding-top"],
                    "padding-bottom":styles["padding-bottom"]
                },function(){//Callback after animation
                    $elem.data("status","shown").trigger("shown");
                });
            });
        },
        hide:function($elem){
            hide($elem,function(){
                //Use animate Animate            
                $elem.stop().animate({
                    "opacity":0,
                    "height":0,
                    "padding-top":0,
                    "padding-bottom":0
                },function(){//Callback after animation
                    $elem.hide();
                    $elem.data("status","hidden").trigger("hidden");
                });
            });
        }    
    },

Continue to extract public parts in accordance with international practice

Complete all js animation parts

// js Animation mode
var js={
    _init:function($elem,callback){
        $elem.removeClass("transition");
        init($elem,callback);        
    },
    _show:function($elem,mode){
        show($elem,function(){
            $elem.stop()[mode](function(){
                $elem.data("status","shown").trigger("shown");
            });            
        });        
    },
    _hide:function($elem,mode){
        hide($elem,function(){
            $elem.stop()[mode](function(){
                $elem.data("status","hidden").trigger("hidden");
            });            
        });        
    },
    //Custom initialization common part
    _customInit:function($elem,options){//options Is an object that contains all the attributes to be changed        
        var styles={};
        for(var o in options){
            styles[o]=$elem.css(o);
        }

        $elem.data("styles",styles);//If not saved, then styles Local, cannot be used in other functions

        js._init($elem,function(){
            $elem.css(options);
        });
    },
    _customShow:function($elem){
        show($elem,function(){
            var styles=$elem.data("styles");

            $elem.show();
            //Use animate Animate            
            $elem.stop().animate(styles,function(){//Callback after animation
                $elem.data("status","shown").trigger("shown");
            });
        });        
    },
    _customHide:function($elem,options){
        hide($elem,function(){        
            $elem.stop().animate(options,function(){//Callback after animation
                $elem.hide();
                $elem.data("status","hidden").trigger("hidden");
            });
        });
    },
    fade:{
        init:function($elem){
            js._init($elem);
        },
        show:function($elem){
            js._show($elem,"fadeIn");
        },
        hide:function($elem){
            js._hide($elem,"fadeOut");
        }        
    },
    slideUpDown:{
        init:function($elem){
            js._init($elem);
        },
        show:function($elem){
            js._show($elem,"slideDown");
        },
        hide:function($elem){
            js._hide($elem,"slideUp");
        }    
    },
    slideLeftRight:{
        init:function($elem){
            js._customInit($elem,{
                "width":0,
                "padding-left":0,
                "padding-right":0
            });
        },
        show:function($elem){
            js._customShow($elem);
        },
        hide:function($elem){
            js._customHide($elem,{
                "width":0,
                "padding-left":0,
                "padding-right":0
            });
        }            
    },
    fadeSlideUpDown:{
        init:function($elem){
            js._customInit($elem,{
                "opacity":0,
                "height":0,
                "padding-top":0,
                "padding-bottom":0
            });
        },
        show:function($elem){
            js._customShow($elem);
        },
        hide:function($elem){
            js._customHide($elem,{
                "opacity":0,
                "height":0,
                "padding-top":0,
                "padding-bottom":0
            });
        }    
    },
    fadeSlideLeftRight:{
        init:function($elem){
            js._customInit($elem,{
                "opacity":0,
                "width":0,
                "padding-left":0,
                "padding-right":0
            });
        },
        show:function($elem){
            js._customShow($elem);
        },
        hide:function($elem){
            js._customHide($elem,{
                "opacity":0,
                "width":0,
                "padding-left":0,
                "padding-right":0
            });
        }    
    }
}

Finally, you need to encapsulate the above code into a module

Encapsulated showhide.js

(function($){
    var transition=window.mt.transition;//Supportive transition attribute
    var isSupport=window.mt.isSupport;//Whether to support transition

    // public init
    function init($elem,hiddenCall){
        if($elem.is(":hidden")){
            $elem.data("status","hidden");
            if(typeof hiddenCall==="function") hiddenCall();
        }else{
            $elem.data("status","shown");
        }    
    }
    //public show
    function show($elem,callback){
        if($elem.data("status")==="show") return;
        if($elem.data("status")==="shown") return;

        $elem.data("status","show").trigger("show");
        callback();
    }
    // public hide
    function hide($elem,callback){
        if($elem.data("status")==="hide") return;
        if($elem.data("status")==="hidden") return;

        $elem.data("status","hide").trigger("hide");
        callback();
    }
    // No animation mode
    var silent={
        init:init,
        show:function($elem){
            show($elem,function(){
                $elem.show();
                $elem.data("status","shown").trigger("shown");
            });
        },
        hide:function($elem){
            hide($elem,function(){
                $elem.hide();
                $elem.data("status","hidden").trigger("hidden");
            });
        }
    }
    // css3 Animation mode
    var css3={
        _init:function($elem,className){
            $elem.addClass("transition");
            init($elem,function(){
                $elem.addClass(className);
            });        
        },
        _show:function($elem,className){
            $elem.off(transition).one(transition,function(){//Execute after animation execution shown
                $elem.data("status","shown").trigger("shown");
            })
            $elem.show();
            setTimeout(function(){
                $elem.removeClass(className);
            },20);            
        },
        _hide:function($elem,className){
            $elem.off(transition).one(transition,function(){
                $elem.hide();
                $elem.data("status","hidden").trigger("hidden");
            })
            $elem.addClass(className);
        },
        //Fade in and fade out
        fade:{
            init:function($elem){
                css3._init($elem,"fadeOut");
            },
            show:function($elem){
                show($elem,function(){
                    css3._show($elem,"fadeOut");    
                });
            },
            hide:function($elem){
                hide($elem,function(){
                    css3._hide($elem,"fadeOut");
                });
            }
        },
        //Sliding up and down
        slideUpDown:{
            init:function($elem){        
                $elem.height($elem.height());//Get the height of the element being opened by the content, and set the height dynamically
                css3._init($elem,"slideUpDownCollapse");
            },
            show:function($elem){
                show($elem,function(){
                    css3._show($elem,"slideUpDownCollapse");        
                });
            },
            hide:function($elem){
                hide($elem,function(){
                    css3._hide($elem,"slideUpDownCollapse");
                });
            }
        },
        //Sliding left and right
        slideLeftRight:{
            init:function($elem){        
                $elem.width($elem.width());//Get the height of the element being opened by the content, and set the height dynamically
                css3._init($elem,"slideLeftRightCollapse");
            },
            show:function($elem){
                show($elem,function(){
                    css3._show($elem,"slideLeftRightCollapse");        
                });
            },
            hide:function($elem){
                hide($elem,function(){
                    css3._hide($elem,"slideLeftRightCollapse");
                });
            }
        },
        //Fade in fade out slide up and down
        fadeSlideUpDown:{
            init:function($elem){        
                $elem.height($elem.height());//Get the height of the element being opened by the content, and set the height dynamically
                css3._init($elem,"fadeOut slideUpDownCollapse");
            },
            show:function($elem){
                show($elem,function(){
                    css3._show($elem,"fadeOut slideUpDownCollapse");        
                });
            },
            hide:function($elem){
                hide($elem,function(){
                    css3._hide($elem,"fadeOut slideUpDownCollapse");
                });
            }
        },
        //Fade in and fade out slide left and right
        fadeSlideLeftRight:{
            init:function($elem){        
                $elem.width($elem.width());//Get the height of the element being opened by the content, and set the height dynamically
                css3._init($elem,"fadeOut slideLeftRightCollapse");
            },
            show:function($elem){
                show($elem,function(){
                    css3._show($elem,"fadeOut slideLeftRightCollapse");        
                });
            },
            hide:function($elem){
                hide($elem,function(){
                    css3._hide($elem,"fadeOut slideLeftRightCollapse");
                });
            }
        }
    }
    // js Animation mode
    var js={
        _init:function($elem,callback){
            $elem.removeClass("transition");
            init($elem,callback);        
        },
        _show:function($elem,mode){
            show($elem,function(){
                $elem.stop()[mode](function(){
                    $elem.data("status","shown").trigger("shown");
                });            
            });        
        },
        _hide:function($elem,mode){
            hide($elem,function(){
                $elem.stop()[mode](function(){
                    $elem.data("status","hidden").trigger("hidden");
                });            
            });        
        },
        //Custom initialization common part
        _customInit:function($elem,options){//options Is an object that contains all the attributes to be changed        
            var styles={};
            for(var o in options){
                styles[o]=$elem.css(o);
            }

            $elem.data("styles",styles);//If not saved, then styles Local, cannot be used in other functions

            js._init($elem,function(){
                $elem.css(options);
            });
        },
        _customShow:function($elem){
            show($elem,function(){
                var styles=$elem.data("styles");

                $elem.show();
                //Use animate Animate            
                $elem.stop().animate(styles,function(){//Callback after animation
                    $elem.data("status","shown").trigger("shown");
                });
            });        
        },
        _customHide:function($elem,options){
            hide($elem,function(){        
                $elem.stop().animate(options,function(){//Callback after animation
                    $elem.hide();
                    $elem.data("status","hidden").trigger("hidden");
                });
            });
        },
        fade:{
            init:function($elem){
                js._init($elem);
            },
            show:function($elem){
                js._show($elem,"fadeIn");
            },
            hide:function($elem){
                js._hide($elem,"fadeOut");
            }        
        },
        slideUpDown:{
            init:function($elem){
                js._init($elem);
            },
            show:function($elem){
                js._show($elem,"slideDown");
            },
            hide:function($elem){
                js._hide($elem,"slideUp");
            }    
        },
        slideLeftRight:{
            init:function($elem){
                js._customInit($elem,{
                    "width":0,
                    "padding-left":0,
                    "padding-right":0
                });
            },
            show:function($elem){
                js._customShow($elem);
            },
            hide:function($elem){
                js._customHide($elem,{
                    "width":0,
                    "padding-left":0,
                    "padding-right":0
                });
            }            
        },
        fadeSlideUpDown:{
            init:function($elem){
                js._customInit($elem,{
                    "opacity":0,
                    "height":0,
                    "padding-top":0,
                    "padding-bottom":0
                });
            },
            show:function($elem){
                js._customShow($elem);
            },
            hide:function($elem){
                js._customHide($elem,{
                    "opacity":0,
                    "height":0,
                    "padding-top":0,
                    "padding-bottom":0
                });
            }    
        },
        fadeSlideLeftRight:{
            init:function($elem){
                js._customInit($elem,{
                    "opacity":0,
                    "width":0,
                    "padding-left":0,
                    "padding-right":0
                });
            },
            show:function($elem){
                js._customShow($elem);
            },
            hide:function($elem){
                js._customHide($elem,{
                    "opacity":0,
                    "width":0,
                    "padding-left":0,
                    "padding-right":0
                });
            }    
        }
    }

    //Set default parameters
    var defaults={
        css3:false,
        js:false,
        animation:"fade"
    };

    //Encapsulate a function
    function showHide($elem,options){
        //$.extend( target [, object1 ] [, objectN ] )
        //If there is only one parameter, the default is target yes jquery Object, which is used for global objects jQuery Add new function
        //If more than one object has the same attribute, the latter overrides the former's attribute value for merging objects
        //Here, options Parameters will override the default parameters, and the merged parameters will be assigned to options object
        var options=$.extend({},defaults,options);
        var mode=null;if(options.css3 && isSupport){//css3 animation
            mode=css3[options.animation] || css3[defaults.animation];//fault-tolerant
        }else if(options.js){//js animation
            mode=js[options.animation] || js[defaults.animation];
        }else{//No animation
            mode=silent;
        }

        mode.init($elem);
        //Use the corresponding method as the function return value
        return {
            // $.proxy(Functions, pointing, arguments)
            // It was originally used to change the this Point, this is mainly used to pass parameters
            // show:$.proxy(mode.show,this,$elem),
            // hide:$.proxy(mode.hide,this,$elem)
            show:mode.show,
            hide:mode.hide
        };

    }

    window.mt=window.mt||{};
    window.mt.showHide=showHide;//take showHide Functions exposed globally

})(jQuery);

To supplement the $. extend() usage here

$.extend( target, [obj1], [objn]

If there is only one parameter, the default target is jQuery, which is used to add new functions to jquery

If there are more than one parameter, it is used for object merging. If more than one object has the same property, the later one will overwrite the previous one

 

When called:

    <script>

        var box=$(".box");

        //It's not elegant
        //You need to transfer in box
        var showHide=window.mt.showHide(box,{
            css3:true,
            animation:"fadeSlideUpDown"
        });

        $("#btn-show").on("click",function(){
            showHide.show(box);//You need to transfer in box
        });
        $("#btn-hide").on("click",function(e){
            showHide.hide(box);//You need to transfer in box
        });

        box.on("show shown hide hidden",function(e){
            if(e.type==="show"){
                console.log("show");
            }
            if(e.type==="shown"){
                console.log("shown");        
            }
            if(e.type==="hide"){
                console.log("hide");                        
            }
            if(e.type==="hidden"){
                console.log("hidden");                    
            }
        });

    </script>

In the above code calls, it can be found that box needs to be passed in three times, which is cumbersome

If you want to pass in only once, you need to make the following changes in showhide.js:

        //Use the corresponding method as the function return value
        return {
            // show:mode.show,
            // hide:mode.hide
            
            // $.proxy(Functions, pointing, arguments)
            // It was originally used to change the this Point, this is mainly used to pass parameters
            show:$.proxy(mode.show,this,$elem),
            hide:$.proxy(mode.hide,this,$elem)            
        };

In this case, only one place needs to be passed into the box

    <script>

        var box=$(".box");

        //Only here need to pass in box
        var showHide=window.mt.showHide(box,{
            css3:true,
            animation:"fadeSlideUpDown"
        });

        $("#btn-show").on("click",function(){
            showHide.show();//Use $.proxy After passing parameters, you no longer need to pass in parameters here

        });
        $("#btn-hide").on("click",function(e){
            showHide.hide();//Use $.proxy After passing parameters, you no longer need to pass in parameters here

        });

        box.on("show shown hide hidden",function(e){
            if(e.type==="show"){
                console.log("show");
            }
            if(e.type==="shown"){
                console.log("shown");        
            }
            if(e.type==="hide"){
                console.log("hide");                        
            }
            if(e.type==="hidden"){
                console.log("hidden");                    
            }
        });

    </script>

 

Here is a supplement to the usage of $. proxy():

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>proxy</title>
</head>
<body>
    <button>Click on me</button>

    <script src="../js/jquery.js"></script>
    <script>
        var obj={
            oname:"cyy",
            otell:function(){
                console.log(this.oname);
            }
        }
        obj.otell();//cyy   this point obj


        $("button").on("click",obj.otell);//Click the button to print undefined  
        // Reason: this Point to the button Elements, and button Element not oname attribute

        
        $("button").on("click",$.proxy(obj.otell,obj));//cyy
        // Solution 1: $.proxy(Method, this point)
        
        
        $("button").on("click",$.proxy(obj,"otell"));//cyy
        //Solution 2: $.proxy(this Point to, method name)
        //Solution 1 is equivalent to solution 2

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

 

 

 

 

Refer to the above solution 1: $. Proxy (method, this point, [parameter])

The third parameter is the method parameter. If there is no parameter, it can not be passed

In general, $. proxy() is used to change the direction of this. Here, we use it to pass parameters, so we don't need to pass parameters repeatedly when calling

 

However, the above call method is not elegant enough

The most recommended way is to use the jquery plug-in, and then modify the code

showhide.js

(function($){
    var transition=window.mt.transition;//Supportive transition attribute
    var isSupport=window.mt.isSupport;//Whether to support transition

    // public init
    function init($elem,hiddenCall){
        if($elem.is(":hidden")){
            $elem.data("status","hidden");
            if(typeof hiddenCall==="function") hiddenCall();
        }else{
            $elem.data("status","shown");
        }    
    }
    //public show
    function show($elem,callback){
        if($elem.data("status")==="show") return;
        if($elem.data("status")==="shown") return;

        $elem.data("status","show").trigger("show");
        callback();
    }
    // public hide
    function hide($elem,callback){
        if($elem.data("status")==="hide") return;
        if($elem.data("status")==="hidden") return;

        $elem.data("status","hide").trigger("hide");
        callback();
    }
    // No animation mode
    var silent={
        init:init,
        show:function($elem){
            show($elem,function(){
                $elem.show();
                $elem.data("status","shown").trigger("shown");
            });
        },
        hide:function($elem){
            hide($elem,function(){
                $elem.hide();
                $elem.data("status","hidden").trigger("hidden");
            });
        }
    }
    // css3 Animation mode
    var css3={
        _init:function($elem,className){
            $elem.addClass("transition");
            init($elem,function(){
                $elem.addClass(className);
            });        
        },
        _show:function($elem,className){
            $elem.off(transition).one(transition,function(){//Execute after animation execution shown
                $elem.data("status","shown").trigger("shown");
            })
            $elem.show();
            setTimeout(function(){
                $elem.removeClass(className);
            },20);            
        },
        _hide:function($elem,className){
            $elem.off(transition).one(transition,function(){
                $elem.hide();
                $elem.data("status","hidden").trigger("hidden");
            })
            $elem.addClass(className);
        },
        //Fade in and fade out
        fade:{
            init:function($elem){
                css3._init($elem,"fadeOut");
            },
            show:function($elem){
                show($elem,function(){
                    css3._show($elem,"fadeOut");    
                });
            },
            hide:function($elem){
                hide($elem,function(){
                    css3._hide($elem,"fadeOut");
                });
            }
        },
        //Sliding up and down
        slideUpDown:{
            init:function($elem){        
                $elem.height($elem.height());//Get the height of the element being opened by the content, and set the height dynamically
                css3._init($elem,"slideUpDownCollapse");
            },
            show:function($elem){
                show($elem,function(){
                    css3._show($elem,"slideUpDownCollapse");        
                });
            },
            hide:function($elem){
                hide($elem,function(){
                    css3._hide($elem,"slideUpDownCollapse");
                });
            }
        },
        //Sliding left and right
        slideLeftRight:{
            init:function($elem){        
                $elem.width($elem.width());//Get the height of the element being opened by the content, and set the height dynamically
                css3._init($elem,"slideLeftRightCollapse");
            },
            show:function($elem){
                show($elem,function(){
                    css3._show($elem,"slideLeftRightCollapse");        
                });
            },
            hide:function($elem){
                hide($elem,function(){
                    css3._hide($elem,"slideLeftRightCollapse");
                });
            }
        },
        //Fade in fade out slide up and down
        fadeSlideUpDown:{
            init:function($elem){        
                $elem.height($elem.height());//Get the height of the element being opened by the content, and set the height dynamically
                css3._init($elem,"fadeOut slideUpDownCollapse");
            },
            show:function($elem){
                show($elem,function(){
                    css3._show($elem,"fadeOut slideUpDownCollapse");        
                });
            },
            hide:function($elem){
                hide($elem,function(){
                    css3._hide($elem,"fadeOut slideUpDownCollapse");
                });
            }
        },
        //Fade in and fade out slide left and right
        fadeSlideLeftRight:{
            init:function($elem){        
                $elem.width($elem.width());//Get the height of the element being opened by the content, and set the height dynamically
                css3._init($elem,"fadeOut slideLeftRightCollapse");
            },
            show:function($elem){
                show($elem,function(){
                    css3._show($elem,"fadeOut slideLeftRightCollapse");        
                });
            },
            hide:function($elem){
                hide($elem,function(){
                    css3._hide($elem,"fadeOut slideLeftRightCollapse");
                });
            }
        }
    }
    // js Animation mode
    var js={
        _init:function($elem,callback){
            $elem.removeClass("transition");
            init($elem,callback);        
        },
        _show:function($elem,mode){
            show($elem,function(){
                $elem.stop()[mode](function(){
                    $elem.data("status","shown").trigger("shown");
                });            
            });        
        },
        _hide:function($elem,mode){
            hide($elem,function(){
                $elem.stop()[mode](function(){
                    $elem.data("status","hidden").trigger("hidden");
                });            
            });        
        },
        //Custom initialization common part
        _customInit:function($elem,options){//options Is an object that contains all the attributes to be changed        
            var styles={};
            for(var o in options){
                styles[o]=$elem.css(o);
            }

            $elem.data("styles",styles);//If not saved, then styles Local, cannot be used in other functions

            js._init($elem,function(){
                $elem.css(options);
            });
        },
        _customShow:function($elem){
            show($elem,function(){
                var styles=$elem.data("styles");

                $elem.show();
                //Use animate Animate            
                $elem.stop().animate(styles,function(){//Callback after animation
                    $elem.data("status","shown").trigger("shown");
                });
            });        
        },
        _customHide:function($elem,options){
            hide($elem,function(){        
                $elem.stop().animate(options,function(){//Callback after animation
                    $elem.hide();
                    $elem.data("status","hidden").trigger("hidden");
                });
            });
        },
        fade:{
            init:function($elem){
                js._init($elem);
            },
            show:function($elem){
                js._show($elem,"fadeIn");
            },
            hide:function($elem){
                js._hide($elem,"fadeOut");
            }        
        },
        slideUpDown:{
            init:function($elem){
                js._init($elem);
            },
            show:function($elem){
                js._show($elem,"slideDown");
            },
            hide:function($elem){
                js._hide($elem,"slideUp");
            }    
        },
        slideLeftRight:{
            init:function($elem){
                js._customInit($elem,{
                    "width":0,
                    "padding-left":0,
                    "padding-right":0
                });
            },
            show:function($elem){
                js._customShow($elem);
            },
            hide:function($elem){
                js._customHide($elem,{
                    "width":0,
                    "padding-left":0,
                    "padding-right":0
                });
            }            
        },
        fadeSlideUpDown:{
            init:function($elem){
                js._customInit($elem,{
                    "opacity":0,
                    "height":0,
                    "padding-top":0,
                    "padding-bottom":0
                });
            },
            show:function($elem){
                js._customShow($elem);
            },
            hide:function($elem){
                js._customHide($elem,{
                    "opacity":0,
                    "height":0,
                    "padding-top":0,
                    "padding-bottom":0
                });
            }    
        },
        fadeSlideLeftRight:{
            init:function($elem){
                js._customInit($elem,{
                    "opacity":0,
                    "width":0,
                    "padding-left":0,
                    "padding-right":0
                });
            },
            show:function($elem){
                js._customShow($elem);
            },
            hide:function($elem){
                js._customHide($elem,{
                    "opacity":0,
                    "width":0,
                    "padding-left":0,
                    "padding-right":0
                });
            }    
        }
    }

    //Set default parameters
    var defaults={
        css3:false,
        js:false,
        animation:"fade"
    };

    //Encapsulate a function
    function showHide($elem,options){
        var mode=null;

        if(options.css3 && isSupport){//css3 animation
            mode=css3[options.animation] || css3[defaults.animation];//fault-tolerant
        }else if(options.js){//js animation
            mode=js[options.animation] || js[defaults.animation];
        }else{//No animation
            mode=silent;
        }

        mode.init($elem);

        return {
            show:$.proxy(mode.show,this,$elem),
            hide:$.proxy(mode.hide,this,$elem)            
        };    
    }

    // Change to jquery Plug-in mode        
    $.fn.extend({
        showHide:function(opt){
            //this Point to the element calling the plug-in, here is box
            //It can be one or more elements, so use each ergodic
            return this.each(function(){
                var ui=$(this);
                // If options Parameter object is passed, then options Attribute and defaults Property is merged and stored in the empty object and assigned to options
                // If options If the object is not passed; otherwise false,Attribute is defaults Default property and assign to options
                // $.extend(target, obj1, objn) Object merging
                var options=$.extend({},defaults,typeof opt==="object" && opt);
                    
                /*
                    opt When it is a parameter object, such as:
                    box.showHide({
                        css3:true,
                        animation:"slideLeftRight"            
                    });
                */        
                var mode=ui.data("showHide");    
                //mode Object instances only need to be generated once                    
                if(!mode){
                    mode=showHide(ui,options);//mode Return contains show and hide Method
                    ui.data("showHide",mode);
                }
                
                /*
                    opt When it is a show or hide string, for example:
                    box.showHide("show");
                */
                //If options yes show perhaps hide String, execute method
                if(typeof mode[opt]==="function"){
                    mode[opt]();
                }
            })
            
        }
    });

})(jQuery);

showhide.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>showhide</title>
    <link rel="stylesheet" href="../css/base.css">
    <style>
        body{
            width:400px;
            margin:0 auto;
        }
        button{
            width:50%;
            height:30px;
            background: #abcdef;
        }
        .box{
            width:400px;
            /*height:300px;*//*height Distraction*/    
            /*padding:150px 0;*//*padding Distraction*/        
            background-color:pink;
            overflow:hidden;/*The height of being opened by content needs to be set to hide overflow*/
        }
        .transition{
            -webkit-transition:all .5s;
            -moz-transition:all .5s;
            -ms-transition:all .5s;
            -o-transition:all .5s;
            transition:all .5s;
        }
        .fadeOut{
            opacity: 0;
            visibility: hidden;
        }
        /*Contraction style*/
        .slideUpDownCollapse{
            height:0 !important;/*Avoid failure to take effect due to insufficient priority*/
            padding-top:0 !important;
            padding-bottom:0 !important;
        }
        .slideLeftRightCollapse{
            width:0 !important;/*Avoid failure to take effect due to insufficient priority*/
            padding-left:0 !important;
            padding-right:0 !important;
        }
    </style>
</head>
<body>
    <button id="btn-show" class="btn">display</button><button id="btn-hide" class="btn">hide</button>
    <div class="box">
        //content<br>
        //Distraction<br>
        //height<br>
    </div>
    <button class="btn">Test occupancy issues</button>

    <script src="../js/jquery.js"></script>
    <script src="../js/transition.js"></script>
    <script src="../js/showhide.js"></script>
    <script>

        var box=$(".box");

        //jquery Plug in mode parameters
        box.showHide({
            css3:true,
            animation:"slideLeftRight"            
        });//Return a containing show and hide Object of method mode

        $("#btn-show").on("click",function(){
            //jquery Plug in mode call
            box.showHide("show");
        });
        $("#btn-hide").on("click",function(e){
            //jquery Plug in mode call
            box.showHide("hide");
        });

        box.on("show shown hide hidden",function(e){
            if(e.type==="show"){
                console.log("show");
            }
            if(e.type==="shown"){
                console.log("shown");        
            }
            if(e.type==="hide"){
                console.log("hide");                        
            }
            if(e.type==="hidden"){
                console.log("hidden");                    
            }
        });

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

Final rendering

 

Knowledge point supplement:

The difference between trigger and trigger handler:

The difference is that trigger will cause the default behavior of the same name of the browser to execute, such as:

trigger('submit '); will not only execute the effect of submit() function, but also the effect of form submission;

The trigger handler does not cause the default behavior to be executed.

In addition, they are very similar. If you can achieve the same effect, you can use either one

 

$.fn $.fn.extend $.extend difference:

$.fn

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>fnExtend</title>
    <style>
        .box{
            width:200px;
            height:200px;
            padding:20px;
            text-align:center;
            line-height: 200px;
            border:1px solid #333;
            margin:100px auto;
        }
    </style>
</head>
<body>
    <div class="box">I am box</div>
    <script src="../js/jquery.js"></script>
    <script>
        //$.fn Only one method can be added at a time
        $.fn.pink=function(){
            $(this).css("background-color","pink");
        };
        
        $(".box").pink();//div Pink background
        $.pink();//Cannot call directly
    </script>
</body>
</html>

 

 $.fn.extend

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>fnExtend</title>
    <style>
        .box{
            width:200px;
            height:200px;
            padding:20px;
            text-align:center;
            line-height: 200px;
            border:1px solid #333;
            margin:100px auto;
        }
    </style>
</head>
<body>
    <div class="box">I am box</div>
    <script src="../js/jquery.js"></script>
    <script>

        //$.fn.extend Add methods to the prototype object. Multiple methods can be added
        $.fn.extend({
            pink:function(){
                $(this).css("background-color","pink");
            },
            blue:function(){
                $(this).css("background-color","#abcdef");
            }
        });
        $(".box").blue();//div The background turns blue
        //$.blue();//Cannot call directly
        
        // Merge object function. If the object has the same properties, the later one will overwrite the previous one
        var obj1={
            a:1,
            b:2
        };
        var obj2={
            b:3,
            c:4
        };
        $.fn.extend(obj1,obj2);//take obj2 merge to obj1 in
        console.log(obj1);//{a: 1, b: 3, c: 4}

        var newObj=$.fn.extend({},obj1,obj2);//take obj2 and obj1 Merge into empty object, assign to newObj
        console.log(newObj);//{a: 1, b: 3, c: 4}
    </script>
</body>
</html>

 

 

$.extend

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>fnExtend</title>
    <style>
        .box{
            width:200px;
            height:200px;
            padding:20px;
            text-align:center;
            line-height: 200px;
            border:1px solid #333;
            margin:100px auto;
        }
    </style>
</head>
<body>
    <div class="box">I am box</div>
    <script src="../js/jquery.js"></script>
    <script>
    
        //$.extend New method
        $.extend({
            pink:function(){
                console.log("pink");
            },
            blue:function(){
                console.log("blue");
            }            
        });
        $.blue();//blue  Direct call required
        $(".box").blue();//Report errors

        // Merge objects, functions and $.fn.extend identical
        var obj1={
            a:1,
            b:2
        };
        var obj2={
            b:3,
            c:4
        };
        $.extend(obj1,obj2);//take obj2 merge to obj1 in
        console.log(obj1);//{a: 1, b: 3, c: 4}
    </script>
</body>
</html>

Conclusion:

$.fn

Only one method can be added at a time

Cannot call directly. Element elem. Method name () is required

 

$.fn.extend

Add methods to the prototype object. Multiple methods can be added

Cannot call directly. Element elem. Method name () is required

Merge object function. If the object has the same properties, the later one will overwrite the previous one

 

$.extend

Add methods to the prototype object. Multiple methods can be added

Must be called directly, cannot have element $. Method name ()

Merge object function. If the object has the same properties, the later one will overwrite the previous one

Posted by chalexan on Fri, 21 Feb 2020 22:43:51 -0800