封装dropdown模块(使用到之前写好的动画组件,封装下拉菜单)

时间:2023-01-25 21:13:19

用 showhide 改写dropdown 模块:

1.首先在 css中新增动画相关样式

        /*showhide组件的样式*/
.fadeOut{
opacity:;
visibility: hidden;
}
/*收缩样式*/
.slideUpDownCollapse{
height:0 !important;/*避免因为优先级不够而无法生效*/
padding-top:0 !important;
padding-bottom:0 !important;
}
.slideLeftRightCollapse{
width:0 !important;/*避免因为优先级不够而无法生效*/
padding-left:0 !important;
padding-right:0 !important;
}

js 中引入 showhide 脚本

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

修改dropdown.js 脚本

(function($){
'use strict';//使用严格模式 function dropdown(elem,options){
var elem=$(elem);
var list=elem.find(".dropdown-list");//下拉列表是需要动画的部分
var activeClass=elem.data("active")+"-active"; //指定动画模式
list.showHide(options); elem.hover(function(){
elem.addClass(activeClass);
list.showHide("show");//show
},function(){
elem.removeClass(activeClass);
list.showHide("hide");//hide
})
} //默认参数
var defaults={
css3:false,
js:false,
animation:"fade"
}; //插件形式
$.fn.extend({
dropdown:function(options){
return this.each(function(){//遍历数组
var options=$.extend({},defaults,options);
dropdown(this,options);
});
}
}); })(jQuery);
//为了防止$符发生冲突,将jQuery作为参数传入,则$符作为内部变量,不会发生冲突

调用时

    <script>
//没传参数时使用默认参数
$(".dropdown").dropdown(); //指定参数
$(".dropdown").dropdown({
css3:true,
js:true,
animation:"slideUpDown"
});
</script>

接下来,用构造函数的形式来改写dropdown模块

(function($){
'use strict';//使用严格模式 //构造函数形式
function Dropdown(elem,options){
this.elem=$(elem);
this.list=this.elem.find(".dropdown-list");//下拉列表是需要动画的部分
this.activeClass=options.active+"-active"; //指定动画模式
this.list.showHide(options); //外面的this指向Dropdown实例,但是hover事件里的this会指向调用该函数的元素,也就是elem
//因此需要改变this的指向
//this.elem.hover(this.show,this.hide); //改变this指向的第一种方法
// var self=this;
// this.elem.hover(function(){
// self.show();
// },function(){
// self.hide();
// });
//注意此处不可以直接写:this.elem.hover(self.show,self.hide);
// 因为匿名函数会形成局部作用域,查找不到self会沿着作用域链去上一级寻找,找到dropdown //改变this指向的第二种方法
//当执行hover方法的时候,$.proxy()方法就会执行,$调用的,也就是jquery调用的
//$.proxy() 接受一个已有的函数,并返回一个带特定上下文的新的函数
//这里上下文指的是show函数所在对象名称,也就是Dropdown,所以改变了this的指向
this.elem.hover($.proxy(this.show,this),$.proxy(this.hide,this));
}
//使用这种方式跟原型有个相同的好处:就是只会生成一次
//不会每次实例化就再次生成
//原型主要用于方法
Dropdown.defaults={
css3:false,
js:false,
animation:"fade",
active:"dropdown"
};
//将show和hide方法写在原型上,就不会每次实例化时重复执行
Dropdown.prototype.show=function(){
this.elem.addClass(this.activeClass);
this.list.showHide("show");//show
}
Dropdown.prototype.hide=function(){
this.elem.removeClass(this.activeClass);
this.list.showHide("hide");//show
} //插件形式
$.fn.extend({
dropdown:function(opt){
return this.each(function(){//遍历数组
//console.log($(this).data());//{active: "menu"}
//将html中写入的data-active属性也加入对象合并
var options=$.extend({},Dropdown.defaults,$(this).data(),options);
new Dropdown(this,options);
});
}
}); })(jQuery);
//为了防止$符发生冲突,将jQuery作为参数传入,则$符作为内部变量,不会发生冲突

注意点:

this.elem.hover(this.show,this.hide); 这种写法是错误的

外面的this指向Dropdown实例,但是hover事件里的this会指向调用该函数的元素,也就是elem
因此需要改变this的指向

改变this指向的第一种方法

        var self=this;
this.elem.hover(function(){
self.show();
},function(){
self.hide();
});

注意不能写成:this.elem.hover(self.show,self.hide);

必须要有匿名函数包裹

因为匿名函数会形成局部作用域,查找不到self会沿着作用域链去上一级寻找,找到dropdown

改变this指向的第二种方法

this.elem.hover($.proxy(this.show,this),$.proxy(this.hide,this));

当执行hover方法的时候,$.proxy()方法就会执行,$调用的,也就是jquery调用的
$.proxy() 接受一个已有的函数,并返回一个带特定上下文的新的函数
这里上下文指的是show函数所在对象名称,也就是Dropdown,所以改变了this的指向


触发方式和延迟显示

要让用户可以选择触发方式:比如hover,比如click

因此要在default 属性中新增 event

dropdown.js

