前端编程提高之旅(二)—-网站常见特效的jquery实现
最后更新于:2022-04-01 09:36:51
最好的编程语言是逻辑,前端各种交互特效的实现多可以用jquery实现,特效可以纷飞,内在逻辑则基本不变。这一篇文章主要介绍jquery实现常见特效背后的逻辑。
**1.通过类名获取元素集合**
**首先来看一个js原生代码不支持的方法,通过类来获取元素集合。**
~~~
document.getElementsByClassName=function(classname){
var retnode = [];
var myclass = new RegExp('\\b'+classname+'\\b');//匹配类名
var elem = this.getElementsByTagName('*');//得到所有元素
for (var j = 0; j < elem.length; j++)
{
var classes = elem[j].className;
if (myclass.test(classes)){
retnode.push(elem[j]);
}
}
return retnode;
}//通过遍历整个文档元素类名,返回所有指定类名的数组
~~~
**逻辑思路:**
**通过构造一个类名的正则表达式,选取所有标签,并通过正则表达式与所有标签类名属性进行匹配,从而返回一个类名数组,实现通过类名得到元素集合的目标。**
**实现这个方法的同时,也给在不使用jquery的情况下,选取特定序数的元素提供了便利。**
**2.二级联动菜单的构造**
~~~
$("#select1").change( function() { //侦测一级菜单的change事件
var id = $("#select1").val();
if(id == 1){ //通过id判断二级菜单
$.get('index.php', null, function(data){ //get方式传值
$("span").empty(); //清空标签
$("span").append("<select><option>济南</opton><option>青岛 </opton><option>临沂</opton></select>"); //填充对应的二级菜单
});
}else{
$.get('index.php', null, function(data){ //get方式传值
$("span").empty(); //清空标签
$("span").append("<select><option>郑州</opton><option>安阳 </opton><option>洛阳</opton></select>"); //填充对应的二级菜单
});
}
});
~~~
**逻辑思路:**
**根据需要设置联动菜单的元素值被改变的情况,通过ajax方法传空值给自身页面,追加相应的元素,在这里是二级菜单。这里用到了jquery两个方法:change方法和empty方法。**
**change方法在选定标签值改变时,会被触发执行。empty方法则是将标签中html内容清空。**
**3.链接样式和链接内容的显示隐藏**
~~~
$(function(){
$("li").each(function(index){ //遍历用户控制区域
$(this).mouseover(function(){ //获取当前用户选择区域
id = setTimeout(function(){ //使用时间事件函数实现缓动效果 更好的用户体验
$("li.tab").removeClass('tab'); //移除默认的选项按钮的样式
$(this).addClass("tab"); //给当前选项按钮添加样式
$("div.show").removeClass('show'); //移除默认的显示区域的样式
$("#tab1 div:eq("+index+")").addClass('show'); //根据选中的index索引添加样式
},300);
}).mouseout(function(){
clearTimeout(id); //用户鼠标移除时同时移除时间事件
});
});
});//链接对应相应内容的隐藏和显示
~~~
**逻辑思路:**
**这里首先用到$()在其中书写函数,[这里](http://www.jb51.net/article/21660.htm)详细介绍了jquery构造函数的适用范围。通过遍历每个导航链接,当鼠标移上对应元素,首先移除所有默认选项样式,在悬浮元素加上默认选中样式。并移除当前显示样式,设置默认选项对应内容样式为显示状态。**
**这里的亮点在于使用了一个显示默认样式的缓动效果,用户体验更细致。**
**4.“显示更多(more)”功能的实现**
~~~
$(function(){
var $hideObj = $('ul li:gt(5):not(:last)');//选择index大于等于5的li元素,除去最后一个,隐藏掉
$hideObj.hide();
$('.showmore span').click(function(){
if(!$hideObj.is(":visible")){//判断是否可见is方法
$hideObj.show();
$('.showmore span').css("background","url(./images/up.bmp) no-repeat 0 -10");//切换状态更换图片
}else{
$hideObj.hide();
$('.showmore span').css("background","url(./images/down.bmp) no-repeat 0 0")
;//切换状态更换图片
}
});
});//选择一部分隐藏掉,再将部分判断是否显示,显示或者隐藏
~~~
**逻辑思路:**
**这里首先动用了选择器除去最后一个元素所有大于5的li元素选中。通过用户点击事件,判断是否显示或者隐藏,并联动修改被点击的图标。**
**亮点在选择器的掌控恰到好处,用jquery最基本的就要用熟选择器,这样会快速高效操作dom节点。这样也就不难理解css3为什么首要改革的就是选择器了,简化操作流程、正则化及语义化css选择器,使得前端工程师读和写代码更便捷。**
**5.文本域“剩余字数”**
****
~~~
$(document).ready(function(){
var tarea = $("#init");//
tarea.focus(function(){
$("#numtj").fadeIn(200);
}).blur(function(){
$("#numtj").fadeOut("slow");
})//文本域获得焦点和失去焦点剩余字数显示或消失,用到渐入渐出
$("#init").keyup(function() {
var text=$("#init").val();
var counter=text.length;
$("#numtj var").text(110-counter);
});// 按下键盘则实时修改剩余字数
});
~~~
**逻辑思路:**
**逻辑非常简单,获得焦点剩余字数显示,失去焦点剩余字数消失。键盘按起计算还剩字数。**
**这里的亮点在于使用了fadeIn和fadeOut方法实现渐入渐出更加自然,体验更好。focus和blur事件也是针对有输入内容的元素常需处理的事件。keyup事件则与用户输入内容,实时交互有关系。**
**6.鼠标移动到图片放大**
~~~
var ShowImage = function() {
xOffset = 10;
yOffset = 30;
$("#imglist").find("img").hover(function(e) {//给图片对象添加事件及触发函数
$("<img id='imgshow' src='" + this.src + "' />").appendTo("body");//在body上添加图片对象
$("#imgshow")
.css("top", (e.pageY - xOffset) + "px")//定位body显示图片的y坐标 鼠标位置加人为设置偏移量
.css("left", (e.pageX + yOffset) + "px")//定位body显示图
.fadeIn("fast");
},function() {
$("#imgshow").remove();
});
$("#imglist").find("img").mousemove(function(e) {
$("#imgshow").css("top",(e.pageY-xOffset) + "px")
.css("left", (e.pageX + yOffset) + "px");
});
};
~~~
**逻辑思路:**
**这段代码的逻辑非常具有普遍性,e代表鼠标事件,鼠标属性pageX和pageY代表鼠标的坐标位置。整体的思路即是通过鼠标触发悬浮事件,显示或者移除与鼠标位置有一个偏移的图片,并通过设置mousemove事件来实时移动放大图位置。**
**看了以上几个例子我们会发现,事件和选择器是整体交互效果核心。所以这里有必要再精通、再精通。**
**7.图片轮播**
~~~
var t = 0;
var n = 0;
var count;//全局变量沟通函数和click事件内变量
$(document).ready(function(){
count=$("#bannerList a").length;//获取用户控制a标签的总数
$("#bannerList a:not(:first-child)").hide();//除了第一个元素都隐藏
$("#banner li").click(function(){//给存放图片的列表添加单击事件
var i = $(this).text() - 1;//获取Li元素内的值,即1,2,3,4
n = i;//i的值赋值给n
if (i >= count){//判断是否大于a标签的总数
return;
}
var $a = $("#bannerList a").filter(":visible").fadeOut(500);//显示的都隐藏掉
$a.parent().children().eq(i).fadeIn(1000);//根据当前li元素的值显示图片
//$("#banner").css("background","");//显示按钮样式
$(this).toggleClass("show");//当前对象删除或者添加类show
$(this).siblings().removeAttr("class");//当前对象删除类属性
});
//设置定时或消除定时
t = setInterval("showTime()", 3000);//每隔三秒执行一次方法
$("#banner").hover(function(){//给按钮添加鼠标滑过事件
clearInterval(t)},function(){//鼠标滑过停止播放
t = setInterval("showTime()", 3000);//鼠标滑出继续播放
});
})
function showTime()
{
if(n>=(count-1)){
n=0;
}else{
n=++n;
}
$("#banner li").eq(n).trigger('click');//代码触发click事件
}
~~~
**逻辑思路:**
**这段图片轮播的代码,大体可以分为三个模块:初始化模块、单击事件模块、鼠标悬浮模块、自动触发模块。初始化模块意在初始化开始轮播图片序数,单击时间模块意在确定单击事件执行被单击对象显示其他对象隐藏操作,鼠标悬浮模块意在清除或者恢复自动触发模块,以便执行单击操作,自动触发模块用于模拟单击事件。**
**这段代码混乱之处在于设置的i和n都为全局变量,在函数和执行语句中游走。trigger这个事件竟然模拟了单击事件,鼠标悬浮hover用的恰到好处,不会造成与click事件的冲突。**
**8.[选择城市插件](http://www.xiao-a.com/index.php/archives/1113.html)**
~~~
jQuery.fn.selectCity = function(targetObj){
var _self = this;//获取当前对象,使用此插件的选择器内对象
var targetObj = $(targetObj);//根据参数获取对象
this.click(function(){//当前对象触发单击事件
var _top=$(this).offset().top + $(this).outerHeight(true);//获取对象相对顶部真实高度
var _left=$(this).offset().left;//获取对象相对左侧真是高度
targetObj.bgiframe();//调用插件的方法bgiframe()
targetObj.show().css({"position":"absolute","top":_top+"px" ,"left":_left+"px"});//显示定位
});//根据被选对象的位置,将隐藏的显示出来并设置隐藏的下方位置
targetObj.find("#selectItemClose").click(function(){
targetObj.hide();//用户单击关闭按钮隐藏选择区域
});
targetObj.find("#selectSub :checkbox").click(function(){
targetObj.find(":checkbox").attr("checked",false);//将所有的多选框设置为未被选中
$(this).attr("checked",true);
_self.val($(this).val());
targetObj.hide();//设置点击选中,并传递给input对象值,隐藏选中框
});
$(document).click(function(event){
if(event.target.id!=_self.selector.substring(1)){//鼠标在页面单击时隐藏复选框对象
targetObj.hide();
}
});
targetObj.click(function(e){
e.stopPropagation(); //阻止事件的传递
});
return this;
}
~~~
**逻辑思路:**
**页面单击对象时,则设置需要显示的对象到被单击对象的下方。并设置关闭按钮。将所有多选框设置未被选中,以选中特定栏。当鼠标单击页面时,需要显示的对象消失。**
**这里比较新颖的是当鼠标不点击显示区域和单击对象时的处理,才采用了一个target.id的判断达到效果。**
**9.分页插件**
~~~
var page_all = $('.page');//获取所有需要分页显示的区域,全局变量
var user_nav = $('#page_nation');//用户分页操作区域,全局变量,函数内更改也会更改值
function createActionLinks(){//动态生成分页操作区域
user_nav.append('<a href="javascript:void(0)" id="prev">上一页</a>');
for(var i=0;i<$('.page').length;i++){//显示区域的范围内遍历
user_nav.append('<a href="javascript:void(0)" class="numlink">'+(i+1)+'</a>');
}
user_nav.append('<a href="javascript:void(0)" id="next">下一页</a>');
}
function changeAction(page,preBtn,nextBtn){//分页实现函数
$('.page:eq('+page+')').css('display','block');//显示当前分页内容
$('.numlink:eq('+page+')').addClass('current');//当前页按钮高亮显示
var pageSize = parseInt($('.page').length - 1);//获取最大页数
if(page == 0){//显示在第一页时
preBtn.hide();//上一页按钮隐藏
nextBtn.show();//下一页按钮显示
}else if(page==pageSize){//显示在最后一页时
preBtn.show();//上一页按钮隐藏
nextBtn.hide();//下一页按钮显示
}else{
preBtn.show();//上一页按钮显示
nextBtn.show();//下一页按钮显示
}
}
function hideObj(){
page_all.css('display','none');//隐藏所有分页
$('.numlink').removeClass('current');//去除所有分页的样式
}
$(document).ready(function(){
$('.page:eq(0)').css('display','block');//默认显示第一页
createActionLinks();//初始化创建用户操作区域
$('.numlink:eq(0)').addClass('current');//给第一个按钮添加样式
var nextBtn = $('#next');//获取下一页按钮对象
var preBtn = $('#prev');//获取上一页按钮对象
var linkAction = $('.numlink');//获取超级链接对象集合
preBtn.hide();//默认显示第一页并隐藏上一页操作按钮
var page = parseInt($('.numlink').index($('.current')));//返回当前分页值,这一句话很关键
//三种点击动作
nextBtn.click(function(){//给下一页按钮添加单击事件
hideObj();//隐藏全部分页部分
changeAction(page+1,preBtn,nextBtn);//函数每执行一次page的值减1
page = parseInt($('.numlink').index($('.current')));//返回page的值
});
preBtn.click(function(){//给上一页按钮添加单击事件
hideObj();//隐藏全部分页部分
changeAction(page-1,preBtn,nextBtn);//函数每执行一次page的值加1
page = parseInt($('.numlink').index($('.current')));//返回page的值
})
linkAction.click(function(){//给分页页码链接添加单击事件
var that = $(this);//获取当前对象
hideObj();//隐藏全部分页部分
var index = that.index() - 1;//获取当前下标值
changeAction(index,preBtn,nextBtn);//调用分页函数
page = parseInt($('.numlink').index($('.current')));//返回page的值
})
})
~~~
**逻辑思路:**
**分页属于老生长谈了,这里的实现主要从分页按钮生成模块、切换页面模块、隐藏模块、并通过ready后,初始化设置初始状态,对相应按钮加上交互操作即click事件,并调用切换页面模块实现点击切换。类似MVC架构。**
**10.自定义插件注意要点**
~~~
(function($){
$.fn.changeTab = function(options){//插件需要附加到jquery.fn对象上
var defaults = {
FontSize:"50px",
Color:'red',
FontWeight:'bold'
}//设置默认的参数
var options = $.extend(defaults,options);//对参数更新
this.each(function(){
var lis = $(this);//保留this操作
lis.hover(function(){
$(this).css({ "fontSize": options.FontSize, "color": options.Color ,"fontWeight":options.FontWeight});
},function(){
$(this).css({ "fontSize": '', "color": '',"fontWeight":''});
})
})
}
})(jQuery)// 插件内避免使用$ ,插件应返回一个jquery对象 便于链式操作
$(function(){
var options={
FontSize:'16px',
Color:'blue',
FontWeight:'bold'
}//设置个性化参数
$('li').changeTab(options);//引用插件
})
~~~
**逻辑思路:**
**1.插件需要附件到jquery.fn上。**
**2.插件内返回jquery对象便于链式操作。**
**3.设定默认参数,并通过传参调用extend对象对参数更新。**
**以上总结均为项目中常见特效的情形,可以看出来事件和选择器是需要掌握扎实的,一些编程技巧也要学会。其次这篇文章可以作为一个程序库,供使用时查看。**