显示隐藏模块封装

来源:2-11 将显示隐藏封装成模块--完善

soso_crazy

2019-04-03 18:18:55

<!DOCTYPE html>

<html lang="en">


<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<meta http-equiv="X-UA-Compatible" content="ie=edge">

<title>显示与隐藏模块</title>

<link rel="stylesheet" href="../../作业素材/code/css/base.css">

<script src="../js/jquery-3.3.1.js"></script>

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

<script src="../js/showhide模块.js"></script>

<style>

body {

width: 400px;

margin: 0 auto;

position: relative;

}

.btn {

width: 50%;

height: 30px;

}

#box {

display: none;

position: absolute;

width: 100%;

height: 200px;

background-color: red;

overflow: hidden;

}

.transition {

transition: all 0.5s;

-webkit-transition: all 0.5s;

-moz-transition: all 0.5s;

-ms-transition: all 0.5s;

-o-transition: all 0.5s;

}

.fadeOut {

visibility: visible;

opacity: 0;

}

.slideUpDownCollapse {

/* 当移除了这个类,高度就会显示为原本高度 */

height: 0 !important;

/* id的优先级比class高,所以#box的高度会覆盖这里的类高度,加上!important使得优先级最高 */

padding-top: 0 !important;

/* 如果是靠内容和padding撑开高度,就设置padding-top和padding-bottom */

padding-bottom: 0 !important;

}

.slideLeftRightCollapse {

/* 当移除了这个类,高度就会显示为原本宽度 */

width: 0 !important;

/* id的优先级比class高,所以#box的宽度会覆盖这里的类宽度,加上!important使得优先级最高 */

padding-left: 0 !important;

/* 如果是靠内容和padding撑开宽度,就设置padding-left和padding-right */

padding-right: 0 !important;

}

</style>

</head>


<body>

<button id="btn-show" class="btn">显示</button><button id="btn-hide" class="btn">隐藏</button>

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

<button class="btn">显示2</button>


<script>

console.log(window.muduoduo.transition.end);

console.log(window.muduoduo.transition.isSupport);



// var silent = {

//     show: function($elem) {

//         // 方法一:  $elem.html('<P>我要显示了</P>');    将函数要执行的语句放在实例化函数中执行

//         // $elem.html('<P>我要显示了</P>');    将函数要执行的语句放在实例化函数中执行

//         // setTimeout(function() {     将函数要执行的语句放在实例化函数中执行

//         //     $elem.html($elem.html() + '<P>我已经显示了</P>');

//         // }, 1000)


//         // 方法二:

//         // show:function($elem,showCallback,shownCallback){

//         //     if (typeof showCallback === 'function') { //适合发布订阅的方式,发布消息就是触发事件,订阅消息就是绑定事件

//         //         showCallback();

//         //     }

//         //     $elem.show();   show方法是需要jq对象元素来调用的,不能是函数调用

//         //     if (typeof shownCallback === 'function') {

//         //         shownCallback();

//         //     }



//         // 方法三:

//         $elem.trigger('show');

//         $elem.show();

//         $elem.trigger('shown');

//     },

//     hide: function($elem) {

//         $elem.trigger('hide');

//         $elem.hide();

//         $elem.trigger('hidden');

//     }

// };

// var css3 = {

//     fade: {

//         show: function() {},

//         hide: function() {}

//     },

//     slideUpDown: {

//         show: function() {},

//         hide: function() {}

//     },

//     slideLeftRight: {

//         show: function() {},

//         hide: function() {}

//     },

//     fadeSlideUpDown: {

//         show: function() {},

//         hide: function() {}

//     },

//     fadeSlideLeftRight: {

//         show: function() {},

//         hide: function() {}

//     }

// };

// var js = {

//     fade: {

//         show: function() {},

//         hide: function() {}

//     },

//     slideUpDown: {

//         show: function() {},

//         hide: function() {}

//     },

//     slideLeftRight: {

//         show: function() {},

//         hide: function() {}

//     },

//     fadeSlideUpDown: {

//         show: function() {},

//         hide: function() {}

//     },

//     fadeSlideLeftRight: {