(function($){
'use strict';//使用严格模式 //构造函数形式
function Dropdown(elem,options){
this.elem=$(elem);
this.list=this.elem.find(".dropdown-list");//下拉列表是需要动画的部分
this.activeClass=options.active+"-active"; //指定动画模式
this.list.showHide(options); var self=this;
if(options.event==="click"){ this.elem.click(function(e){
self.show();
e.stopPropagation();//阻止冒泡,否则点击下拉时也会冒泡到document,导致显示后立刻隐藏的效果
});
//点击空白处消失
$(document).click($.proxy(this.hide,this)); }else{//容错机制,写错默认也是hover
this.elem.hover($.proxy(this.show,this),$.proxy(this.hide,this));
}
}
Dropdown.defaults={
event:"hover",//还有click
css3:false,
js:false,
animation:"fade",
active:"dropdown"
};
Dropdown.prototype.show=function(){
this.elem.addClass(this.activeClass);
this.list.showHide("show");//show
}
Dropdown.prototype.hide=function(){
this.elem.removeClass(this.activeClass);
this.list.showHide("hide");//show
} //插件形式
$.fn.extend({
dropdown:function(opt){
return this.each(function(){
var options=$.extend({},Dropdown.defaults,$(this).data(),opt);
new Dropdown(this,options);
});
}
}); })(jQuery);
//为了防止$符发生冲突,将jQuery作为参数传入,则$符作为内部变量,不会发生冲突

dropdown.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>dropdown</title>
<link rel="stylesheet" href="../css/base.css">
<style>
/*分离出dropdown公共样式*/
.dropdown{
position: relative;
}
.dropdown-toggle{
position: relative;
z-index:2;
}
.dropdown-arrow{
display: inline-block;
vertical-align: middle;
background-repeat: no-repeat;
}
.dropdown-list{
display: none;
position: absolute;
z-index:1;
}
.dropdown-left{
left:0;
right:auto;
}
.dropdown-right{
right:0;
left:auto;
}
/*分离出nav的dropdown独有样式*/
.menu .dropdown-toggle{
display: block;
padding:0 16px 0 12px;
border-right:1px solid #f3f5f7;
border-left:1px solid #f3f5f7;
}
.menu .dropdown-arrow{
margin-left:8px;
vertical-align: middle;
}
.menu .dropdown-list{
border:1px solid #cdd0d4;
background-color: #fff;
top:100%;
overflow:hidden;/*避免容器还没显示时,文字提前显示*/
}
.menu-item{
height:30px;
line-height:30px;
padding:0 12px;
white-space: nowrap;
}
/*鼠标移入*/
.menu-item:hover{
background-color: #f3f5f7;
}
.menu-active .dropdown-toggle{
color:#f01414;
background-color:#fff;
border-color:#cdd0d4;
} @font-face {
font-family: "iconfont";
src: url('../font/iconfont.eot?t=1582272973653'); /* IE9 */
src: url('../font/iconfont.eot?t=1582272973653#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAMgAAsAAAAABxAAAALRAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDBgqBbIFbATYCJAMMCwgABCAFhG0HQRssBsgekiSCCCFEuNlXEQBAPHzt93ru7n5ElURBCR2BR5Bliy51gKpGVNYCG9XxbMSbd+4zPSCMOgTu9Sct57/89MAB8gDg+U2hMJtwk9PLaOlpn+dyehPoQO6qb1lua9nY4/lRL8A4oEDHGrQICiQgT0F2R6CWvJtA25Ik3NGapi7gonAGBeKOLPLApRRRFCnfFOotM4t4zVEzPUnf8Cr+fvy3M1xIapkz8vi1agso+zX5VZFnqjVDIUG9nAvSPDI2AwpxtTVznr2QOHttk0N/eV0R0lLxqiJWmZb6Qf94iahzartgPc0mfvn7coJfFXdIIIM6Co4BTlN2+u4sWkuugcK7XzPWn03hfqHrBFzKHnD9N/PZ4F7P9ffhg8fc2Vs3r7PmkLOEZ8HuotvxoydrARZ8tPZoJtANHTbfLfNt8m1kb0r92n/hum2PejfY0bcssN9up2U/iqlrDF15exnd72H3eLIT35f1BRwJ/n/uTXKjpdzjBd/wyYYk987lMN+Ix9xY6SQYA1D9yB9yEQDktVT2m3/jYS3h8+ig6F+zU8BP8933OFL9KHBL8yaMMVH5U9VgQzG1jjUXXeWrbF+2/QZdCVrXRsUJjP2ZbpnBtYSmWY6kYRFZ0zJZ2M2o6diNuqYDaNukdn7HBGUvSgsbLRKEoZdI+j4jG/pOFvY3aub+om4Y9mg7G/4rdqyG7FZJEc+QBY5PQ1kgBvbszC2p70CiqfG0qI35HkRtchymp6RV87XIQHSJMbYJMYMxDDElOqwh+yFNI9BKiYIEliIxZi1ITcVtD0oRiA7cHEEhPAaxgMZNg2QCwoDD1oxb7fMdEJFJw6M9ooZiD4SykTuH0qVIA8hakwGJHuUemwmiDAyDQRhF6KAa0g3RaAjI2t5NgQiYFNKElFWBVLcZRk0p21v0/9sGbc7KOVLkKJrXiTlpChLymJJ5jVeCMoMREwAAAAA=') format('woff2'),
url('../font/iconfont.woff?t=1582272973653') format('woff'),
url('../font/iconfont.ttf?t=1582272973653') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('../font/iconfont.svg?t=1582272973653#iconfont') format('svg'); /* iOS 4.1- */
} .iconfont {
font-family: "iconfont" !important;
font-size: 14px;
font-style: normal;/*i标签自带斜体效果*/
-webkit-font-smoothing: antialiased;/*在webkit内核和火狐浏览器中,抗锯齿*/
-moz-osx-font-smoothing: grayscale;
} [class*="-active"] .dropdown-arrow{
-webkit-transform:rotate(180deg);
-moz-transform:rotate(180deg);
-ms-transform:rotate(180deg);
-o-transform:rotate(180deg);
transform:rotate(180deg);
}
/*提取出过渡样式,可公用*/
.transition{
-webkit-transition:all .5s;
-moz-transition:all .5s;
-ms-transition:all .5s;
-o-transition:all .5s;
transition:all .5s;
}
/*showhide组件的样式*/
.fadeOut{
opacity: 0;
visibility: hidden;
}
/*收缩样式*/
.slideUpDownCollapse{
height:0 !important;/*避免因为优先级不够而无法生效*/
padding-top:0 !important;
padding-bottom:0 !important;
}
.slideLeftRightCollapse{
width:0 !important;/*避免因为优先级不够而无法生效*/
padding-left:0 !important;
padding-right:0 !important;
}
</style>
</head>
<body>
<div class="menu dropdown fl" data-active="menu">
<a href="javascript:;" class="dropdown-toggle">我的慕淘<i class="dropdown-arrow iconfont transition"></i></a>
<ul class="dropdown-list dropdown-left">
<li class="menu-item"><a href="#">已买到的宝贝</a></li>
<li class="menu-item"><a href="#">我的足迹</a></li>
</ul>
</div>
<div class="menu dropdown fl" data-active="menu">
<a href="javascript:;" class="dropdown-toggle">我的慕淘<i class="dropdown-arrow iconfont transition"></i></a>
<ul class="dropdown-list dropdown-left">
<li class="menu-item"><a href="#">已买到的宝贝</a></li>
<li class="menu-item"><a href="#">我的足迹</a></li>
</ul>
</div>
<div class="menu dropdown fl" data-active="menu">
<a href="javascript:;" class="dropdown-toggle">我的慕淘<i class="dropdown-arrow iconfont transition"></i></a>
<ul class="dropdown-list dropdown-left">
<li class="menu-item"><a href="#">已买到的宝贝</a></li>
<li class="menu-item"><a href="#">我的足迹</a></li>
</ul>
</div>
<script src="../js/jquery.js"></script>
<script src="../js/transition.js"></script>
<script src="../js/showhide.js"></script>
<script src="../js/dropdown.js"></script>
<script>
//指定参数
$(".dropdown").dropdown({
event:"click",
css3:true,
js:true,
animation:"slideUpDown",
active:"menu"
});
</script>
</body>
</html>

