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