javascript
和HTML
之间的交互是经过用户和浏览器操做页面时引起的事件来处理的。jQuery
不只提供了更加优雅的事件处理语法,并且极大地加强了事件处理能力。
前面章节咱们已经对比了window.onload()
和$(document).ready()
两种方法的区别。两种都是入口函数,只不过前者是js
中的然后者是jQ
中的。而且领着之间仍是有区别的:
一、执行时机:javascript
window.onload()
方法是等到页面中全部元素加载完毕以后,才执行,即javascript
此时才能够访问网页中的任何元素。而jQuery
使用$(document).ready()
方法,能够在DOM
载入就绪时就对其进行操纵并调用执行它所绑定的函数。也就是说在jQ
中,不须要等待全部图片加载完再执行。php
可是就会有个问题,当获取图片宽高的时候,可能获取不到。不过jQ
中单独提出了一个页面加载的方法——load()
方法,若是这个处理函数绑定给window
对象则会在全部内容加载完毕以后触发。css
$(window).load(function(){ // 执行代码 });
上面的代码,等同于js
中的:html
window.onload = function(){ // 执行代码 }
二、屡次使用:java
在javascript
中入口函数只能写一次,若是写多个,下面会将上面的覆盖掉:jquery
window.onload = function(){ alert(123); } window.onload = function(){ alert(456); // 页面只会弹出 456 }
在jQuery
中,入口函数能够写屡次,不会出现覆盖的状况:ajax
$(document).ready(function(){ alert(123); // 123 }); $(document).ready(function(){ alert(456); // 456 });
三、简写方式:javascript
中没有简写方式,可是在jQ
中有简写方式:json
// 1-原始版写法 $(document).ready(function(){ // 执行代码 }); // 2-简化写法,document能够省略 $().ready(function(){ // 执行代码 }); // 3-简化写法 $(function(){ // 执行代码 });
一、什么是事件绑定segmentfault
在文档装载完成以后,若是打算为元素绑定事件来完成某些操做,则可使用bind()
方法,bind()
方法的调用格式为:
bind(type [, data] ,fn);
bind()
方法有三个参数:设计模式
type
:事件类型,类型包括:blur
,focus
,load
,resize
,scroll
,unload
,click
,dbclick
,mousedown
,mouseup
,mousemove
,mouseover
,mouseout
,mouseenter
,mouseleave
,change
,select
,submit
,keydown
,keypress
,keyup
,error
等。[,data]
:可选参数,做为event.data属性值传递给事件对象的额外数据对象。fn
:用来绑定的处理函数。示例代码: [ 38-jq事件机制-事件绑定.html ]
<!-- html 部分 --> <h2>什么是相对论?</h2> <div class="hide"> <p>相对论是关于时空和引力的基本理论,主要由阿尔伯特·爱因斯坦创立,依据研究的对象不一样分为狭义相对论和广义相对论。相对论的基本假设是相对性原理,即物理定律与参照系的选择无关。</p> <p>狭义相对论和广义相对的区别是,前者讨论的是匀速直线运动的参照系(惯性参照系)之间的物理定律,后者则推广到具备加速度的参照系中(非惯性系),并在等效原理的假设下,普遍应用于引力场中。相对论极大地改变了人类对宇宙和天然的“常识性”观念,提出了“同时的相对性”、“四维时空”、“弯曲时空”等全新的概念。它发展了牛顿力学,推进物理学发展到一个新的高度。</p> <p>狭义相对性原理是相对论的两个基本假定,在目前实验的观测下,物体的运动与相对论是吻合很好的,因此目前广泛认为相对论是正确的理论。</p> </div> <!-- js 部分 --> <script> $(function() { // 绑定点击事件 $('h2').bind('click', function() { // 选择器$(this).next() 屡次出现,能够用一个变量接收 储存起来 var $content = $(this).next(); // is 方法 能够对元素的状态进行判断 if ($content.is(":visible")) { $content.hide(); } else { $content.show(); } }); }); </script>
效果图:
注意:
is()
方法,能够用来判断一个元素是否包含某一属性。二、简写绑定事件
jQuery
提供了一套简写的方法,简写的方法和bind()
的使用方法相似,实现效果也相同,可是能够减小代码量:
$(function(){ $('h2').click(function(){ // 执行代码 }); });
jQuery
有两个合成事件:hover()
方法和toggle()
方法(这里的toggle
跟另外一个方法toggle
不是一个方法,这里的toggle
方法由于重名的缘由,已经在jQ1.8
版本之后弃用了)。
一、hover()方法:
hover(enter,leaver); // enter 和 leaver 是两个函数
hover()
方法用于模拟光标悬停事件。当光标移动到元素上的时候会触发第一个函数(enter
),当光标离开元素的时候会触发第二个函数(leaver
)。
示例代码: [ 39-jq事件机制-合成事件hover.html ]
$(function() { // hover 方法 $('h2').hover(enter, leaver); var $content = $('h2').next(); // 鼠标进入的时候触发的函数 function enter() { $content.show(); } // 鼠标离开时触发的函数 function leaver() { $content.hide(); } });
二、toggle()方法:此方法自1.8版本之后,已弃用
toggle(fn1,fn2,...fnN);
toggle()
方法,模拟的是鼠标单击事件,当点击第一次的时候,触发对应的第一个函数(fn1
),当点击第二次的时候,触发对应的第二个函数(fn2
),一直到最后一个函数的时候,再点击就会循环到第一个函数,就这样一直循环切换。
另一个 toggle()
方法,是切换元素的可见状态,若是元素是可见的,事件触发以后,就会切换成不可见。
$('h2').click(function(){ $(this).next().toggle(); // 若是元素一开始是隐藏的,点击以后就会切换成显示。 });
在前面
特效篇
里面,咱们已经介绍了什么是
事件冒泡,这里再也不累赘,简单来讲,就是一个元素包含另外一个元素,两个元素同时绑定了点击事件,当我点击里面元素的时候,会同时触发两个事件函数,这就是事件冒泡。
具体产生的原理,和解决办法请点击这个连接,这里会有处理兼容性的详细步骤。
示例代码: [ 40-jq事件机制-事件冒泡.html ]
<!-- html 部分 --> <div class="box"> <p>提示信息</p> <div class="box1"> <p>提示信息</p> <div class="box2"> <p>提示信息</p> </div> </div> </div> <!-- js 部分 --> <script> $(function() { $('.box').click(function() { $(this).children('p').text(".box被触发了"); }); $('.box1').click(function() { $(this).children('p').text(".box1被触发了"); }); $('.box2').click(function() { $(this).children('p').text(".box2被触发了"); }); }); </script>
效果图:
咱们能够看到,明明点击的是最里面的盒子,可是三个点击事件都同时触发了。
一、事件对象:
因为在IE-DOM
和标准DOM
实现事件对象的方法各不相同,因此须要处理兼容性。在jQuery
中,已经将咱们封装好了。 直接在触发事件函数里面传一个参数:
$('element').bind('click',function(event){ // 执行代码 });
二、阻止事件冒泡:
阻止事件的方法存也在兼容性,一样的jQ
中已经封装好,直接使用stopPropagation()
方法来阻止事件冒泡。
示例代码: [ 41-jq事件机制-阻止事件冒泡.html ]
$(function() { $('.box').click(function(e) { // 事件对象 $(this).children('p').text(".box被触发了"); e.stopPropagation(); // 阻止事件冒泡 }); $('.box1').click(function(e) { $(this).children('p').text(".box1被触发了"); e.stopPropagation(); }); $('.box2').click(function(e) { $(this).children('p').text(".box2被触发了"); e.stopPropagation(); }); });
效果图:
三、阻止默认行为:
网页中有不少元素都有默认行为,例如,单击超连接后会跳转、单击提交按钮后表单会提交,有时候咱们须要阻止元素的默认行为。
在jQ
中提供了一个方法来阻止元素的默认行为:preventDefault
不加阻止默认行为时的效果:
示例代码: [ 42-jq事件机制-阻止默认行为.html ]
<!-- html 部分 --> <form action="test.html"> <label for="username">用户名</label><input type="text" id="username" placeholder="请输入用户名"> <br> <input type="submit" value="提交" id="sub"> </form> <div id="msg"></div> <!-- js 部分 --> <script> $(function() { $('#sub').click(function(e) { // 事件对象 var $username = $('#username').val(); if ($username == "") { $('#msg').html('<p>文本框的值不能为空</p>'); e.preventDefault(); // 阻止默认行为 } }); }); </script>
效果图:
四、return false:
若是想要同时对事件中止冒泡和阻止默认行为,能够有一种默认的简写方式:
return false
。
五、事件捕获:
在jQ
中不支持事件捕获,若是想要事件捕获的话,请参考原生的js
。
一、event.type:
该方法能够获取到事件的类型。
$("a").click(function(event){ console.log(event.type); // 打印a标签点击以后的事件类型 打印 ==> click return false; // 阻止a标签默认跳转事件 });
二、event.stopPropagation()方法:
上面已经提过了,该方法是阻止事件冒泡。
三、event.preventDefault()方法:
上面已经提过了,该方法是阻止事件默认行为。
四、event.target:
该方法的做用是获取到触发事件的元素。
$("a").click(function(event){ console.log(event.target); // 打印 ==> a return false; // 阻止a标签默认跳转事件 });
五、event.pageX 和 event.pageY:
该方法的做用,是分别获取到光标相对于页面的x
坐标和y
坐标,若是页面上有滚动条的话,还要加上滚动条的宽度和高度。
六、event.which
该方法的做用是在鼠标单击事件中获取到鼠标的左、中、右键;在键盘事件中获取键盘的按键。
好比获取鼠标的按键:
$("a").mousedown(function(event){ console.log(event.which); // 鼠标左键==> 1 鼠标中键==> 2 鼠标右键==> 3 return false; // 阻止a标签默认跳转事件 });
好比获取键盘的按键:
$("input[text]").keyup(function(event){ console.log(event.which); // 对应按下的键盘码 });
七、event.metaKey:
该方法是针对不一样浏览器,获取到
<ctrl>
按键。
当咱们想要移除一个事件的时候,可使用
unbind()
方法。
unbind([type].[data]);
第一个参数是事件类型,第二个参数是将要移除的函数:
示例代码: [ 43-jq事件机制-移除事件.html ]
<!-- html 部分 --> <button id="btn1">点击弹出alert</button> <br> <button id="btn2">点击移除上一个btn点击事件</button> <!-- js 部分 --> <script> $(function() { // 点击第一个按钮 弹出信息 $('#btn1').click(function() { alert('我是btn1'); }); // 点击第二个按钮移除第一个按钮的点击事件 $('#btn2').click(function() { $('#btn1').unbind('click'); }); }); </script>
效果图:
什么是模拟操做呢?咱们能够看到前面的单击事件,都须要手动去触发,模拟操做就是能够自动触发
click
,而不须要用户主动点击。
<!-- html 部分 --> <button id="btn">点击弹出信息</button> <!-- js 部分 --> <script> $(function() { $('#btn').click(function() { alert("呵呵"); }); // $('#btn').click(); $('#btn').trigger('click'); }); </script>
一进入页面就会自动弹出“呵呵”,其中 $('#btn').click();
,也能够达到一样的效果。
trigger()方法触发事件后,会执行浏览器默认操做:
$('input').trigger('focus');
上面的代码不只会触发元素绑定的focus
事件,也会使input
元素自己获得焦点(这就是浏览器的默认操做)。
triggerHandler()方法:
若是你只想触发绑定的focus
事件,而不想执行浏览器默认操做,可使用triggerHandler()
方法。
$('input').triggerHandler('focus');
事件委托,首先按字面的意思就能看出来,是将事件交由别人来执行,再联想到事件冒泡,是否是想到了?对,就是将子元素的事件经过冒泡的形式交由父元素来执行。
举个例子:
假如想要给多个li
都注册点击事件,只须要给li
循环遍历,再添加点击事件,这种方法当然简单,可是假若有100
个、1000
个li
的时候,这里的DOM
操无形之中就繁琐了。而且当咱们动态添加li
元素的时候,这些li
是没有点击事件的。可是这些只要讲点击事件交给父元素来执行,就能实现了。
一、on + 注册事件:
除了bind
方法绑定事件以外,在jQuery1.7
版本以后,新添了一种方法:on()
方法用来绑定事件,off()
方法用来解除绑定事件。on()
方法既能够注册事件,还能够注册委托事件。
$(element).on(type,[selector],fn);
参数详解:
type
:字符串,事件类型,如:click
、mouseover
...;selector
:可选,字符串,用于过滤出被选中的元素中能触发事件的后代元素。若是选择器是 null
或者忽略了该选择器,那么被选中的元素老是能触发事件;fn
:事件被触发执行的函数。示例代码:
<!-- html 部分 --> <div> <p>111111</p> <p>111111</p> <p>111111</p> <p>111111</p> <i>123456</i> </div> <!-- js 部分 --> <script> $(function () { // 这个是p本身注册的事件(简单事件) $("p").on("click", function() { alert("p的点击事件"); }); //给div本身执行的 $("div").on("click", function() { alert("div的点击事件"); }); //给div里面的p执行 委托事件 $("div").on("click", "p", function() { alert("div里面的p的点击事件"); }); }); </script>
效果图:
第二个参数其实就至关于一个过滤器的做用,给div
里面的p
注册委托事件。在执行顺序上,会先执行元素本身的事件,再去执行绑定的事件,最后执行父元素的事件。
当第二个参数传进去的时候,就想当于给过滤的元素注册委托事件
。
二、delegate 注册委托事件:
delegate
只能注册委托事件。
$(fatheElement).delegate(selector,type,fn);
参数详解:
fatheElement
:父元素;selector
:可选,字符串,用于过滤出被选中的元素中能触发事件的后代元素。若是选择器是 null
或者忽略了该选择器,那么被选中的元素老是能触发事件;type
:事件类型;fn
:事件被触发执行的函数。一、绑定多个事件类型:
$('div').bind('mouseover mouseout',function(){ $(this).toggleClass("over"); // 当鼠标进入的时候,该元素的class属性切换为over 鼠标离开时class切换为先前的值 });
二、添加事件的命名空间:
$('div').bind('click.plugin',function(){ alert(123); }); $('div').bind('mouseover.plugin',function(){ alert(456); }); $('div').bind('dbclick',function(){ alert(666); }); $('button').click(function(){ $('div').unbind('.plugin'); });
其中.plugin
就是命名空间,当点击button
按钮的时候,就删除了事件的命名空间.plugin
,此时对应的事件也会被移除。
相同的事件,不一样的命名空间:
$('div').bind('click.plugin',function(){ alert(456); }); $('div').bind('click',function(){ alert(666); }); $('button').click(function(){ $('div').trigger('click!'); // 注意后面的感叹号 });
当点击div
的时候,会同时触发click.plugin
和click
事件,若是点击button
只会触发click
事件,而不会触发click.plugin
事件。trigger('click!')
,后面感叹号表示的是匹配全部不在命名空间中的click
方法。
相对于原生js
,jQuery
中的动画更加的方便,更加的强大。
当一个元素调用show()
方法的时候,会将该元素的display
设置为block
,当调用hide()
方法的时候,会将该元素的display
设置为none
。
$('h2').bind('mouseover',function(){ $(this).next().show(); // 鼠标进入的时候 h2 下一个兄弟元素显示 }).bind('mouseout',function(){ $(this).next().hide(); // 鼠标离开的时候 h2 下一个兄弟元素隐藏 })
此时尚未动画的效果,下面给他们加上动画效果
下面的代码表示的是,元素在600ms
内显示出来:
$('element').show(600);
下面的代码表示的是,元素在300ms
内隐藏起来:
$('element').hide(300);
示例代码: [ 45-jq动画-show&hide.html ]
<!-- 样式部分 --> <style> * { margin: 0; padding: 0; } h4 { width: 300px; height: 30px; background: sandybrown; line-height: 30px; text-align: center; } div { width: 260px; height: 160; background: antiquewhite; padding: 20px; display: none; } </style> <!-- html 部分 --> <h4>鼠标通过&离开</h4> <div> <p>相对论是关于时空和引力的基本理论,主要由阿尔伯特·爱因斯坦创立,依据研究的对象不一样分为狭义相对论和广义相对论。相对论的基本假设是相对性原理,即物理定律与参照系的选择无关。</p> </div> <!-- js 部分 --> <script> $(function() { $('h4').bind('mouseover', function() { $(this).next().show(600); }).bind('mouseout', function() { $(this).next().hide(300); }); }); </script>
效果图:
咱们能够看到,无论是show
仍是hide
的时候,元素的宽
、高
和不透明度
都是在慢慢增长或者减少的。
与show
、hide
方法不一样的是,fadeIn
和fadeOut
方法只改变元素的不透明度,不会去改变宽高。
下面的代码表示的是元素淡入
的效果,其中也能够传时间:
$('element').fadeIn();
下面的代码表示的是元素淡出
的效果:
$('element').fadeOut();
示例代码: [ 46-jq动画-fadeIn&fadeOut.html ]
$(function() { $('h4').bind('mouseover', function() { $(this).next().fadeIn(); }).bind('mouseout', function() { $(this).next().fadeOut(); }); });
效果图:
slideUp()
方法和slideDown()
方法只会改变元素的高度,若是一个元素的display
属性值为“none”
,调用slideDown()
方法的时候元素由上至下延伸显示。slideUp()
正好相反,元素将由下到上缩短隐藏。
示例代码: [ 47-jq动画-slideDown&slideUp.html ]
$(function() { $('h4').bind('mouseover', function() { $(this).next().slideDown(); }).bind('mouseout', function() { $(this).next().slideUp(); }); });
效果图:
前面几种类型动画,比较单一,不少时候不能知足于用户的需求,可是在jQ
中还有一个自定义动画animate
,很是强大。
animate(params,speed,easing,callback);
参数说明以下:
params
:一个包含样式和值的对象,好比{p1:"val1",p2:"val2",...}
;speed
:动画执行速度(可选),默认400
;easing
:表示过分使用哪一种缓动函数(默认swing
,jQ
内部还支持一个linear
)callback
:在动画执行完以后,执行的函数(可选)。一、简单的动画:
<!-- 样式部分 --> <style> #box { position: relative; width: 150px; height: 150px; background: aquamarine; } </style> <!-- html 部分 --> <div id="box"></div> <!-- js 部分 --> <script> $(function() { // box两秒内向右移动600px $('#box').animate({left: '600px'}, 2000); }); </script>
效果图:
二、累加、累减动画:
经过累加一个值让元素从当前位置,累加到900的位置
$('#box2').animate({ left: '+=900' // 在当前位置累加到 900 }, 1000);
三、多重动画:
同时执行多个动画
$('#box3').click(function() { $(this).animate({ left: '300', height: '200px', width: '200px', top: '200px' }, 2000); });
效果图:
咱们能够看到全部的变化都是同时进行的。
按顺序执行多个动画
$('#box4').click(function() { $(this).animate({ left: '400px', height: '150px', opacity: '1' }, 3000).animate({ top: '150px', width: '150px' }, 3000).fadeOut('slow'); });
效果图:
四、延迟动画:
在动画执行中若是想要对某一段动画进行延迟操做,可使用
delay()
方法。
$('#box5').click(function() { $(this).animate({ left: '400px', height: '150px', opacity: '1' }, 3000) .delay(1000) .animate({ top: '150px', width: '150px' }, 3000).fadeOut('slow'); });
效果图:
五、动画队列:
一组元素上的效果:
animate()
方法中应用多个属性时,动画是同时发生的;多组元素上的动画:
六、中止动画:
若是须要在某处中止动画须要使用
stop()
方法。
stop([clearQueue],[gotoEnd]);
两个参数都是可选的,都为布尔值,clearQueue
表示是否要清空未执行完的动画队列。gotoEnd
表示的是直接将正在执行的动画跳转到末状态。直接使用stop()
方法,则会当即中止当前正在执行的动画。
不明白的小伙伴,参考8.6
小节,第二个案例 《动画下拉菜单栏》
一、toggle()方法:
toggle()
方法能够切换元素的可见状态,若是元素是可见的,则切换为隐藏。若是元素是隐藏的,则切换为可见。
$('#btn1').click(function() { $(this).next().toggle(); });
效果图:
只要循环点击h4
,它的下一个兄弟元素就会循环切换。
二、slideToggle()方法:
经过高度变化来切换匹配元素的可见性。
$('#btn2').click(function() { $(this).next().slideToggle(); });
效果图:
三、fadeTo()方法:
fadeTo()
方法能够将不透明度设置到指定的值。
$('#btn3').click(function() { $(this).next().fadeTo(600, 0.5); // 600表示的是执行时间 0.5 表示目标值 });
效果图:
四、fadeToggle()方法:
fadeToggle()
方法能够切换不透明度。
$('#btn4').click(function() { $(this).next().fadeToggle(); });
效果图:
下面经过几个简单的例子,巩固一下
jQuery
动画的知识。
一、呼吸灯版轮播图:
在实现原理上,与前面特效篇的是不一样的,这里改变的是图片的不透明度opacity
,而且不须要让全部li
左浮动,ul
也不须要设置一个很宽的宽度。在jQ
中操做更加的简单。
样式上:
li
设置隐藏属性,第一张图片须要显示;js上:
index
用来记录当前点击的张数;li
,fadeIn
,其他的兄弟元素fadeOut
,同时让对应的小圆点添加current
类,其他的兄弟元素移除这个类;index--
,再进行判断一下,其余的与点击右箭头原理是同样的。示例代码: [ 50-jq动画-案例-呼吸灯版轮播图.html ]
<!-- 样式部分 --> <style> * { margin: 0; padding: 0; list-style: none; } #slide { width: 560px; height: 315px; margin: 100px auto; position: relative; } #slide ul li { position: absolute; display: none; } #slide ul li:first-child { display: block; } #slide ul img { display: block; } #slide #arrow { display: none; } #slide:hover #arrow { display: block; } #slide #arrow #leftArr, #slide #arrow #rightArr { width: 30px; height: 60px; background-color: rgba(0, 0, 0, 0.3); position: absolute; top: 50%; margin-top: -30px; text-decoration: none; color: #fff; text-align: center; font: 700 24px/60px "宋体"; } #slide #arrow #leftArr { left: 0; } #slide #arrow #rightArr { right: 0; } #slide #arrow #leftArr:hover, #slide #arrow #rightArr:hover { background-color: rgba(0, 0, 0, 0.5); } #slide ol { width: 100px; height: 14px; background-color: rgba(255, 255, 255, 0.6); position: absolute; bottom: 14px; left: 50%; margin-left: -50px; border-radius: 7px; } #slide ol li { width: 10px; height: 10px; float: left; background-color: #fff; border-radius: 50%; margin-top: 2px; margin-left: 8.5px; cursor: pointer; } #slide ol li.current { background-color: #DF654A; } </style> <!-- html 部分 --> <div id="slide"> <ul> <li> <a href="#"><img src="../image/轮播图/1.jpg" alt=""></a> </li> <li> <a href="#"><img src="../image/轮播图/2.jpg" alt=""></a> </li> <li> <a href="#"><img src="../image/轮播图/3.jpg" alt=""></a> </li> <li> <a href="#"><img src="../image/轮播图/4.jpg" alt=""></a> </li> <li> <a href="#"><img src="../image/轮播图/5.jpg" alt=""></a> </li> </ul> <div id="arrow"> <a href="javascript:void(0);" id="leftArr"><</a> <a href="javascript:void(0);" id="rightArr">></a> </div> <ol id="circleOl"> <li class="current"></li> <li></li> <li></li> <li></li> <li></li> </ol> </div> <!-- js 部分 --> <script> $(function() { // 定义一个变量,监测张数 var index = 0; var $li = $('#slide ul li'); // 1- 右箭头功能 $('#rightArr').click(function() { index++; if (index == $li.length) { index = 0; } // 让第 index 个 li fadeIn,其余全部的兄弟元素 fadeOut $li.eq(index).fadeIn(1000).siblings().fadeOut(1000); // 控制小圆点,当前index的小圆点添加 current 类 其他的兄弟元素移除这个类 $('#circleOl li').eq(index).addClass('current').siblings().removeClass('current'); }); // 2- 左箭头功能 $('#leftArr').click(function() { index--; if (index == -1) { index = $li.length - 1; } // 让第 index 个 li fadeIn,其余全部的兄弟元素 fadeOut $li.eq(index).fadeIn(1000).siblings().fadeOut(1000); // 控制小圆点,当前index的小圆点添加 current 类 其他的兄弟元素移除这个类 $('#circleOl li').eq(index).addClass('current').siblings().removeClass('current'); }); }); </script>
效果图:
二、动画下拉菜单栏:
动画下拉菜单栏,主要实现原理仍是运用jQ
里面的两个动画slideDown
和slideUp
,而且配合stop方法
。
先看一下,若是不加stop()
方法,会是一个什么效果:
咱们能够看到一个效果,当光标移到第一个“一级菜单”的时候,触发动画效果,可是动画效果还没结束,我就将光标移进了第二个菜单,触发第二个菜单下拉效果。因此致使了动画效果与光标不一致,此时只须要在光标移入、移出以前加上stop()
方法,就能解决这个问题。
stop()
方法会结束当前正在进行的动画效果,并当即执行队列中的下一个动画。
示例代码: [ 51-jq动画-案例-动画下拉菜单.html ]
<!-- html 部分 --> <div class="wrap"> <ul> <li> <a href="javascript:void(0);">一级菜单1</a> <ul class="ul"> <li><a href="javascript:void(0);">二级菜单11</a></li> <li><a href="javascript:void(0);">二级菜单12</a></li> <li><a href="javascript:void(0);">二级菜单13</a></li> </ul> </li> <li> <a href="javascript:void(0);">一级菜单2</a> <ul> <li><a href="javascript:void(0);">二级菜单21</a></li> <li><a href="javascript:void(0);">二级菜单22</a></li> <li><a href="javascript:void(0);">二级菜单23</a></li> </ul> </li> <li> <a href="javascript:void(0);">一级菜单3</a> <ul> <li><a href="javascript:void(0);">二级菜单31</a></li> <li><a href="javascript:void(0);">二级菜单32</a></li> <li><a href="javascript:void(0);">二级菜单33</a></li> </ul> </li> </ul> </div> <!-- js 部分 --> <script> $(function() { // 1- 给当前 菜单栏注册鼠标进入事件 $('.wrap>ul>li').mouseenter(function() { // 进入的时候,让下面的ul slideDown动画显示,显示以前要加上stop方法 $(this).children('ul').stop().slideDown(); }); // 2- 给当前 菜单栏注册鼠标离开事件 $('.wrap>ul>li').mouseleave(function() { // 离开的时候,让下面的ul slideUp动画显示,显示以前要加上stop方法 $(this).children('ul').stop().slideUp() }); }); </script>
效果图:
三、手风琴:
实现原理:
ul,li
结构,li
设置宽高,与图片大小一致,设置绝对定li
添加背景图片,由于li
绝对定位的缘由,此时全部的li
都叠在一块儿li
设置left
值(left*i
),这时候li
就会依次排开overflow-hidden
属性,将多余的隐藏掉li
注册鼠标鼠标通过事件,而后根据下面推算出的规律(当前鼠标通过的索引index
,他以前包括他本身的left
值都是,设定的最小值乘以对应的索引。而他后面的会将设定的最小值乘以对应的索引后再加上450
,这里的450
不是一个固定值,根据规律找出来的)进行判断,设置各自的left
值;大盒子没有overflow-hidden
的时候:
画个图,理解一下:
找规律:
结合上面的图片,咱们能够找到一个规律
当鼠标在第1个li上的时候,li下标index为0:
当鼠标在第2个li上的时候,li下标index为1:
当鼠标在第3个li上的时候,li下标index为2:
看出规律了吗?
<=
鼠标悬停的的下标上的时候left
值 是50*i
>
鼠标悬停的的下标上的时候left
值 是50*i + ,450
(450不是固定的值,是通过计算出来的)示例代码: [ 52-jq动画-案例-手风琴.html ]
<!-- 样式部分 --> <style> * { margin: 0; padding: 0; list-style: none; } #box { width: 700px; height: 440px; margin: 100px auto; position: relative; overflow: hidden; box-sizing: border-box; border-radius: 30px; } li { width: 700px; height: 440px; position: absolute; } </style> <!-- html 部分 --> <div id="box"> <ul> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> </div> <!-- js 部分 --> <script> $(function() { var $li = $('#box li'); // 给全部的 li 设置背景图 for (var i = 0; i < $li.length; i++) { // 这里加上eq的目的是,隐式迭代添加的图片只会是第一张 $li.eq(i) .css({ "backgroundImage": "url(../image/手风琴/" + (i + 1) + ".png)", "left": 140 * i }); // 鼠标进入的时候 $li.mouseenter(function() { for (var i = 0; i < $li.length; i++) { // 判断i小于等于当前索引的时候,让以前的left值都是50*i的 if (i <= $(this).index()) { $li.eq(i).stop().animate({ left: 50 * i }) } else { // 其他的li的left值应该加上450 $li.eq(i).stop().animate({ left: 50 * i + 450 }); } } }); // 鼠标离开的时候 让每个li 的left 恢复到 140*i $li.mouseleave(function() { for (var i = 0; i < $li.length; i++) { $li.eq(i).stop().animate({ left: 140 * i }); } }); } }); </script>
效果图:
四、弹幕效果:
value
值;并生成 span
标签span
标签添加到 页面中,随机颜色 随机高度 span
动画从右向左span
标签(不删除会随着输入的内容愈来愈多影响性能)示例代码: [ 53-jq动画-案例-弹幕效果.html ]
<!-- html 部分 --> <div id="page"> <div id="import"> <div id="content"> <p class="title">吐槽</p> <input type="text" name="" id="text" placeholder="发送弹幕,与小伙伴一块儿互动!"> <button id="btn">发射</button> </div> </div> </div> <!-- js 部分 --> <script> $(function() { // 定义一个颜色数组 var colorArr = ['#FF895D', '#78BBE6', '#FF4273', '#00BBF0', '#7C73E6', '#EE2B47', '#F60C86', '#9870FC', '#F96D00', '#303481']; $('#btn').click(function() { // 获取到输入框的内容 var content = $('#text').val(); $("#text").val(""); // 获取随机颜色和高度 var randomColor = parseInt(Math.random() * colorArr.length); var randomTop = parseInt(Math.random() * 301); // 获取屏幕的可视宽度 var clientWidth = $(window).width(); // 根据屏幕的宽度计算出弹幕的速度(1300px的时候8秒执行完) var time = (8000 / 1300) * clientWidth; // 建立span标签 判断当输入为空的时候不触发 if (content != "" && content.trim()) { $('<span></span>').text(content) // 设置span的颜色 与 top值left值 .css({ "color": colorArr[randomColor], "left": clientWidth, "top": randomTop }) // 将建立的span添加到页面中 .appendTo("#page") // 执行动画 left目标值-300px,执行时间time 过渡效果linear(匀速) 回调函数内将到达终点的span移除掉 .animate({left: -300}, time, "linear", function() { $(this).remove(); }) } }); // 对整个页面注册键盘按下事件 $(document).keydown(function(e) { // 当按下的键为回车键时,执行上面的点击事件 if (e.keyCode == 13) { $("#btn").click(); } }) }); </script>
效果图:
Ajax
全称“Asynchronous JavaScript and XML
”(异步的JavaScript
和XML
)。它的出现揭开了无刷新更新页面的新时代。具体的实现方式以及Ajax
的优缺点,在前面的一篇文章[《js 进阶知识-Ajax篇》]()已经讲得很详细了,不明白的小伙伴,能够先去学习下原生js
是如何实现Ajax
的。
jQuery
对Ajax
操做进行了封装,在jQuery
中$.ajax()
方法属于最底层的方法,第2
层是load()
、$.get()
和$.post()
方法,第3
层就是$.getScript()
和$.getJSON()
方法。
一、载入HTML文档
load()
方法是jQuery
中最为简单和经常使用的Ajax
方法,能载入远程HTML
代码并插入DOM
中。它的结构为:
load(url[,data][,callback]);
参数详解:
参数名称 | 类型 | 说明 |
---|---|---|
url |
String |
请求HTML 页面的URL 地址 |
data (可选) |
Object |
发送至服务器的key/value 数据 |
callback (可选) |
Function |
请求完成时的回调函数,不管请求成功仍是失败 |
示例代码:
首先新建一个data.html
的文件,里面模拟的是请求的数据:
<div class="comment"> <h4>张三:</h4> <p class="para">哈哈哈,真有趣</p> </div> <div class="comment"> <h4>李四:</h4> <p class="para">顶楼上</p> </div> <div class="comment"> <h4>王五:</h4> <p class="para">66666</p> </div>
再建立一个主页面,index.html
:
<!-- 样式部分 --> <style> .send { margin-bottom: 10px; } .comment { width: 300px; padding: 10px 0px 10px 10px; background: rgba(156, 250, 220, 0.5); border: 1px dashed #f45; margin-bottom: 10px; } </style> <!-- html 部分 --> <input type="button" class="send" value="Ajax请求"> <div class="comment">已有评论:</div> <div class="resText"></div> <!-- js部分 --> <script> $(function() { // 点击按钮,使用load方法请求data页面 $(".send").click(function() { // 请求的页面追加到类名为resText的div中 $(".resText").load("data.html"); }); }); </script>
效果图:
上面的例子能够看出来,开发人员只须要使用jQuery
选择器为HTML
片断指定目标位置,而后将要加载的文件URL
做为参数传递给load()
方法便可。咱们能够发现本来的data
页面是没有为类comment
设置样式的,可是主页面加载后一样的样式名会当即应用到新加载的内容上。
二、筛选载入的HTML文档
上面的案例咱们能够看到,点击以后data.html
里面的整个内容都被加载进来了。若是须要加载data.html
页面里的某些元素的时候该怎么办呢?咱们可使用load()
方法的URL参数来达到目的。只须要指定选择符就ok
了。
示例代码:
// 选择加载data.html页面中class为“para”的内容,注意中间有一个空格 $(".resText").load("data.html .para");
效果图:
咱们能够看到,只有类名是“para
”的被加载了。
三、传递方式:
load()
方法的传递方式根据参数data
来自动指定。若是没有参数传递,则采用GET
方式传递;反之则会自动转换为POST
方式:
// 1- 无data参数传递的时候,则是GET方式 $('.resText').load("data.php",function(){}); // 2- 有data参数传递的时候,则是POST方式 $('.resText').load("data.php",{name:"Levi",age:"18"},function(){});
四、回调函数:
回调函数是在页面加载完成以后执行的操做,该函数有三个参数,分别是请求返回的内容、请求状态、
XMLHttpRequest
对象:
$('.resText').load("data.php",function(responseText,textStatus,XMLHttpRequest){ // responseText : 请求返回的内容 // textStatus:请求状态:success、error、notmodified、timeout 4种 // XMLHttpRequest :XMLHttpRequest对象 });
在load()
方法中,不管Ajax
请求是否成功,只要当请求完成以后,回调函数都会执行。
load()
方法一般是用来从WEB
服务器上获取静态的数据的,若是须要向服务器传递参数的话,可使用$.get()
方法和$.post()
方法还有后面的$.ajax
方法。
一、$.get()方法
$.get()
方法使用GET
方式来进行异步请求:
$.get(url [,data] [,callback] [,type]);
参数详解:
参数名称 | 类型 | 说明 |
---|---|---|
url |
String |
请求HTML 页面的URL 地址 |
data (可选) |
Object |
发送至服务器的key/value 数据,会做为字符串凭接在url的后面 |
callback (可选) |
Function |
请求完成时的回调函数(只有当Response的返回状态是success的时候,才调用该函数) |
type (可选) |
String |
服务器返回内容的格式,包括xml、html、script、json、text、_default |
回调函数:
$.get()
方法的回调函数只有两个参数:
$.get("get.php",{useraname: "Levi",age:18},function(data,textStatus){ // data 返回的内容,能够是XML文档、JSON文件、HTML片断等的 // textStatus 请求状态:success、error、notmodified、timeout 4种。 })
data
参数表明请求返回的内容,textStatus
参数表明请求回来的状态,注意:只有当数据成功返回success
后才被调用。
二、$.post()方法
它与
$.get()
方法的结构和使用方式都相同,不过他们之间仍有如下区别:
$.ajax()
方式经常使用参数解析:
方法 | 做用 |
---|---|
url |
请求的地址 |
type |
请求的方式 |
dataType |
告诉jQuery ,须要按照什么格式对服务器返回的数据进行解析,默认json |
data |
数据 |
success |
请求成功的回调函数 |
error |
请求失败的回调函数 |
beforeSend |
请求发送以前调用的函数 |
complete |
不论请求是成功仍是失败的,只要请求完成就会调用 |
timeout |
设置请求超时时间 |
示例代码:
$.ajax({ // 请求的地址 url: "04-data.php", // 请求的方式 type: "get", // 告诉jQuery,须要按照什么格式对服务器返回的数据进行解析,默认json dataType: "json", // 数据 data: { msg: "我是来请求数据的" }, // 请求成功的回调函数 success: function(data) { console.log(data); }, // 请求失败的回调函数 error: function() { console.log("失败了"); }, // 请求发送以前调用的函数 beforeSend: function() { console.log("请求发送以前调用的函数"); // 若是返回一个false,那么就会阻止整个请求的发送 // return false; // 用法:能够用做表单验证,当表单内容符合规范的时候发送ajax请求,当不符合的时候就不发送ajax请求 }, // 不论请求是成功仍是失败的,只要请求完成就会调用 complete: function() { console.log("请求完成了"); }, // 设置请求超时时间(单位:ms),超过这个时间后,就不会请求了 timeout:2000 });
一、jQuery中的serialize方法:
serialize
方法会将表单中全部的内容拼接成key=value&key=value
这样的字符串。
经过这种方式就不要再去手动获取表单中的内容的
<form id="form"> <input type="text" name="username"> <input type="text" name="pwd"> <input type="text" name="phonenumber"> <input type="text" name="email"> <button id="btn">获取数据</button> </form> <script src="jquery.min.js"></script> <script> $(function() { $('#btn').click = function() { var dataStr = $('#form').serialize(); $.ajax({ url: "json.php", //data这个参数能够接收对象,也能够接受 key=value&key=value的这种字符串 data: dataStr, type: "post" }); } }); </script>
二、jQuery中的serializeArray方法:
上面的方法咱们能够看到,获取整个数据的时候,是很简单,可是想要进行校验的话就很难,由于上面的方法获取的是一个字符串,不能进行校验,因此此时咱们须要另一个方法,jQuery
中的serializeArray
方法。
<form id="form"> <input type="text" name="username"> <input type="text" name="pwd"> <input type="text" name="phonenumber"> <input type="text" name="email"> <button id="btn">获取数据</button> </form> <script src="jquery.min.js"></script> <script> $(function() { $('#btn').click = function() { // 获取到的数组拼接成字符串 var dataArr = $('#form').serializeArray(); $.ajax({ url: "json.php", data: dataArr, type: "post" }); } }); </script>
示例代码:ajax模拟表单校验及注册
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>sing in page</title> <style> body { margin: 0; padding: 0; background-color: #F7F7F7; } ul { margin: 0; padding: 50px; list-style: none; } .register { width: 800px; margin: 50px auto; background-color: #FFF; border: 1px solid #CCC; border-radius: 5px; } li { display: flex; margin: 20px 0; } label, input { display: block; float: left; height: 46px; font-size: 24px; box-sizing: border-box; color: #333; } label { width: 200px; line-height: 46px; margin-right: 30px; text-align: right; } input { width: 320px; padding: 8px; line-height: 1; outline: none; position: relative; } input.code { width: 120px; } input.verify { width: 190px; margin-left: 10px; } input.disabled { background-color: #CCC !important; } input[type=button] { border: none; color: #FFF; background-color: #E64145; border-radius: 4px; cursor: pointer; } .error { color: red; margin-left: 10px; font-size: 12px; line-height: 46px; } .tips { position: fixed; top: 0; width: 100%; height: 40px; text-align: center; } .tips p { min-width: 300px; max-width: 400px; line-height: 40px; margin: 0 auto; color: #FFF; display: none; background-color: #C91623; } </style> </head> <body> <div class="register"> <form id="ajaxForm"> <ul> <li> <label for="name">用户名</label> <input type="text" name="name" class="name" id="name"> <span class="error"></span> </li> <li> <label for="pass">请设置密码</label> <input type="password" name="pass" class="pass" id="pass"> </li> <li> <label for="repass">请确认密码</label> <input type="password" name="repass" class="repass" id="repass"> </li> <li> <label for="mobile">验证手机</label> <input type="text" name="mobile" class="mobile" id="mobile"> </li> <li> <label for="code">短信验证码</label> <input type="text" name="code" class="code" id="code"> <input type="button" value="获取验证码" class="verify"> </li> <li> <label for="submit"></label> <input type="button" class="submit" value="当即注册" id="submit"> </li> </ul> </form> </div> <div class="tips"> <p>用户名不能为空</p> </div> <script src="../05-Form-Validation/js/jquery.min.js"></script> <script> /* * 1.获取短信验证码 * 1.1 当没有输入手机号的时候 提示请输入手机号 * 1.2 手机号格式不正确 提示请输入正确的手机号 * 1.3 调获取短信验证码接口 * 1.4 显示正在发送中 不能再次发送(防止重复提交) * 1.5 当接口成功 按照后台的计时时间 进行倒计时 * 1.6 当接口失败 提示短信接口繁忙 恢复按钮 * 1.7 倒计时完成以后 恢复按钮 * */ /* * 2.注册 * 2.1 当没有输入用户名的时候 提示请输入用户名 * 2.2 调注册接口 * 2.3 显示正在提交 不能再次发送(防止重复提交) * 2.4 当接口成功 * 状态码 10000 成功 * 状态码 10001 失败 提示用户 用户名已注册 表单后 * 状态码 10002 失败 没输用户 请输入用户名 * 恢复按钮 * 2.5 当接口失败 恢复按钮 * */ $(function() { /* 警告显示提示 */ var showTip = function(tip) { $(".tips p").html(tip).fadeIn(500).delay(1000).fadeOut(500); }; /* 1.获取短信验证码 */ $(".verify").on("click", function() { /* 当前按钮指定变量 */ var $btn = $(this); /* 判断当前按钮是否有disabled属性,有的话说明已经被点击了,就不让再点击了 */ if ($btn.hasClass('disabled')) { return false; } /* 获取手机号 */ var mobile = $.trim($('#mobile').val()); /* 判断是否输入内容,没有的话提示信息 */ if (!mobile) { showTip('请输入手机号'); return false; } /* 判断手机格式 不正确的话提示信息 */ var regPhone = /^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/; if (!regPhone.test(mobile)) { showTip('请输入正确的手机号'); return false; } /* 调取短信验证码接口 */ $.ajax({ url: 'registerCode.php', type: 'post', dataType: 'json', data: { mobile: mobile }, success: function(data) { if (data.code == 10000) { /* 给发送成功的按钮添加一个倒计时 */ var time = parseInt(data.result.time); var timer = setInterval(function() { time--; $btn.val(time + '秒后再次获取'); /* 倒计时完成以后 恢复按钮*/ if (time <= 0) { $btn.val('获取验证码').removeClass('disabled'); clearInterval(timer); } }, 1000); } else { /* 逻辑上的失败 */ $btn.val('获取验证码').removeClass('disabled'); } }, error: function() { /* 当接口失败,提示短信接口繁忙 */ showTip('短信接口繁忙'); $btn.val('获取验证码').removeClass('disabled'); }, beforeSend: function() { /* 点击以后,显示正在发送 */ $btn.val('正在发送...').addClass('disabled'); } }); $btn.addClass('disabled'); }); /* 2.注册功能的实现 */ $('.submit').on('click', function() { /* 当前点击的按钮 */ var $btn = $(this); /* 正在请求当中 不能再次点击 */ if ($btn.hasClass('disabled')) { return false; } var username = $("#name").val().trim(); var password = $("#pass").val().trim(); var repeatPassword = $("#repass").val().trim(); var code = $("#code").val().trim(); var phoneNum = $("#mobile").val().trim(); /* 调注册接口 */ $.ajax({ type: 'post', url: 'register.php', data: { name: username, pass: password, repass: repeatPassword, code: code, mobile: phoneNum }, dataType: 'json', // beforeSend: function() { // /* 显示正在提交 不能再次发送(防止重复提交)*/ // $btn.val('正在提交...').addClass('disabled'); // }, success: function(data) { /* 当接口成功 */ /* 状态码 10000 成功 */ if (data.code == 10000) { /* 提示+跳转登陆页 */ showTip('恭喜' + data.result.name + '注册成功,3后秒自动前往登陆页'); setTimeout(function() { location.href = 'http://www.baidu.com/'; }, 3000); } else if (data.code == 10001) { /* 输入框提示 */ $('.error').html('用户名已注册'); /* 恢复按钮 */ $btn.val('当即注册').removeClass('disabled'); } else if (data.code == 10002) { showTip('请输入用户名'); /* 恢复按钮 */ $btn.val('当即注册').removeClass('disabled'); } }, error: function() { showTip('系统繁忙!'); $btn.val('当即注册').removeClass('disabled'); } }) }); }); </script> </body> </html>
效果图:
插件:plugin
,jQuery
不可能包含全部的功能,因此就出现了成百上千的插件,帮助咱们扩展jQuery
的功能。
最新最全的插件能够参考jQuery
官方网站的插件版块。
animate
不支持颜色的渐变,可是使用了jquery.color.js
后,就能够支持颜色的渐变了。
使用步骤:
jQuery
,再引入jquery.color.js
<!-- 引入js --> <script src="../js/jquery-3.2.1.min.js"></script> <script src="../js/plugins/jquery.color.js"></script> <!-- 样式部分 --> <style> .box { width: 300px; height: 300px; background: aquamarine; } </style> <!-- html 部分 --> <input type="button" id="btn" value="点击过渡"> <div class="box"></div> <!-- js 部分 --> <script> $(function() { $('#btn').click(function() { $('.box').animate({ backgroundColor: "#f45f45" }, 1000); }); }); </script>
什么是懒加载?
懒加载也就是延迟加载。当访问一个页面的时候,先把img
元素或是其余元素的背景图片路径替换成一张大小为1*1px
图片的路径(这样就只需请求一次,俗称占位图),只有当图片出如今浏览器的可视区域内时,才设置图片正真的路径,让图片显示出来。这就是图片懒加载。
为何要使用懒加载?
不少页面,内容很丰富,页面很长,图片较多。好比说各类商城页面。这些页面图片数量多,并且比较大,少说百来K,多则上兆。要是页面载入就一次性加载完毕。估计你们都会等到黄花变成黄花菜了。
懒加载的原理是什么?
页面中的img
元素,若是没有src
属性,浏览器就不会发出请求去下载图片,只有经过javascript
设置了图片路径,浏览器才会发送请求。懒加载的原理就是先在页面中把全部的图片统一使用一张占位图进行占位,把正真的路径存在元素的“
data-url
”(这个名字起个本身认识好记的就行)属性里,要用的时候就取出来,再设置;
懒加载的实现步骤?
首先,不要将图片地址放到src
属性中,而是放到其它属性(data-url
)中。页面加载完成后,根据
scrollTop
判断图片是否在用户的视野内,若是在,则将data-url
属性中的值取出存放到src
属性中。在滚动事件中重复判断图片是否进入视野,若是进入,则将
data-url
属性中的值取出存放到src
属性中。
插件使用:
data-original
;jQ
中找到图片元素,给它加上一个lazyload()
函数。<!-- 样式部分 --> <style> center { margin-top: 1200px; } div { margin-bottom: 10px; } img { width: 500px; height: 350px; } </style> <!-- html 部分 --> <center id="box"> <div><img src="" data-original="http://ww1.sinaimg.cn/large/9c47d583gy1fjgqik3k1kj211y0lcdji.jpg" alt="当你看不见图片的时候,你才会看到这里的字"></div> </center> <!-- js 部分 --> <script> $(function() { //使用插件 $("img").lazyload(); }); </script>
jQuery UI
是一个创建在jQuery JavaScript
库上的小部件和交互库,您可使用它建立高度交互的Web
应用程序。
下载地址:点击这里跳转到官网下载
虽然网上的插件有不少,可是可能不是咱们彻底想要的,其中可能还穿插着其余的功能,因此咱们也能够本身封装一个
jQuery
插件,
有三种方式为全部jQuery
对象添加方法,在建立一个jQuery
插件的时候,咱们只须要将添加的方法保存为一个js
文件,再去引用它便可。
一、$.prototype
方法添加
$.prototype.setStyle = function(){ };
二、$.fn.setStyle
方法添加
$.fn.setStyle = function(){ };
三、$.fn.extend({})
方法添加
// extend能够新增多个方法 $.fn.extend({ setStyle:function(){ }, setPosition:function(){ } });
示例代码:
经过上面三种方法的任何一种,为jQuery
添加一个插件setStyle
。
建立插件jquery.setStyle.js
:
// 给jQuery里面添加一个setStyle方法 // (function(){})()的做用是函数自调用,避免全局污染。是一种设计模式:沙箱模式 (function(){ $.fn.setStyle = function(){ this.css({ width:400, height:400, backgroundColor:"pink" }); return this; } })()
使用插件:
<div id="box"></div> <script src="jquery.min.js"></script> <script src="jquery.setStyle.js"></script> <script> // 弹出123 $("#box").setStyle(); </script>
沙箱模式:(function(){})()
的做用是函数自调用,避免全局污染。是一种设计模式:沙箱模式
用jQuery
封装一个瀑布流插件,前面特效篇已经讲过了瀑布流的原理,不明白的小伙伴,建议先去看看原生实现的原理( 《原生js实现瀑布流效果》),再来学习jQuery
封装。
主页面部分:
<!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> <style> body { margin: 0; padding: 0; font-family: "Microsoft Yahei"; background: #f5f5f5; } .box { width: 1200px; margin: 0 auto; padding-top: 40px } .box > .items { position: relative; } .box > .items > .item { width: 220px; box-shadow: 2px 2px 2px #999; position: absolute; } .box > .items > .item > p { margin: 0; padding: 10px; background: #fff; } .box > .items > .item > img { width: 100%; display: block } .box > .btn { width: 280px; height: 40px; margin: 30px auto; text-align: center; line-height: 40px; background-color: #CCC; border-radius: 6px; font-size: 24px; cursor: pointer; } .box > .loading { background-color: transparent; } </style> </head> <body> <div class="box"> <div class="items"> <div class="item"> <img src="image/001.jpg" alt=""> <p>云想衣裳花想容,春风拂槛露华浓。若非群玉山头见,会向瑶台月下逢。</p> </div> . . . <div class="item"> <img src="image/030.jpg" alt=""> <p>云想衣裳花想容,春风拂槛露华浓。若非群玉山头见,会向瑶台月下逢。</p> </div> </div> <div class="btn">正在加载...</div> </div> <script src="jquery.min.js"></script> <script src="jquery.waterfull.js"></script> <script> // 必定要写在入口函数内,保证图片加载完在计算高度 window.onload = function(){ $(".items").waterfull(); } </script> </body> </html>
封装插件jquery.waterfull.js:
(function(){ $.fn.waterfull = function(){ // 1-肯定要排多少列 var columns = 5; // 2-获取每个元素的宽度 // this指的是当前调用的对象items 要获取的是item的宽度 var width = this.children().width(); // 3-计算间隔 gap:左右间隔 gap_t:上下间隔 var gap = (this.width() - width * columns) / (columns - 1); var gap_t = 10; // 4-声明一个数组,用来存放全部item的高度值 var heightArr = []; // 5-遍历全部item this.children().each(function(index,ele){ // 5-1 排列第一行 // 判断当前遍历的item索引小于列数的时候,说明是第一行 if(index < columns){ // 将ele对象转化成DOM对象,再设置它的top 和 left $(ele).css({ top:0, left:index * (width +gap) }); // 5-2 将第一行每个item的高度存到数组中 heightArr.push($(ele).height()); }else{ // 5-3 计算heightArr数组里面的最小值,并记录下最小值的列数即索引 var minHeight = heightArr[0]; var minIndex = 0; $.each(heightArr,function(index,value){ if(minHeight > value){ minHeight = value; minIndex = index; } }); // 5-5 当剩下的item排在最小列下面的时候,要在数组中,跟新这个最小列的高度 heightArr[minIndex] += $(ele).height() + gap_t; // 5-4 排列剩下的行数,下面的item放到上一行最小高度的下面,依次列推 // 设定定位的top值, 10 是上下的间距 var top = minHeight + gap_t; // 设定定位的left值,即高度最小列的索引乘以item的宽度加上间隙 var left = minIndex * (width + gap); $(ele).css({ top: top, left: left }); } // 6-设置加载按钮的位置,只须要将items设置一个高度便可 // 加载按钮的位置应该在heightArr数组里最大高度值的哪个item的下面 var maxHeight = heightArr[0]; $.each(heightArr,function(index,value){ maxHeight = maxHeight > value ? maxHeight : value; }); // 设置items的高度 this指的是每个item $(this).parent().height(maxHeight); }) } })()