此时有个问题:就是当 event 设置为hover,然后存在多个下拉列表

鼠标从1开始快速移动到3,则1,2,3都会被触发事件

假设只是想触发1,3事件,快速经过中触发了2事件,是一种对性能的浪费

这里引入延迟显示的机制

dropdown.js

(function($){
'use strict';//使用严格模式 //构造函数形式
function Dropdown(elem,options){
//保存到this中才能公用
this.elem=$(elem);
this.options=options;
this.timer=null;
this.list=this.elem.find(".dropdown-list");//下拉列表是需要动画的部分
this.activeClass=options.active+"-active"; //指定动画模式
this.list.showHide(options); var self=this;
if(options.event==="click"){ this.elem.click(function(e){
self.show();
e.stopPropagation();//阻止冒泡,否则点击下拉时也会冒泡到document,导致显示后立刻隐藏的效果
});
//点击空白处消失
$(document).click($.proxy(this.hide,this)); }else{//容错机制,写错默认也是hover
this.elem.hover($.proxy(this.show,this),$.proxy(this.hide,this));
}
}
Dropdown.defaults={
event:"hover",//还有click
css3:false,
js:false,
animation:"fade",
delay:0,//默认无延迟
active:"dropdown"
};
Dropdown.prototype.show=function(){
var self=this;
if(this.options.delay){
//如果有延迟
this.timer=setTimeout(function(){
_show();
},this.options.delay);
}else{
//没有延迟
_show();
}
function _show(){
self.elem.addClass(self.activeClass);
self.list.showHide("show");//show
} }
Dropdown.prototype.hide=function(){
if(this.options.delay){
clearTimeout(this.timer);
}
this.elem.removeClass(this.activeClass);
this.list.showHide("hide");//show
} //插件形式
$.fn.extend({
dropdown:function(opt){
return this.each(function(){
var options=$.extend({},Dropdown.defaults,$(this).data(),opt);
new Dropdown(this,options);
});
}
}); })(jQuery);
//为了防止$符发生冲突,将jQuery作为参数传入,则$符作为内部变量,不会发生冲突

页面调用

    <script>
//指定参数
$(".dropdown").dropdown({
event:"hover",
css3:true,
js:true,
animation:"slideUpDown",
delay:500,
active:"menu"
});
</script>

用构造函数的形式重写dropdown模块-发送消息、暴露方法以及单例