//         show: function() {},

//         hide: function() {}

//     }

// };



var $box = $('#box');

// 方法二的调用

// $('#btn-show').on('click', function() {

//     silent.show($box, function() {

//         $box.html('<P>我要显示了</P>');

//     }, function() {

//         setTimeout(function() {

//             $box.html($box.html() + '<P>我已经显示了</P>');

//         }, 1000)

//     });

// });


// silent.init($box); //初始化,只执行一次

// css3.fade.init($box);

// css3.slideLeftRight.init($box);

// js.slideLeftRight.init($box);

// js.fadeSlideUpDown.init($box);

// js.fadeSlideLeftRight.init($box);

// var showHide = window.muduoduo.showHide($box, {

//     css3: true,

//     animation: 'fade'

// });


$box.showHide({

css3: false,

js: false,

animation: 'fade'

})


// 发布:触发事件

$('#btn-show').on('click', function() {

// silent.show($box);

// css3.fade.show($box);

// css3.slideLeftRight.show($box);

// js.slideLeftRight.show($box);

// js.fadeSlideUpDown.show($box);

// js.fadeSlideLeftRight.show($box);

// showHide.show($box); //调用showHide中的show方法

// showHide.show();

$box.showHide('show');

});


$('#btn-hide').on('click', function() {

// silent.hide($box);

// css3.fade.hide($box);

// css3.slideLeftRight.hide($box);

// js.slideLeftRight.hide($box);

// js.fadeSlideUpDown.hide($box);

// js.fadeSlideLeftRight.hide($box);

// showHide.hide($box);

// showHide.hide();

$box.showHide('hide');

});


// 订阅:接收事件

$box.on('show shown hide hidden', function(e) {

// console.log(e); 打印结果是show shown hide hidden

if (e.type === 'show') {

$box.html('<P>我要显示了</P>');

} else if (e.type === 'shown') {

setTimeout(function() {

$box.html($box.html() + '<P>我已经显示了</P>');

}, 1000)

}

});


// 订阅:接收事件

$box.on('show shown hide hidden', function(e) {

if (e.type === 'show') {

$box.css('backgroundColor', 'yellow');

} else if (e.type === 'shown') {

setTimeout(function() {

$box.css('backgroundColor', '');

}, 1000)

}

});

// 以上两个接收事件改变内容互补影响,不用在各自接收事件上修改程序,方便多人协作,发布消息(触发事件),新增者只需订阅发布者的消息(绑定消息)就可以修改

</script>



</body>


</html>



(function($) { //将showhide封装成模块:放在自执行的匿名函数中

'use strict';


var transition = window.muduoduo.transition;


function init($elem, hiddenCallback) {

if ($elem.is(':hidden')) {

$elem.data('status', 'hidden');

if (typeof hiddenCallback === 'function') {

hiddenCallback();

}

$elem.addClass('fadeOut');

} else {

$elem.data('status', 'shown');

}

};


function show($elem, Callback) {

if ($elem.data('status') === 'show') return; //当已是显示状态,不再重复执行show的代码

if ($elem.data('status') === 'shown') return; //当已是显示状态,不再重复执行shown的代码

$elem.data('status', 'show').trigger('show'); // 第一次没执行状态,status是undefined,当执行完第一次之后,status是show 不再重复执行代码

Callback();

};


function hide($elem, Callback) {

if ($elem.data('status') === 'hide') return; //当已是隐藏状态,不再重复执行hide的代码

if ($elem.data('status') === 'hidden') return; //当已是隐藏状态,不再重复执行hidden的代码

$elem.data('status', 'hide').trigger('hide');

Callback();

};


var silent = {

init: 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');

})

}

};

