4.2 函数节流
所谓的函数节流,就是我们希望一些函数不要连续的触发。甚至于规定,触发这个函数的最小间隔是多少时间。
这个就是函数节流。
方法1:
经典的函数节流模型:
var lock = true; input.onclick = function(){ if(!lock) return; lock = false; setTimeout(function(){ lock = true; },1000); }
方法2:
改变我们的运动框架,在运动框架里面加上一个逻辑:运动开始了,就给elem加上一个属性isanimated,表示是否在运动,改为true。然后运动停止之后,停表之后,把elem.isanimated设为false
.onclick = function(){ if(m_unit.isanimate) return; //如果点击按钮的时候运动机构在动,那么return }
是一个a标签,但是我们不希望点击之后有任何默认的事情,默认事情通常是刷新当前页:
<a href="javascript:;" class="leftBtn" id="leftBtn"></a>
中级
是一个a标签,但是我们不希望点击之后有任何默认的事情,默认事情通常是刷新当前页:
<a href="javascript:;" class="leftBtn" id="leftBtn"></a>
打点标签后得到的数组不能用数组pop push。。。。等方法,得转换一下子
****!
五、$()函数
5.1 jQuery对象不是原生JS对象
$()函数,是招牌功能,能够根据CSS选择元素。
比如:
$("#box")
选择页面上id为box的盒子。
注意,选择出来的东西,是一个类数组对象,是jQuery自己的对象,这个jQuery对象后面不能跟着原生JS的语法:
$("#box").style.backgroundColor = "red";
因为.style.backgroundColor是原生JS语法,$()原则的对象是jQuery对象,不能跟着原生。
所以,如果想把jQuery对象,转为原生JS对象,要加[0]就行了:
$("#box")[0].style.backgroundColor = "red";
这里我们补充一点,jQuery选择的如果是很多元素,那么[0]转化的是一个元素。[1]、[2]、[3]……
$等价于jQuery
jQuery("#box") 等价于 $("#box")
Siblings()
查找每个 p 元素的所有类名为 "selected" 的所有同胞元素:
$("p").siblings(".selected")//可以加选择器
5.2 引号问题
$("选择器")
注意引号不能丢!!在jQuery世界中,只有三个东西不能加引号,其他必须加引号:
$(this) $(document) $(window)
上述的三个东西,不能有引号,干吗用的,后面说。5.3 支持的选择器
jQuery支持所有CSS2.1的选择器:
$("p") $(".box") $("#box") $("#box ul li") $("li.special") $("ol , ul") $("*")
也支持部分CSS3的选择器,我们CSS3的选择器在CSS3课程介绍,所以也不讲了。
5.4 筛选器
这些都是关于序号的:
$("p") 所有的p $("p:first") 第一个p $("p:last") 最后一个p $("p:eq(3)") 下标为3的p $("p:lt(3)") 下标小于3的p $("p:gt(3)") 下标大于3的p $("p:odd") 下标是奇数的p $("p:even") 下标是偶数的p
特别的,eq可以单独提炼为方法,可以连续打点:
$("p").eq(3).animate({"width":400},1000);
等价于
$("p:eq(3)").animate({"width":400},1000);
提炼出来的好处是,可以用变量
var a = 3; $("p").eq(a).animate({"width":400},1000);
!!!!
别的不行了,但是可以切割下面这样
********$("p:lt("+a+")")
CSS函数
Css可以连续打点
css函数可以读样式,可以设样式。
读样式,可以读取计算后样式,写一个参数,是不是驼峰,无所谓,但是必须加引号:
$("p:first").css("background-color"); $("p:first").css("backgroundColor");
设置样式,设置样式,有两种语法,如果你只想设置一个样式,逗号隔开k和v:
$("p:odd").css("backgroundColor","blue");
如果想设置很多样式,就写JSON:
$("p:odd").css(JSON);
所有的数值,不需要单位:
$("p:lt(4)").css({ "width" : 20, "height" : 20, "backgroundColor" : "red" })
特别的,还支持+=写法:
$("p:eq(5)").css("width","+=20px");
七、animate函数
!!!有好多东西animate不能完成
$("p").animate({"left":1000},2000,function(){ $(thisut).css("background-color","red"); });
我们骄傲的告诉大家,我们封装的animate语法基本和jQuery一样,只不过jQuery是对象打点:
$("选择器").animate(终点JSON,动画时间,回调函数);
有没有缓冲呢,有,jQuery需要插件来完成,我们日后说。
jQuery默认不是匀速,是easeInOut
和我们封装的框架不一样,jQuery默认有一个处理机制,叫做动画排队。当一个元素接收到了两个animate命令之后,后面的animate会排队:
$("p").animate({"left":1000},2000); $("p").animate({"top":400},2000);
先2000毫秒横着跑,然后2000毫秒竖着跑。动画总时长4000。
如果想让元素斜着跑,就是同时变化left和top,就写在同一个JSON里面:
$("p").animate({"left":1000,"top":400},2000);
不同的元素,不排队,是同时的。
你要记住这个事情,background-color是不能渐变的。页面上如果想要使用background-color的过渡效果,慢慢从红色变为蓝色,必须使用css3。
jQuery中提供了非常牛逼的动画队列功能,相同元素的animate()方法会累积
*不同元素的动画是同时进行的
八、事件监听
$(".box1").click(function(){ //点击box1之后做的事情 });
事件名一律不写on。特别的,鼠标进入改成了mouseenter,鼠标离开改为了mouseleave。
Onclick 单击
Onmouseover 鼠标进入mouseenter
Onmouseout 鼠标离开mouseleave
Ondblclivk 双击
Onfouse 得到焦点
Onblue 失去焦点
Onmousedown 鼠标按下
Onmouseup 鼠标按键抬起
2.2 index()方法
返回这个元素在亲兄弟中的排名,无视选择器怎么选。
$(this).index()是一个很常见的写法,表示触发这个事件的元素,在自己亲兄弟中的排名:
2.3 each()
$("p").each(function(i){ $(this).animate({"width":50 * i},1000); });
Children:自己的儿子中的啥啥啥
2.4 size()方法和length属性
jQuery 对象中元素的个数。
前面$()的元素页面上一共有几个,length、size()返回的都是同一个数值,就是个数。
$("p").length $("p").size()
2.5 get()方法
get()方法和eq()方法基本一致,都仰赖$()的序列。
eq()返回的是jQuery对象,而get()返回的是原生JS对象。jQuery对象后面要跟着jQuery方法,原生对象后面要跟着原生属性、方法:
Html改变的两种方法!!!!
原生里面的innerHTML加倍增加
***.innerHTML+=***.innerHTML
jQuary中
$(“”).html($(“”).html()+$(“”).html());
$(“”).html()~!!!! html是个方法函数必须加小括号调用!!!!!
$("p").eq(2).html("哈哈哈哈哈哈");
等价于:
$("p").get(2).innerHTML = "哈哈哈哈哈哈";
等价于:
$("p").eq(2)[0].innerHTML = "哈哈哈哈哈哈";
3.1 内置show()、hide()、toggle()方法
show()显示、hide()隐藏、toggle()切换
$("div").show(); //让一个本身是play:none;元素显示 $("div").hide(); //隐藏元素play:none; $("div").toggle(); //切换显示状态。 //自行带有判断,如果可见,就隐藏;否则显示。
$("div").show([时间],[回调函数]);
特别的,如果show()、hide()、toggle()里面有数值,将变为动画:
[]表示这个参数可选。
3.2 slideDown()、slideUp()、slideToggle()方法
slideDown : 下滑展开//如果定义的对象是position定位top的话那么向下展开,bottom的话那么向上展开!!!!!!!
slideUp:上滑收回
slideToggle : 滑动切换
$("div").slideDown();
slideDown()的起点一定是play:none换句话说,只有play:none的元素,才能够调用slideDown()
相反的,slideUp()的终点就是play:none;
同样的,slideDown、slideUp、slideToggle里面可以写动画时间、回调函数。
默认时间为1000
*****
如果不加>号那么就是选中的后代
加了就是选中的儿子
注意水平菜单的html结构:
<div class="nav"> <ul> <li> <a href=""></a> <div class="dropdown"> <div class="inner"> </div> </div> </li> </ul> </div>
3.3 fadeIn()、fadeOut()、fadeTo()、fadeToggle()方法
fadeIn()淡入
fadeOut()淡出
fadeTo() 淡到那个数
fadeToggle() 淡出入切换
fadeIn()的起点是play:none;换句话说,只有play:none的元素,才能执行fadeIn()
$("div").fadeIn(5000);
动画机理:
一个play:none的元素,瞬间可见,然后瞬间变为opacity:0,往自己的opacity上变。如果没有设置opacity,就往1变。
fadeTo有三个参数,第一个参数是动画的时间,第二个参数是要变到的透明度,第三个参数是回调函数。
$("div").fadeTo(1000,0.3);
fadeTo的起点不一定是play:none;
3.4 stop()
stop()挺有意思的:
停止当前的animate动画,但是不清除队列,立即执行后面的animate动画:
$("div").stop(); //等价于$(“div”).stop(false,false);
停止当前的animate动画,并且清除队列,盒子留在了此时的位置:
$("div").stop(true); //等价于$(“div”).stop(true,false);
瞬间完成当前的animate动画,并且清除队列:
$("div").stop(true,true);
瞬间完成当前的animate动画,但是不清楚队列,立即执行后面的动画:
$("div").stop(false,true);
公式:
stop(是否清除队列,是否瞬间完成当前动画)
如果没有写true或者false,默认是false
改变图片路径
$().attr(“读取的属性”,”变更的属性”);
得到自己定义的属性
3.6 delay()
delay延迟,可以使用连续打点,必须放在运动语句之前。
$("div").delay(1000).animate({"left":500},1000); $("div").delay(1000).slideUp(); $("div").delay(1000).hide(1); //必须写1,写1了就是运动
小窍门,让所有的img元素,都延迟不同的时间入场:
$("img").each(function(i){ //attr就表示得到标签内的属性 $(this).delay(i * 1000).fadeIn(1000);
});
3.7 is(":animated")
is()方法表示身份探测,返回true、false。
比如,判断点击的这个p是不是有t这个类:
$("p").click(function(){ alert( $(this).is(".t") ); });
is里面可以写筛选器:is(:visible)//可见的
判断点击的这个p是不是序号是奇数:
$(this).is("p:odd")
判断点击的这个p是不是序号小于3:
$(this).is("p:lt(3)")
还可以写
is(":animated")
判断这个元素是否在运动中。判断是否在运动中,可以防止动画的积累:
if($(this).children(".dropbox").is(":animated")){ return; }
4.2 原生JS中的节点关系-childNodes
任何节点都有childNodes属性,是一个类数组对象,存放着所有自己的儿子。
注意,这里有重大兼容性问题:
结构
<div id="box"> <p></p> </div>
Chrome、IE9、IE10……高级浏览器,认为:
box.childNodes[0].nodeType //3
高级浏览器认为box的大儿子是文本节点。当然是空文本。
IE6、7、8认为:
box.childNodes[0].nodeType //1
IE6、7、8认为box的大儿子是p。
所以为了没有兼容问题,需要遍历节点的时候,HTML结构就不能有空格。
面试题:
<div id="box"> <p></p> <p></p> <p></p> <p></p> </div>
document.getElementById(“box”).childNodes.length; //高级浏览器9,低级浏览器4
怎么解决这个差异呢?放弃原有的数组,重新遍历儿子数组,把所有nodeType为1的元素组成一个新的数组
var childs = []; for(var i = 0 ; i < box.childNodes.length ; i++){ if(box.childNodes[i].nodeType == 1){ childs.push(box.childNodes[i]); } } childs[1].style.background = "red";
4.3 原生JS中的节点关系-parentNode
注意childNodes儿子可以有很多 ,parendNode父亲只能有1个
某个元素.parentNode
4.4 previousSibling、nextSibling
上一个同胞兄弟,下一个同胞兄弟。
需要注意的是,天大的浏览器兼容问题出现了:
<div id="box"> <p>AAA</p> <p>BBB</p> <p>CCC</p> <p>DDD</p> </div>
ps[2].previousSibling //低级浏览器就是BBB那个p,高级浏览器是空文本节点
onchange事件
addClass removeClass hasClass 增加class移除class 是否有class类名
2.2 jQuery中的节点关系
● children()方法
所有亲儿子节点。就是儿子,孙子不在children()里面。
让box的所有儿子变红:
$("#box").children().css("background-color","red");
儿子有很多,我们可以用选择器来表示怎么样的儿子:
$("#box").children("h3").css("background-color","red");
还可以用筛选器:
$("#box").children(":odd").css("background-color","red");
jQuey屏蔽掉了浏览器兼容问题,不存在空文本节点也是儿子了,事实上children()返回的只能是节点,所有的文本都不算做是儿子了。
● find()
所有后代元素。和children()不一样,children()返回的是自己的亲儿子元素列表,而find()返回的是自己的后代所有元素的列表。
$("#box").find("p").css("background-color","red");
注意,和children()方法不一样,find()方法里面,必须写参数,表示后代的谁?
说白了find是寻找的意思,就是你要在后代寻找谁。
● parent()
亲爸爸。任何元素都只有一个亲爸爸。
$("p").parent().css("background-color","red");
● parents()
这个元素的所有的祖先节点。
● siblings()
亲兄弟
$(".xiaoming").siblings().css("background-color","red");
同样的,jQuery只返回节点元素,对于文本、注释都不视为兄弟。
可以加选择器、筛选器:
$(".xiaoming").siblings(":odd").css("background-color","red");
排他,妈妈再也不用担心我写for循环了:
$(this).addClass("cur").siblings().removeClass("cur");
我加cur,我的兄弟们去cur。///常用到
● prev()、next()、prevAll()、nextAll()
前一个兄弟、后一个兄弟、前所有兄弟、后所有兄弟。
总结:感恩!jQuery屏蔽了所有的不兼容,只选择nodeType=1的元素,不选择文本、注释等等。
三、节点操作
3.1 原生JavaScript节点操作
3.1.1 createElement()和appendChild()
var ul = document.getElementsByTagName("ul")[0]; //创建一个li标签,用变量oLi来表示。创建出来的节点不是任何节点的儿子, //也就是说没有在DOM树上, var oLi = document.createElement("li"); oLi.innerHTML = "DDDD"; //改变这个节点里面的内容 //把新创建的节点,追加到DOM树上 ul.appendChild(oLi);
创建节点的API:
document.createElement()
create创建,Element元素。接收一个参数,就是创建的标签是什么。
追加节点的API:
创建出来的节点不在DOM树上,所以就应该用appendChild()来添加到DOM树上:
父亲.appendChild(新儿子);
appendChild()一般来说就是用来追加新创建的节点。如果你试图把页面上已经有的节点,appendChild()到别的地方,那么这个节点将移动。也就是说,同一个节点不可能在页面上的两个地方出现。
比如结构:
<div id="box1"> <p id="xiaoming">我是小明</p> </div> <div id="box2"> </div>
语句:
box2.appendChild(xiaoming);
将使xiaoming移动位置,从box1里面移动到box2里面。
事实上,工作的时候很少使用createElement。因为innerHTML足够好用,innerHTML也可以用来创建节点,甚至效率比createElement还高。
box.innerHTML = "<ul><li>哈哈哈</li><li>做顿饭</li></ul>";
3.1.2 insertBefore
我们刚才说的appendChild是把新节点在父亲的所有儿子后添加,也就是说添加的节点就是父亲的最后一个儿子。
我们可以在任意一个位置添加节点。
父亲.insertBefore(新儿子,原有标杆儿子);
会在原有标杆儿子之前插入。
如果想每次添加都在开头添加,那么就是:
ul.insertBefore(oLi, lis[0]);
lis这个变量是动态的,这次添加的li,下回就是lis[0]
3.1.3 removeChild()
父亲.removeChild(儿子);
如果要自杀,也要找到爸爸
this.parentNode.removeChild(this);
3.1.4 replaceChild()
替换节点
父亲.replaceChild(新儿子, 老儿子);
3.1.5 cloneNode()
克隆节点,参数true表示深复制,节点里面的所有内容一同复制。
复制之后的节点是个孤儿节点,所以也需要使用appendChild、inserBefore、replaceChild来添加上DOM树。
ul.appendChild(lis[0].cloneNode(true));