dropdown.js

(function($){
'use strict';//使用严格模式 //构造函数形式
function Dropdown(elem,options){
//保存到this中才能公用
this.elem=elem;
this.options=options;
this.timer=null;
this.list=this.elem.find(".dropdown-list");//下拉列表是需要动画的部分
this.activeClass=options.active+"-active"; this._init();//初始化
}
Dropdown.defaults={
event:"hover",//还有click
css3:false,
js:false,
animation:"fade",
delay:0,//默认无延迟
active:"dropdown"
};
//约定俗称:内部使用的可以以_开头
Dropdown.prototype._init=function(){
var self=this; //指定动画模式
this.list.showHide(this.options); //绑定事件
this.list.on("show shown hide hidden",function(e){
//console.log(e.type);
//消息转发
self.elem.trigger("dropdown-"+e.type);//触发事件
});
if(this.options.event==="click"){ this.elem.click(function(e){
self.show();
e.stopPropagation();//阻止冒泡,否则点击下拉时也会冒泡到document,导致显示后立刻隐藏的效果
});
//点击空白处消失
$(document).click($.proxy(this.hide,this)); }else{//容错机制,写错默认也是hover
this.elem.hover($.proxy(this.show,this),$.proxy(this.hide,this));
}
};
Dropdown.prototype.show=function(){
var self=this;
if(this.options.delay){
//如果有延迟
this.timer=setTimeout(function(){
_show();
},this.options.delay);
}else{
//没有延迟
_show();
}
function _show(){
self.elem.addClass(self.activeClass);
self.list.showHide("show");//show
} }
Dropdown.prototype.hide=function(){
if(this.options.delay){
clearTimeout(this.timer);
}
this.elem.removeClass(this.activeClass);
this.list.showHide("hide");//show
} //插件形式
$.fn.extend({
dropdown:function(opt){
return this.each(function(){
var ui=$(this);
var dropdown=ui.data("dropdown");
//opt是参数对象
var options=$.extend({},Dropdown.defaults,ui.data(),typeof opt==="object"&&opt); //单例:一个DOM元素对应一个实例,如果已经存在则不需要反复实例化
if(!dropdown){
dropdown=new Dropdown(ui,options);
ui.data("dropdown",dropdown);
} //opt是show或者hide
if(typeof dropdown[opt]==="function"){
dropdown[opt]();
}
});
}
}); })(jQuery);
//为了防止$符发生冲突,将jQuery作为参数传入,则$符作为内部变量,不会发生冲突

下拉菜单的按需显示

当下拉列表里内容很多时,如果首次加载全部,会影响用户体验,因此需要按需加载

将需要的数据放到json文件中,需要时再去加载

json中一定要加双引号

dropdown.json

[
{
"url":"#",
"name":"已买到的宝贝"
},
{
"url":"#",
"name":"我的足迹"
},
{
"url":"#",
"name":"我的优惠券"
}
]