var css3 = {

fade: {

init: function($elem) {

css3._init($elem, 'fadeOut');

},

show: function($elem) {

css3._show($elem, 'fadeOut');

},

hide: function($elem) {

css3._hide($elem, 'fadeOut');

}

},

slideUpDown: {

init: function($elem) {

$elem.height($elem.height()); /* 获取高度,并把获取到的高度设置给到jq元素的高度 */

/* 当$elem没有设置高度,由内容撑开时,slideUpDownCollapse将高度变为0有过渡效果 */

css3._init($elem, 'slideUpDownCollapse');

},

show: function($elem) {

css3._show($elem, 'slideUpDownCollapse');

},

hide: function($elem) {

css3._hide($elem, 'slideUpDownCollapse');

}

},

slideLeftRight: {

init: function($elem) {

$elem.width($elem.width()); /* 获取宽度,并把获取到的宽度设置给到jq元素的高度 */

/* 当$elem没有设置宽度,由内容撑开时,slideLeftRightCollapse将高度变为0有过渡效果 */

css3._init($elem, 'slideLeftRightCollapse');

},

show: function($elem) {

css3._show($elem, 'slideLeftRightCollapse');

},

hide: function($elem) {

css3._hide($elem, 'slideLeftRightCollapse');

}

},

fadeSlideUpDown: {

show: function() {},

hide: function() {}

},

fadeSlideLeftRight: {

show: function() {},

hide: function() {}

}

};


css3._init = function($elem, className) {

$elem.addClass('transition');

init($elem, function() { //传入参数为jq对象,回调函数

$elem.addClass(className); //当初始状态是隐藏时,添加class

});

};


css3._show = function($elem, className) {

show($elem, function() {

// 如果当前动画没有执行完毕,就执行另一个动画,那么之前的动画是不会停止的,会继续执行,直到结束,所以有的时候显示之后突然显示,就是之前消失的动画没有执行完毕。 为了解决这个问题,要将jq元素解绑过渡动画,再绑定一次过渡

$elem.off(transition.end).one(transition.end, function() { //transition.end是transition.js中的属性值

$elem.trigger('shown'); //执行自定义的shown方法

});

$elem.show(); //$elem.show();和$elem.css执行顺序一前一后,但是执行非常快,可以认为同步执行,不存在过渡效果,讲它们异步执行setTimeout

// transition过渡时遇到没有效果,可以考虑是否异步问题

setTimeout(function() {

$elem.removeClass(className);

}, 20);

});

};


css3._hide = function($elem, className) {

hide($elem, function() {

$elem.off(transition.end).one(transition.end, function() { //transition结束有transitionend事件

// 绑定事件在触发事件之前

// one()只绑定一次时间 之前解绑时间,即当快速按下显示和隐藏按钮时,show shown hide hidden不会按顺序执行,可能会没有shown

$elem.hide();

$elem.data('status', 'hidden').trigger('hidden');

});

$elem.addClass(className);

});

};


var js = {

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._init($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-down': 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-top': 0,

'padding-bottom': 0

});

}

}

};



js._init = function($elem, hiddenCallback) { //hiddenCallback做为参数,需要用时再传入,不需要用就不传入

$elem.removeClass('transition'); //transition的类和js争做动画效果,避免这种情况,需要移除transition的类

init($elem, hiddenCallback); //调用之前定义的init函数

};


js._customInit = function($elem, options) { //用于fadeSlideUpDown的自定义

var styles = {};

for (var p in options) {

styles[p] = $elem.css(p);

}

$elem.data('styles', styles); //设置数据styles的data值为styles,将局部的变量可以在其他函数中使用


js._init($elem, function() {

$elem.css(options);

})

};


js._show = function($elem, mode) { //mode用来接收淡入淡出等的模式  模式是字符串,而且是参数,不能用.要用[]

show($elem, function() {

$elem.stop()[mode](function() { //stop()暂停之前执行的动画,再开始新动画  

$elem.data('status', 'shown').trigger('shown');

})

})

};


js._customShow = function($elem) {

show($elem, function() {

$elem.show(); //执行最上边定义的show函数

$elem.stop().animate($elem.data('styles'), function() { //动画结束后

$elem.data('status', 'shown').trigger('shown');

});

});

};


js._hide = function($elem, mode) {

hide($elem, function() {

$elem.stop()[mode](function() { //如果点击了显示按钮立刻点击隐藏按钮,stop()会立刻停止显示按钮去执行隐藏按钮

$elem.data('status', 'hidden').trigger('hidden');

});

});

};


