学习Js(1)-使用Jquery实现滑动切换效果
1.前言杂谈:
对于Javascript 是从大二就开始接触了,那个时候刚开始接触到web开发。在公司实习期间,由于什么都不会,带我师兄就让我在百度传课上看了一周的传智播客的教学视频,这才有点底子,可以写写正则,做表单验证什么的。到现在刚参加工作的时候,一直不太想从事前端方面的工作,觉得这个应该由公司前端来完成,我是用C#的,让我能专注的写后台就好。
但现实比较那啥,领导要求啊,没办法,只能写了。在接触了一段时间后,也着实加深了自己对整个web开发的理解,从HTML到CSS,再到JS,虽然简单,上手容易,但这是针对学习门槛上的。任何一个需要多人参与才能完成的网站项目,都需要对这三门语言进行深入理解才行。如:只有理解CSS的样式继承层次,对HTML代码结构做好规划,才能够良性的对网站中的页面进行增添删除,不至于显得过于臃肿,也不会造成修改了某局部的样式之后,造成网站中其余页面错位等情况。
2.需求说明:
网站首页的广告位,要增添左右滑动效果;
方便以后对广告位进行扩展;
方便移植到其它需要滑动的区域中。
3.效果展示图:
4.重要代码展示及说明:
/*HTML代码结构*/
<body>
<div class="cooperation">
<div class="ico" >/*图标*/
<span id="icoL" ></span>
<span id="icoR" ></span>
</div>
<!--网页中的展示区域,这里注意style中的三个属性是必须的,如果滑动效果出现了弹跳或是不流畅等现象,可以对width属性进行微调-->
<ul class="img_display" style="overflow:hidden;white-space:nowrap;width: 1175px;" >
<li ><img src="1.png"></li>
<li ><img src="2.png"></li>
<li ><img src="3.png"></li>
<li ><img src="4.png"></li>
</ul>
<!--这里是隐藏区域,用来存放未展示出来的图片-->
<!--这里有个问题就是,每次页面加载的时候,隐藏区域的图片未被展示出来,但仍然请求了服务器的资源,这样不太好,但一时也没想到好的方法来存储隐藏区域的信息-->
<ul class="img_hidden" style="display:none;">
<li><img src="5.png"></li>
<li ><img src="6.png"></li>
<li ><img src="7.png"></li>
<li ><img src="8.png"></li>
</ul>
<div class="clear"></div>
</div>
</body>
下面是JS的代码展示:
这里主要使用了Jquery中的animate函数。简单来说这个函数是在指定时间内,将指定的元素逐渐移动到某一位置。animate用法参考
需要注意的是,指定函数位置时可以使用left,right,top,bottom,也可以使用marginLeft,marginTop等,区别在于前者需要HTML元素本身的position设置成为absolute即绝对定位,后者则没什么要求,都可以使用。
这里其实涉及到CSS定位的一个层次问题,笔者在这方面没有什么了解,就不过多解释了。
<script src="jquery-1.10.2.min.js"></script>
<script type="text/javascript" charset="utf-8">
$("#icoL").bind("click",function(){
MoveLeft(".img_display",4,"li",".img_hidden");
});
$("#icoR").bind("click",function(){
MoveRight(".img_display",4,"li",".img_hidden");
});
//往左滑动
//displayRegion 显示区域
//displayNum 显示区域中,显示元素个数
//elementName 显示元素标识
//HiddenRegion 隐藏区域
function MoveLeft(displayRegion, displayNum, elementName, HiddenRegion) {
//防止重复点击
if ($(displayRegion + " " + elementName).length >= displayNum + 1) {
return;
}
//算滑动距离
var width = parseInt($($(displayRegion)[0]).css("width"));
var marginLeft = 0;
$(displayRegion + " " + elementName).each(function (index) {
if (index > 0) {
//除去displayRegion中第一个元素的marginLeft,因为滑动是以第一个元素本身的左边为基准开始滑动的。
marginLeft += parseInt($(this).css("marginLeft"));
}
});
//原始滑动距离
var distance = (width - marginLeft) / displayNum;
//由于在滑动结束时,会移除滑动到屏幕之外的元素,所以得考虑元素移除后,如何恢复原始的布局;
//令滑动前,displayRegion中第一个元素的marginLeft为a,第二个元素的为b;
//若a==0,滑动距离应加上b;若a<>0,则无需加上b
if (parseInt($($(displayRegion + " " + elementName)[0]).css("marginLeft")) == 0) {
distance += parseInt($($(displayRegion + " " + elementName)[1]).css("marginLeft"));
}
//从HiddenRegion中取出第一个元素,填补到displayRegion得末尾
var displayElem = $(HiddenRegion + " " + elementName + ":first")[0];
$(displayRegion).append(displayElem.outerHTML);
$(displayElem).detach();
var hiddenElem = $(displayRegion + " " + elementName + ":first")[0];
$(hiddenElem).animate({ marginLeft: 0 - distance }, 1000, function () {
//滑动结束,移除滑出屏幕外的元素,填补到HiddenRegion得末尾,并除去滑动造成的marginLeft的改变
$(HiddenRegion).append(hiddenElem.outerHTML);
$(hiddenElem).detach();
$(HiddenRegion + " " + elementName + ":last").removeAttr("style");
});
}
//往右滑动
//displayRegion 显示区域
//displayNum 显示区域中,显示元素个数
//elementName 显示元素标识
//HiddenRegion 隐藏区域
function MoveRight(displayRegion, displayNum, elementName, HiddenRegion) {
if ($(displayRegion + " " + elementName).length >= displayNum + 1) {
return;
}
//算滑动距离
var slideDistance = parseInt($($(displayRegion + " " + elementName)[0]).css("marginLeft"));
//算元素的隐藏距离,即滑动前应该在displayRegion中的那里加上新增的元素
var hiddenDistance = 0 - parseInt($(displayRegion + " " + elementName)[0].offsetWidth);
if (parseInt($($(displayRegion + " " + elementName)[0]).css("marginLeft")) == 0) {
hiddenDistance -= parseInt($($(displayRegion + " " + elementName)[1]).css("marginLeft"));
}
var displayElem = $(HiddenRegion + " " + elementName + ":last")[0];
$(displayElem).attr("style", "margin-left:" + hiddenDistance + "px");
$(displayRegion).prepend(displayElem.outerHTML);
$(displayElem).detach();
$($(displayRegion + " " + elementName + ":first")[0]).animate({ marginLeft: slideDistance }, 1000, function () {
$(HiddenRegion).prepend($(displayRegion + " " + elementName + ":last")[0].outerHTML);
$($(displayRegion + " " + elementName + ":last")[0]).detach();
$(displayRegion + " " + elementName + ":first").removeAttr("style");
});
}
</script>
示例下载1
如果有更好的实现方法,请在下方法留言。
5.新需求说明:、
不改动原有的滑动效果;
网站首页的广告位不够用,需要按地区进行分类;
当某一地区广告位不足时,可以进行循环滑动;
全国地区类别中,可以通过滑动浏览到所有的公司,公司按加入时间降序排列。
方便在不同地区里新增广告位;
方便移植到其它需要滑动的区域中。
6.效果展示图:
7.主要代码说明:
其实相较于刚开始的滑动效果,这里只是新增了对全国地区和广告位不足的处理,原始的滑动效果和HTML结构并没有变化。仍旧是需要一个显示区域和一个隐藏区域。
主要的HTML代码如下:
<body>
<ul class="company_city">
<li class="city on" city_abbr="QuanGuo">全国</li>
<li class="city" city_abbr="HB">华北</li>
<li class="city" city_abbr="HD">华东</li>
<li><a href="" target="_self">全部公司 </a></li>
</ul>
<div class="ico" >
<span id="icoL" ></span>
<span id="icoR" ></span>
</div>
<div class="cooperation" >
<!---全国 可通过滑动查看所有公司 -->
<ul class="img_display_QuanGuo" style="overflow:hidden;white-space:nowrap;width: 1175px;" >
<li sortNum="4"><img src="4.png" ></li>
<li sortNum="3"><img src="3.png" ></li>
<li sortNum="2"><img src="2.png" ></li>
<li sortNum="1"><img src="1.png" ></li>
</ul>
<ul class="img_hidden_QuanGuo" style="display:none;">
</ul>
<!-- 广告位不够用时,进行循环滑动-->
<ul class="img_display_HB" style="overflow:hidden;white-space:nowrap;width: 1175px;display:none;" >
<li sortNum="4"><img src="4.png" ></li>
<li sortNum="3"><img src="3.png" ></li>
<li sortNum="2"><img src="2.png" ></li>
<li sortNum="1"><img src="1.png" ></li>
</ul>
<ul class="img_hidden_HB" style="display:none;">
</ul>
<ul class="img_display_HD" style="overflow:hidden;white-space:nowrap;width: 1175px;display:none;" >
<li sortNum="4"><img src="4.png" ></li>
<li sortNum="3"><img src="3.png" ></li>
<li sortNum="2"><img src="2.png" ></li>
<li sortNum="1"><img src="1.png" ></li>
</ul>
<ul class="img_hidden_HD" style="display:none;">
<li sortNum="8" ><img src="8.png" ></li>
<li sortNum="7" ><img src="7.png" ></li>
<li sortNum="6" ><img src="6.png" ></li>
<li sortNum="5" ><img src="5.png" ></li>
</ul>
<div class="clear"></div>
</div>
</body>
这里新增了两点处理,一个是判断广告位是否足够,即判断相应地区的隐藏区域中是否有元素存在;另一个是增加了对全国地区的处理。
先说判断广告位的问题,如果隐藏区域中没有元素存在,那么在进行滑动之前,先要往隐藏区域中填充元素,怎么填充视往左往右而定;在滑动完成之后要清空隐藏区域,回复到原始状态,以进行下一次滑动。
再说对全国地区的处理:在全国 这个选项被选中的情况下,用户可以通过左右滑动看到所有的公司,这些公司按照一定规则排序,这里的排序规则是给每个元素新增了一个sortNum属性,sortNum越大排的就越前。
从HTML代码中可以看到,在img_display_QuanGuo中有四个元素,这是为了主页显示效果,而提前写在页面里面的;而在img_hidden_QuanGuo中是没有元素的,这就意味着每次滑动前,都要动态的新增元素到这个区域中;
新增元素的规则是这样的:
用户点击了向左滑动的按钮;
JS会先获取最左边元素的sortNum;
如果sortNum是1,即最小的,那么需要找到所有展示元素中sortNum最大的元素,并添加到隐藏区域中;
如果sortNum大于1,那么需要找到比sortNum小,且离sortNum最近的一个元素,并把该元素添加到隐藏区域中;
进行滑动;
滑动完成时,将隐藏区域清空,回复到原始状态。
用户点击了向右滑动的按钮;
JS会先获取最右边元素的sortNum;
遍历所有展示,找到比sortNum大,且离sortNum最近的一个元素,并把该元素添加到隐藏区域中;
如果找不到,则认为最右边元素的sortNum是最大的,此时要进行循环滑动了,将sortNum=1的元素添加到隐藏区域中;
进行滑动;
滑动完成时,将隐藏区域清空,回复到原始状态。
点这里下载代码
主要的JS代码如下:
$(function () {
$(".company_city .city").each(function () {
var abbr = $(this).attr("city_abbr");
$(this).bind("click", function () {
//切换不同地区的公司
$(".cooperation").children().each(function (index, element) {
$(element).css("display", "none");
});
$(".img_display_" + abbr).css("display", "block");
//调整显示字体
$(".company_city .city").each(function () {
$(this).removeClass("on");
});
$(this).addClass("on");
//公司左右滑动
$("#icoL").unbind("click");
$("#icoR").unbind("click");
$("#icoL").bind("click", function () {
MoveRight(".img_display_" + abbr, 4, "li", ".img_hidden_" + abbr);
});
$("#icoR").bind("click", function () {
MoveLeft(".img_display_" + abbr, 4, "li", ".img_hidden_" + abbr);
});
});
});
//点击 全国
$(".company_city .city")[0].click();
});
//往左滑动
//displayRegion 显示区域
//displayNum 显示区域中,显示元素个数
//elementName 显示元素标识
//HiddenRegion 隐藏区域
function MoveLeft(displayRegion, displayNum, elementName, HiddenRegion) {
//防止重复点击
if ($(displayRegion + " " + elementName).length >= displayNum + 1) {
return;
}
//若是全国地区,则可以滑动看到所有公司(按时间降序排序,越新排越前;即SortNum越大排越前),需要进行处理
var isQuanGuo = false;
if (displayRegion.indexOf("QuanGuo") > 0) {
isQuanGuo = true;
}
if (isQuanGuo == true) {
var sortNum = parseInt($($(displayRegion + " " + elementName + ":last")[0]).attr("SortNum"));
//循环、依次递减的查找比sortNum小的元素。
while ($(HiddenRegion + " " + elementName).length <= 0 && sortNum > 1) {
$(displayRegion).parent().find(elementName).each(function () {
if (parseInt($(this).attr("SortNum")) == (sortNum - 1)) {
$(HiddenRegion).prepend(this.outerHTML);
return false;
}
});
if ($(HiddenRegion + " " + elementName).length <= 0) {
sortNum--;
}
}
//为循环滑动,此时要查找SortNum最大的元素
if (sortNum == 1) {
var maxNum = parseInt($($(displayRegion).parent().find(elementName + ":first")[0]).attr("SortNum"));
var maxIndex = 0;
$(displayRegion).parent().find(elementName).each(function (index,element) {
if(maxNum<parseInt($(this).attr("SortNum"))){
maxNum = parseInt($(this).attr("SortNum"));
maxIndex = index;
}
});
$(HiddenRegion).prepend($(displayRegion).parent().find(elementName)[maxIndex].outerHTML);
}
}
//判断元素总数是否等于displayNum,若是,则需处理
var isEelementLack = false;
if ($(HiddenRegion + " " + elementName).length <= 0) {
isEelementLack = true;
}
if (isEelementLack == true) {
$(HiddenRegion).prepend($(displayRegion + " " + elementName)[0].outerHTML);
}
//算滑动距离
var width = parseInt($($(displayRegion)[0]).css("width"));
var marginLeft = 0;
$(displayRegion + " " + elementName).each(function (index) {
if (index > 0) {
//除去displayRegion中第一个元素的marginLeft,因为滑动是以第一个元素本身的左边为基准开始滑动的。
marginLeft += parseInt($(this).css("marginLeft"));
}
});
//原始滑动距离
var distance = (width - marginLeft) / displayNum;
//由于在滑动结束时,会移除滑动到屏幕之外的元素,所以得考虑元素移除后,如何恢复原始的布局;
//令滑动前,displayRegion中第一个元素的marginLeft为a,第二个元素的为b;
//若a==0,滑动距离应加上b;若a<>0,则无需加上b
if (parseInt($($(displayRegion + " " + elementName)[0]).css("marginLeft")) == 0) {
distance += parseInt($($(displayRegion + " " + elementName)[1]).css("marginLeft"));
}
//从HiddenRegion中取出第一个元素,填补到displayRegion得末尾
var displayElem = $(HiddenRegion + " " + elementName + ":first")[0];
$(displayRegion).append(displayElem.outerHTML);
$(displayElem).detach();
var hiddenElem = $(displayRegion + " " + elementName + ":first")[0];
$(hiddenElem).animate({ marginLeft: 0 - distance }, 1000, function () {
//滑动结束,移除滑出屏幕外的元素,填补到HiddenRegion的末尾,并除去滑动造成的marginLeft的改变
$(HiddenRegion).append(hiddenElem.outerHTML);
$(hiddenElem).detach();
$(HiddenRegion + " " + elementName + ":last").removeAttr("style");
//清空HiddenRegion,保证元素不够的情况下也可以循环滑动;回到初始状态
if (isEelementLack == true || isQuanGuo == true) {
$(HiddenRegion).empty();
}
});
}
//往右滑动
//displayRegion 显示区域
//displayNum 显示区域中,显示元素个数
//elementName 显示元素标识
//HiddenRegion 隐藏区域
function MoveRight(displayRegion, displayNum, elementName, HiddenRegion) {
if ($(displayRegion + " " + elementName).length >= displayNum + 1) {
return;
}
//若是全国地区,则可以滑动看到所有公司(按时间降序排序,越新排越前;即SortNum越大排越前),需要进行处理
var isQuanGuo = false;
if (displayRegion.indexOf("QuanGuo") > 0) {
isQuanGuo = true;
}
if (isQuanGuo == true) {
var sortNum = parseInt($($(displayRegion + " " + elementName + ":first")[0]).attr("SortNum"));
//循环、一次递增的查找比sortNum大的元素
while ($(HiddenRegion + " " + elementName).length <= 0 && sortNum <= $(displayRegion).parent().find(elementName).length) {
$(displayRegion).parent().find(elementName).each(function () {
if (parseInt($(this).attr("SortNum")) == (sortNum + 1)) {
$(HiddenRegion).prepend(this.outerHTML);
return false;
}
});
if ($(HiddenRegion + " " + elementName).length <= 0) {
sortNum++;
}
}
//为循环滑动,此时要查找SortNum为1的元素
if ($(HiddenRegion + " " + elementName).length <= 0) {
$(displayRegion).parent().find(elementName).each(function () {
if (parseInt($(this).attr("SortNum")) == 1) {
$(HiddenRegion).prepend(this.outerHTML);
return false;
}
});
}
}
//判断元素总数是否等于displayNum,若是,则需处理
var isEelementLack = false;
if ($(HiddenRegion + " " + elementName).length <= 0) {
isEelementLack = true;
}
if (isEelementLack == true) {
$(HiddenRegion).prepend($(displayRegion + " " + elementName+":last")[0].outerHTML);
}
//算滑动距离
var slideDistance = parseInt($($(displayRegion + " " + elementName)[0]).css("marginLeft"));
//算元素的隐藏距离,即滑动前应该在displayRegion中的那里加上新增的元素
var hiddenDistance = 0 - parseInt($(displayRegion + " " + elementName)[0].offsetWidth);
//这里要注意hiddenDistance是负数,为了让右边新增的元素可以与原来的DIV中的第一个元素保持间距,需要做处理
if (parseInt($($(displayRegion + " " + elementName)[0]).css("marginLeft")) == 0) {
hiddenDistance -= parseInt($($(displayRegion + " " + elementName)[1]).css("marginLeft"));
}
//在显示区域右边新增元素
var displayElem = $(HiddenRegion + " " + elementName + ":last")[0];
$(displayElem).attr("style", "margin-left:" + hiddenDistance + "px");
$(displayRegion).prepend(displayElem.outerHTML);
$(displayElem).detach();
$($(displayRegion + " " + elementName + ":first")[0]).animate({ marginLeft: slideDistance }, 1000, function () {
//滑动结束,移除滑出屏幕外的元素,填补到HiddenRegion的头部,并除去滑动造成的marginLeft的改变
$(HiddenRegion).prepend($(displayRegion + " " + elementName + ":last")[0].outerHTML);
$($(displayRegion + " " + elementName + ":last")[0]).detach();
$(displayRegion + " " + elementName + ":first").removeAttr("style");
//清空HiddenRegion,保证元素不够的情况下也可以循环滑动
if (isEelementLack == true || isQuanGuo==true) {
$(HiddenRegion).empty();
}
});
}