dropdown.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>dropdown</title>
<link rel="stylesheet" href="../css/base.css">
<style>
/*分离出dropdown公共样式*/
.dropdown{
position: relative;
}
.dropdown-toggle{
position: relative;
z-index:2;
}
.dropdown-arrow{
display: inline-block;
vertical-align: middle;
background-repeat: no-repeat;
}
.dropdown-list{
display: none;
position: absolute;
z-index:1;
}
.dropdown-left{
left:0;
right:auto;
}
.dropdown-right{
right:0;
left:auto;
}
/*分离出nav的dropdown独有样式*/
.menu .dropdown-toggle{
display: block;
padding:0 16px 0 12px;
border-right:1px solid #f3f5f7;
border-left:1px solid #f3f5f7;
}
.menu .dropdown-arrow{
margin-left:8px;
vertical-align: middle;
}
.menu .dropdown-list{
border:1px solid #cdd0d4;
background-color: #fff;
top:100%;
overflow:hidden;/*避免容器还没显示时,文字提前显示*/
}
.menu-item{
height:30px;
line-height:30px;
padding:0 12px;
white-space: nowrap;
}
/*鼠标移入*/
.menu-item:hover{
background-color: #f3f5f7;
}
.menu-active .dropdown-toggle{
color:#f01414;
background-color:#fff;
border-color:#cdd0d4;
} @font-face {
font-family: "iconfont";
src: url('../font/iconfont.eot?t=1582272973653'); /* IE9 */
src: url('../font/iconfont.eot?t=1582272973653#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAMgAAsAAAAABxAAAALRAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDBgqBbIFbATYCJAMMCwgABCAFhG0HQRssBsgekiSCCCFEuNlXEQBAPHzt93ru7n5ElURBCR2BR5Bliy51gKpGVNYCG9XxbMSbd+4zPSCMOgTu9Sct57/89MAB8gDg+U2hMJtwk9PLaOlpn+dyehPoQO6qb1lua9nY4/lRL8A4oEDHGrQICiQgT0F2R6CWvJtA25Ik3NGapi7gonAGBeKOLPLApRRRFCnfFOotM4t4zVEzPUnf8Cr+fvy3M1xIapkz8vi1agso+zX5VZFnqjVDIUG9nAvSPDI2AwpxtTVznr2QOHttk0N/eV0R0lLxqiJWmZb6Qf94iahzartgPc0mfvn7coJfFXdIIIM6Co4BTlN2+u4sWkuugcK7XzPWn03hfqHrBFzKHnD9N/PZ4F7P9ffhg8fc2Vs3r7PmkLOEZ8HuotvxoydrARZ8tPZoJtANHTbfLfNt8m1kb0r92n/hum2PejfY0bcssN9up2U/iqlrDF15exnd72H3eLIT35f1BRwJ/n/uTXKjpdzjBd/wyYYk987lMN+Ix9xY6SQYA1D9yB9yEQDktVT2m3/jYS3h8+ig6F+zU8BP8933OFL9KHBL8yaMMVH5U9VgQzG1jjUXXeWrbF+2/QZdCVrXRsUJjP2ZbpnBtYSmWY6kYRFZ0zJZ2M2o6diNuqYDaNukdn7HBGUvSgsbLRKEoZdI+j4jG/pOFvY3aub+om4Y9mg7G/4rdqyG7FZJEc+QBY5PQ1kgBvbszC2p70CiqfG0qI35HkRtchymp6RV87XIQHSJMbYJMYMxDDElOqwh+yFNI9BKiYIEliIxZi1ITcVtD0oRiA7cHEEhPAaxgMZNg2QCwoDD1oxb7fMdEJFJw6M9ooZiD4SykTuH0qVIA8hakwGJHuUemwmiDAyDQRhF6KAa0g3RaAjI2t5NgQiYFNKElFWBVLcZRk0p21v0/9sGbc7KOVLkKJrXiTlpChLymJJ5jVeCMoMREwAAAAA=') format('woff2'),
url('../font/iconfont.woff?t=1582272973653') format('woff'),
url('../font/iconfont.ttf?t=1582272973653') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('../font/iconfont.svg?t=1582272973653#iconfont') format('svg'); /* iOS 4.1- */
} .iconfont {
font-family: "iconfont" !important;
font-size: 14px;
font-style: normal;/*i标签自带斜体效果*/
-webkit-font-smoothing: antialiased;/*在webkit内核和火狐浏览器中,抗锯齿*/
-moz-osx-font-smoothing: grayscale;
} [class*="-active"] .dropdown-arrow{
-webkit-transform:rotate(180deg);
-moz-transform:rotate(180deg);
-ms-transform:rotate(180deg);
-o-transform:rotate(180deg);
transform:rotate(180deg);
}
/*提取出过渡样式,可公用*/
.transition{
-webkit-transition:all .5s;
-moz-transition:all .5s;
-ms-transition:all .5s;
-o-transition:all .5s;
transition:all .5s;
}
/*showhide组件的样式*/
.fadeOut{
opacity: 0;
visibility: hidden;
}
/*收缩样式*/
.slideUpDownCollapse{
height:0 !important;/*避免因为优先级不够而无法生效*/
padding-top:0 !important;
padding-bottom:0 !important;
}
.slideLeftRightCollapse{
width:0 !important;/*避免因为优先级不够而无法生效*/
padding-left:0 !important;
padding-right:0 !important;
}
.dropdown-loading{
width:32px;
height:32px;
background:url(../img/loading.gif) no-repeat;
margin:20px;
}
</style>
</head>
<body>
<!-- 用data-load来确定数据源 -->
<div class="menu dropdown fl" data-active="menu" data-load="dropdown.json">
<a href="javascript:;" class="dropdown-toggle">我的慕淘<i class="dropdown-arrow iconfont transition"></i></a>
<ul class="dropdown-list dropdown-left">
<li class="dropdown-loading"></li>
</ul>
</div>
<div class="menu dropdown fl" data-active="menu">
<a href="javascript:;" class="dropdown-toggle">我的慕淘<i class="dropdown-arrow iconfont transition"></i></a>
<ul class="dropdown-list dropdown-left">
<li class="menu-item"><a href="#">已买到的宝贝</a></li>
<li class="menu-item"><a href="#">我的足迹</a></li>
</ul>
</div> <button class="show-btn">点我显示</button>
<button class="hide-btn">点我隐藏</button> <script src="../js/jquery.js"></script>
<script src="../js/transition.js"></script>
<script src="../js/showhide.js"></script>
<script src="../js/dropdown.js"></script>
<script>
//绑定事件 显示之前加载数据
$(".dropdown").on("dropdown-show",function(e){ var ui=$(this);
var dataLoad=ui.data("load"); if(!dataLoad) return; //只请求一次即可
if(!ui.data("loaded")){ var list=ui.find(".dropdown-list");
var html=""; //$.getJSON(文件,回调) jquery封装的获取json数据的方法
setTimeout(function(){
$.getJSON(dataLoad,function(data){
//console.log(data);
for(var i=0;i<data.length;i++){
console.log(data[i]);
html+='<li class="menu-item"><a href="'+data[i]["url"]+'">'+data[i]["name"]+'</a></li>';
}
//console.log(html);
list.html(html);
ui.data("loaded",true); });
},500);//模拟线上延迟
} }); //指定参数
$(".dropdown").dropdown({
event:"hover",
css3:true,
js:true,
animation:"slideUpDown"
}); //通过按钮也可以控制下拉菜单的显示隐藏
$(".show-btn").on("click",function(){
$(".dropdown").dropdown("show");
});
$(".hide-btn").on("click",function(){
$(".dropdown").dropdown("hide");
});
</script>
</body>
</html>