js._customHide = function($elem, options) {

hide($elem, function() {

$elem.stop().animate(options, function() { //动画结束后

$elem.hide(); //执行最上边定义的hide函数

$elem.data('status', 'hidden').trigger('hidden');

});

});

};


// 设置默认参数,值为true时,执行相应的方法

var defaults = {

css3: false,

js: false,

animation: 'fade'

};


function showHide($elem, options) {

var mode = null;


if (options.css3 && transition.isSupport) { //options.css3为真,而且浏览器支持  css3的transition过渡

mode = css3[options.animation] || css3[defaults.animation]; //如果传错参数,没有覆盖到defaults相同的属性,就用defaults的属性

} else if (options.js) { //js的animation动画

mode = js[options.animation] || js[defaults.animation];

} else { //没有动画 no animation

mode = silent;

}


mode.init($elem);

return { //返回show和hide

// show: mode.show,

show: $.proxy(mode.show, this, $elem), //mode.show是函数 第二个参数是this的指向 this 第三个参数是传入参数$elem

hide: $.proxy(mode.hide, this, $elem)

};

}


//假设外部传了options为 {css3:true} 那么就会覆盖defaults中相同的css3属性的值,将false变为true



// // 局部对象调用到全局,运用之前的全局对象window.muduoduo

// window.muduoduo = window.muduoduo || {};

// window.muduoduo.showHide = showHide;


// 使用插件形式

$.fn.extend({

showHide: function(option) { //判断option是否是对象

return this.each(function() { //为了能连缀. .,返回this

var $this = $(this),

options = $.extend({}, defaults, typeof option === 'object' && option), //将外部传入的参数options覆盖defaults相同属性放到空对象中,将赋值后的对象给options


//&&是短路操作符,如果typeof option==='object'为真,则将option的值传入showHide,如果typeof option==='object'为假,不会执行&&后面的option,将false传入showHide

//如果把false传给showHide, option的值没有覆盖到defaults 就是不使用外部参数,使用defaults的值


mode = $this.data('showHide');

if (!mode) { //没有mode 是第一次执行

$this.data('showHide', mode = showHide($this, options));

}


if (typeof mode[option] === 'function') {

mode[option]();

}


})

}

})

})(jQuery);



(function() {

var transitionEndEventName = {

transition: 'transitionend',

MozTransition: 'transitionend',

WebkitTransition: 'WebkitTransitionEnd',

OTransition: 'oTransitionEnd otransitionend'

};


var transitionEnd = '', //在自执行的匿名函数中定义的是局部作用域

isSupport = false; //在自执行的匿名函数中定义的是局部作用域


//一般都存在body元素,如果不用body判断是否有transitionend,可以用document.create('DOM元素'),再用document.创建的DOM元素.style[name]

for (var name in transitionEndEventName) {

var ele = document.body || document.documentElement;

if (ele.style[name] !== undefined) { //存在transitionend

transitionEnd = transitionEndEventName[name];

isSupport = true;

break; //如果找到就无需继续遍历,立刻跳出

}

}


//全局作用域中暴露获得的结果

window.muduoduo = window.muduoduo || {}; //如果window存在muduoduo就用muduoduo 本身,原来不存在第一次用就是一个空对象

window.muduoduo.transition = {

end: transitionEnd,

isSupport: isSupport

};

})();

为什么将css3:false,和js:false,就出现问题?

写回答

1回答

好帮手慕星星

2019-04-03

你好,如果css3和js都设置false的话,那么执行的就是slient中的事件:

http://img.mukewang.com/climg/5ca49271000111ef13230622.jpg

开始就先init初始化:

http://img.mukewang.com/climg/5ca4928a0001a67f08450597.jpg

初始化之后就会添加上fadeOut类,这个类中设置了透明度:

http://img.mukewang.com/climg/5ca492c60001678015530254.jpg

点击显示按钮之后其实是显示出来的,只不过有透明度而已:

http://img.mukewang.com/climg/5ca492e60001b1f115850632.jpg

还是之前的情况,把添加的这个类删掉即可。

自己测试下,祝学习愉快!

0

0 学习 · 14456 问题

查看课程