效果图

封装dropdown模块(使用到之前写好的动画组件,封装下拉菜单)

接下来就按照封装好的下拉菜单,来改写首页中的下拉菜单

index.html

<!DOCTYPE html>
<html lang="zh-CN"><!-- 设置简体中文 -->
<head>
<meta charset="UTF-8">
<title>index</title>
<link rel="stylesheet" href="css/base.css">
<link rel="stylesheet" href="css/index.css">
<link rel="stylesheet" href="css/common.css">
<!-- css一般放在DOM加载前,防止DOM裸奔 -->
</head>
<body>
<!-- 导航 -->
<div class="nav-site">
<div class="container">
<ul class="fl">
<li class="fl"><a href="javascript:;" class="nav-site-login">亲,请登录</a></li>
<li class="fl"><a href="javascript:;" class="nav-site-reg link">免费注册</a></li>
<li class="fl"><a href="#" class="nav-site-shop link">手机逛慕淘</a></li>
</ul>
<ul class="fr">
<li class="fl dropdown menu" data-active="menu">
<a href="javascript:;" class="dropdown-toggle link transition">我的慕淘<i class="dropdown-arrow iconfont transition"></i></a>
<ul class="dropdown-list dropdown-left">
<li class="menu-item"><a href="#">已买到的宝贝</a></li>
<li class="menu-item"><a href="#">我的足迹</a></li>
</ul>
</li>
<li class="fl dropdown menu" data-active="menu">
<a href="javascript:;" class="dropdown-toggle link transition">收藏夹<i class="dropdown-arrow iconfont transition"></i></a>
<ul class="dropdown-list dropdown-left">
<li class="menu-item"><a href="#">收藏的宝贝</a></li>
<li class="menu-item"><a href="#">收藏的店铺</a></li>
</ul>
</li>
<li class="fl dropdown">
<a href="javascript:;" class="nav-site-cat link">商品分类</i></a>
</li>
<li class="fl dropdown menu" data-active="menu" data-load="js/dropdown-seller.json">
<a href="javascript:;" class="dropdown-toggle link transition">卖家中心<i class="dropdown-arrow iconfont transition"></i></a>
<ul class="dropdown-list dropdown-left">
<li class="dropdown-loading"></li>
<!-- <li class="menu-item"><a href="#">免费开店</a></li>
<li class="menu-item"><a href="#">已卖出的宝贝</a></li>
<li class="menu-item"><a href="#">出售中的宝贝</a></li>
<li class="menu-item"><a href="#">卖家服务市场</a></li>
<li class="menu-item"><a href="#">卖家培训中心</a></li>
<li class="menu-item"><a href="#">体验中心</a></li> -->
</ul>
</li>
<li class="nav-site-service fl dropdown menu" data-active="menu">
<a href="javascript:;" class="dropdown-toggle link transition">联系客服<i class="dropdown-arrow iconfont transition"></i></a>
<ul class="dropdown-list dropdown-right">
<li class="menu-item"><a href="#">已买到的宝贝</a></li>
<li class="menu-item"><a href="#">我的足迹</a></li>
</ul>
</li>
</ul>
</div>
</div> <script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
<script>
//短路操作,如果cdn的jquery没有引用成功,则会执行后面一句,引入本地jquery
//括号中的<\/script>标签会被当做当前标签的结束标签,因此需要转义
window.jQuery || document.write('<script src="js/jquery.js"><\/script>');
</script>
<script src="js/transition.js"></script>
<script src="js/showhide.js"></script>
<script src="js/dropdown.js"></script>
<script src="js/index.js"></script>
</body>
</html>

index.js

// 不要暴露在全局,使用匿名函数自执行
(function($){ "use strict"; //绑定事件 显示之前加载数据
$(".dropdown").on("dropdown-show",function(e){ var ui=$(this);
var dataLoad=ui.data("load"); if(!dataLoad) return; if(!ui.data("loaded")){ var list=ui.find(".dropdown-list");
var html=""; setTimeout(function(){
$.getJSON(dataLoad,function(data){
for(var i=0;i<data.length;i++){
console.log(data[i]);
html+='<li class="menu-item"><a href="'+data[i]["url"]+'">'+data[i]["name"]+'</a></li>';
}
list.html(html);
ui.data("loaded",true); });
},500);
}
}); //插件形式调用
$(".dropdown").dropdown({
css3:true,
js:true
}); })(jQuery);

common.css

/*公共样式 */
.container{
width:1200px;
margin:0 auto;
}
.link{
color:#4d555d;
}
.link:hover{
color:#f01414;
}
.fl{
float:left;
}
.fr{
float:right;
}
/*提取出过渡样式,可公用*/
.transition{
-webkit-transition:all .5s;
-moz-transition:all .5s;
-ms-transition:all .5s;
-o-transition:all .5s;
transition:all .5s;
}
/*文字隐藏*/
.text-hidden{
text-indent:-9999px;
overflow:hidden;
} /*icon*/
@font-face {
font-family: "iconfont";
src: url('../font/iconfont.eot?t=1582272973653'); /* IE9 */
src: url('../font/iconfont.eot?t=1582272973653#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAMgAAsAAAAABxAAAALRAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDBgqBbIFbATYCJAMMCwgABCAFhG0HQRssBsgekiSCCCFEuNlXEQBAPHzt93ru7n5ElURBCR2BR5Bliy51gKpGVNYCG9XxbMSbd+4zPSCMOgTu9Sct57/89MAB8gDg+U2hMJtwk9PLaOlpn+dyehPoQO6qb1lua9nY4/lRL8A4oEDHGrQICiQgT0F2R6CWvJtA25Ik3NGapi7gonAGBeKOLPLApRRRFCnfFOotM4t4zVEzPUnf8Cr+fvy3M1xIapkz8vi1agso+zX5VZFnqjVDIUG9nAvSPDI2AwpxtTVznr2QOHttk0N/eV0R0lLxqiJWmZb6Qf94iahzartgPc0mfvn7coJfFXdIIIM6Co4BTlN2+u4sWkuugcK7XzPWn03hfqHrBFzKHnD9N/PZ4F7P9ffhg8fc2Vs3r7PmkLOEZ8HuotvxoydrARZ8tPZoJtANHTbfLfNt8m1kb0r92n/hum2PejfY0bcssN9up2U/iqlrDF15exnd72H3eLIT35f1BRwJ/n/uTXKjpdzjBd/wyYYk987lMN+Ix9xY6SQYA1D9yB9yEQDktVT2m3/jYS3h8+ig6F+zU8BP8933OFL9KHBL8yaMMVH5U9VgQzG1jjUXXeWrbF+2/QZdCVrXRsUJjP2ZbpnBtYSmWY6kYRFZ0zJZ2M2o6diNuqYDaNukdn7HBGUvSgsbLRKEoZdI+j4jG/pOFvY3aub+om4Y9mg7G/4rdqyG7FZJEc+QBY5PQ1kgBvbszC2p70CiqfG0qI35HkRtchymp6RV87XIQHSJMbYJMYMxDDElOqwh+yFNI9BKiYIEliIxZi1ITcVtD0oRiA7cHEEhPAaxgMZNg2QCwoDD1oxb7fMdEJFJw6M9ooZiD4SykTuH0qVIA8hakwGJHuUemwmiDAyDQRhF6KAa0g3RaAjI2t5NgQiYFNKElFWBVLcZRk0p21v0/9sGbc7KOVLkKJrXiTlpChLymJJ5jVeCMoMREwAAAAA=') format('woff2'),
url('../font/iconfont.woff?t=1582272973653') format('woff'),
url('../font/iconfont.ttf?t=1582272973653') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('../font/iconfont.svg?t=1582272973653#iconfont') format('svg'); /* iOS 4.1- */
} .iconfont {
font-family: "iconfont" !important;
font-size: 14px;
font-style: normal;/*i标签自带斜体效果*/
-webkit-font-smoothing: antialiased;/*在webkit内核和火狐浏览器中,抗锯齿*/
-moz-osx-font-smoothing: grayscale;
} /*dropdown下拉组件*/
.dropdown{
position: relative;
}
.dropdown-toggle{
position: relative;
z-index:;
}
.dropdown-arrow{
display: inline-block;
vertical-align: middle;
background-repeat: no-repeat;
line-height:;/*否则图标字体会继承父元素的line-height属性,占据过多空间*/
}
.dropdown-list{
display: none;
position: absolute;
z-index:;
}
.dropdown-left{
left:;
right:auto;
}
.dropdown-right{
right:;
left:auto;
}
[class*="-active"] .dropdown-arrow{
-webkit-transform:rotate(180deg);
-moz-transform:rotate(180deg);
-ms-transform:rotate(180deg);
-o-transform:rotate(180deg);
transform:rotate(180deg);
}
.dropdown-loading{
width:32px;
height:32px;
background:url(../img/loading.gif) no-repeat;
margin:20px;
} /*menu的dropdown独有样式*/
.menu .dropdown-toggle{
display: block;
/*padding:0 16px 0 12px;*/
padding:0 13px 0 12px;/*减去图标字体自带的3px边距*/
border-right:1px solid #f3f5f7;
border-left:1px solid #f3f5f7;
}
.menu .dropdown-arrow{
/*margin-left:8px;*/
margin-left:5px;/*减去图标字体自带的3px边距*/
vertical-align: middle;
}
.menu .dropdown-list{
border:1px solid #cdd0d4;
background-color: #fff;
top:100%;
}
.menu-item{
height:30px;
line-height:30px;
padding:0 12px;
white-space: nowrap;
}
/*鼠标移入*/
.menu-item:hover{
background-color: #f3f5f7;
}
.menu-active .dropdown-toggle{
color:#f01414;
background-color:#fff;
border-color:#cdd0d4;
} /*showhide*/
.fadeOut{
opacity:;
visibility: hidden;
}
.slideUpDownCollapse{
height:0 !important;/*避免因为优先级不够而无法生效*/
padding-top:0 !important;
padding-bottom:0 !important;
}
.slideLeftRightCollapse{
width:0 !important;/*避免因为优先级不够而无法生效*/
padding-left:0 !important;
padding-right:0 !important;
}

效果图

封装dropdown模块(使用到之前写好的动画组件,封装下拉菜单)

封装dropdown模块(使用到之前写好的动画组件,封装下拉菜单)

封装dropdown模块(使用到之前写好的动画组件,封装下拉菜单)的更多相关文章

  1. jQuery手写几个常见的滑动下拉菜单 分分秒秒学习JS

    一般的企业网站再我们再实际工作中,有些特效,用jQuery来做,显得极其简单,除非一些大的公司,需要封装自己的类. 今天,我们讲解jQuery入门知识,来写几个简单jQuery滑动下拉菜单.感受一下j ...

  2. 下拉菜单的jquery组件封装

    首先晒出封装好的dropdown.js (function($){ 'use strict';//使用严格模式 //构造函数形式 function Dropdown(elem,options){ // ...

  3. Unity3D UGUI下拉菜单&sol;Dropdown组件用法、总结

    Unity3D中UGUI实现下拉菜单 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- ...

  4. Mega Dropdown - 带子分类的响应式下拉菜单

    当你在开发一个内容很多的 Web 项目的时候,最具挑战性的部分之一是为了如果更方便用户浏览这些内容.我们都能想到的一个例子是 Amazon,无限的类别以及它们的子类别.Mega Dropdown 是带 ...

  5. 第一百三十二节,JavaScript,封装库--下拉菜单

    JavaScript,封装库--下拉菜单 封装库,增加了3个方法 shu_biao_yi_ru_yi_chu()方法,给元素设置鼠标移入移出事件,接收两个参数,参数是移入和移出时的执行函数(包含代码) ...

  6. Unity3D 重写下拉菜单&sol;Dropdown组件、开启每个按钮可用

    Override Dropdown Component 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) ...

  7. HTML&plus;CSS写下拉菜单

    今天学习了使用HTML+CSS实现下拉菜单效果,在这个例子中,我学到了如下知识点: 设置背景图片(background-image.background-size) 如何让无序列表横向显示(float ...

  8. 巧用CSS3 &colon;target 伪类制作Dropdown下拉菜单(无JS)

    :target 是CSS3 中新增的一个伪类,用以匹配当前页面的URI中某个标志符的目标元素(比如说当前页面URL下添加#comment就会定位到id=“comment”的位置,俗称锚).CSS3 为 ...

  9. 一个常见下拉菜单的样式:一体化小三角(纯css手写解决)

    类似下拉菜单2个一体化小三角,习惯上用字体图标加jQuery处理,比较方便,但是下面纯css手写解决方式,效果也还不错,对CSS知识也是一个比较好的孔固. 小三角用了2种不同处理方式:1.利用bord ...

随机推荐

  1. 创建DbContext

    返回总目录<一步一步使用ABP框架搭建正式项目系列教程> 上一篇介绍了<创建实体>,这一篇我们顺其自然地介绍<创建DbContext>. 温故: 提到DbConte ...

  2. sqlite采用的ORM包

    关注了两个库的使用方式,一个是Dapper,一个是Simple.Data.考虑一个可选的是ORMLite, Dapper和simple.data都比较好用,动态对象的使用妙不可言,区别在于 //Dap ...

  3. WWDC 2015 - 概记

    WWDC 2015已经过去快一个月了,今年似乎没有像去年那样变化巨大,一切都在慢慢演进,iOS.Mac OS.watchOS都变得越来越好. 新的三大平台的发布,iOS 9/Mac OS EL Cap ...

  4. phpcms 源码分析四: 数据库类实现

    这次是逆雪寒的数据库类分析: <?php /* 这个讲 phpcms 的数据库类 和 phpcms 的文本缓存的实现.看了看 都是很简单的东西.大家看着我注释慢慢看吧.慢慢理解,最好能装了PHP ...

  5. jquery deferred done then区别

    jquery deferred done then区别 deferred是jquery 对promise的实现. 以下内容基于jquery 1.8及以上版本 deferred具有then done等属 ...

  6. 用powershell实现:&OpenCurlyDoubleQuote;倩女幽魂姥姥”版《语音报警系统》

    ------[第一章 前言]------ win7,及以上版本中,是自带语音库的,系统自带一套女声中文库,一套女声英文库.用powershell调用,从而发音,制作报警系统.是一件太简单的事情,只需要 ...

  7. Java进阶&lpar;四十一&rpar;多线程讲解

    Java多线程讲解 前言 接到菜鸟网络的电话面试,面试官让自己谈一下自己对多线程的理解,现将其内容整理如下. 线程生命周期 Java线程具有五种基本状态 新建状态(New):当线程对象创建后,即进入了 ...

  8. OpenUDID 和 IDFA 比较

    iOS标识符 现今来比较下,不同情况下两种标识符的变化情况.以下试验,每种标识符均分为存于Keychain和未存于Keychain的两种情况做比较. 广告标识符(IDFA-identifierForI ...

  9. hbase-bloom filter

    bloom fliter的作用主要用于提升hbase的读性能,但是会牺牲一定的存储空间. 原理: bloom fliter是一种空间效率很高的随机数据结构,初始状态时,bloom filter是一个包 ...

  10. Walle,一个开源的web代码发布管理系统

    前言 Walle 一个web部署系统工具,可能也是个持续发布工具,配置简单.功能完善.界面流畅.开箱即用!支持git.svn版本管理,支持各种web代码发布,静态的HTML,动态PHP,需要编译的JA ...