JQuery知识

284 阅读7分钟

入口函数

加载模式

原生JSJQuery入口函数的加载模式不同

  • 原生JS会等到DOM元素加载完毕,并且图片这些外部资源也加载完毕才会执行。

  • JQuery会等到DOM元素加载完毕,但不会等到图片这些外部资源也加载完毕就会执行。

  • 原生JS如果编写了多个入口函数onload,后写的会覆盖之前的。

  • JQuery如果编写了多个入口函数,后写的不会覆盖之前的。

写法

  1. $(document).ready(function(){
    	alert("第一种入口函数");
    });
    
  2. jQuery(document).ready(function(){
    	alert("第二种入口函数");
    });
    
  3. $(function(){
    	alert("第三种入口函数");
    });
    //写的更少,做的更多
    
  4. jQuery(function(){
    	alert("第四种入口函数");
    });
    

JQuery冲突问题

​ 在使用多个库时,若别的库中含有$符号,则会和JQuery$符号冲突。

解决方案

  1. 释放$的使用权

    jQuery.noConflict();
    //释放之后所有的$都用jQuery代替
    //释放必须写在所有JQuery代码前
    
  2. 自定义一个访问符号

    var myflag=jQuery.noConflict();
    //所有$符号都由myflag代替
    

JQuery的核心函数

$()就表示调用JQuery的核心函数。

  1. 接收一个函数

    $(function(){
    	alert("第三种入口函数");
    });
    
  2. 接收一个字符串

    1. 接收一个字符串选择器

      $(function(){
      var box1=$(".box");
      //CSS 类名选择器
      var box2=$("#box");
      //CSS id选择器
      var box3=$("div");
      //CSS 标签名选择器
      });
      
    2. 接收一个代码片段

      $(function(){
      	var box2=$("#box");
      	var p=$("<p>asd</p>");
      	//会将该代码片段转换为一个对象
      	box2.append(p);
      });
      
  3. 接收一个DOM元素

    $(function(){
    	var box2=document.getElementById('box');
    	console.log(box2);
    	var $box2=$(box2);
    	//会将原生JS对象包装为jQuery对象
    	console.log($box2);
    });
    

JQuery对象

  1. 什么是jQuery对象

    jQuery对象是一个伪数组对象

  2. 什么是伪数组

    0length-1的属性,并且有length属性

JQuery静态方法和实例方法

在原生JS中

  • 静态方法直接附加给类名,并且通过类名调用

  • 实例方法附加给类名的prototype原型对象,通过实例名调用

静态方法each

  • JSforEach实例方法

    //第一个参数:遍历到的元素
    //第二个参数:遍历到的元素索引
    //注意点:
    //	原生的forEach方法只能遍历数组,不能遍历伪数组
    var obj={0:1 ,1:3 ,2:5 ,3:7 ,4:9 ,length:5};
    var arr=[1,3,5,7,9];
    arr.forEach(function(value,index){
    	console.log(value,index);
    });
    obj.forEach(function(value,index){  //会报错
    	console.log(value,index);
    });
    
  • jQuery中的each静态方法

    //与原生JS不同的是,回调函数中的参数
    //     第一个参数为索引
    //     第二个参数为元素
    //该方法可以遍历伪数组
    $(function(){
    	var obj={0:1 ,1:3 ,2:5 ,3:7 ,4:9 ,length:5};
    	var arr=[1,3,5,7,9];
    	$.each(arr,function(index,value){
    		console.log(index,value);
    	});
    	$.each(obj,function(index,value){
    		console.log(index,value);
    	});
    });
    

静态方法map

  • 原生JS中的map实例方法

    //第一个参数:遍历到的元素
    //第二个参数:遍历到的元素索引
    //第三个参数:当前被遍历的数组
    //注意点:
    //	原生的map方法只能遍历数组,不能遍历伪数组
    var obj={0:1 ,1:3 ,2:5 ,3:7 ,4:9 ,length:5};
    var arr=[1,3,5,7,9];
    arr.map(function(value,index,array){
        console.log(value,index,array);	
    });	
    obj.map(function(value,index,array){//会报错
        console.log(value,index,array);	
    });
    
  • jQuery中的map静态方法

    //第一个参数:遍历到的元素索引
    //第二个参数:遍历到的元素
    //jQuery中的map方法可以遍历伪数组
    $(function(){
    	var obj={0:1 ,1:3 ,2:5 ,3:7 ,4:9 ,length:5};
    	var arr=[1,3,5,7,9];
    	$.map(arr,function(index,value){
    		console.log(index,value);
    	});
    	$.map(obj,function(index,value){
    		console.log(index,value);
    	});
    });
    //jQuery中的each方法和map方法的不同
      //each静态方法返回值是,当前遍历的数组
      	//map静态方法默认的返回值是一个空数组
      //each静态方法不可以在回调函数对遍历的数组进行处理
      	//map静态方法可以在回调函数总通过return对遍历的数组进行处理,然后生成一个新的数组返回
    

trim

//$.trim();
//作用:去除字符串两端的空格
//参数:需要去空格的字符串
//返回值:去掉空格的字符串
var str1="  123  ";
console.log(str1);
var str2=$.trim(str1);
console.log(str2

isWindow

//$.isWindow方法
//判断参数是否为window对象
//返回值true则是window,反之不然
var w=window;
var res=$.isWindow(w);
console.log(res);
var n=123;
res=$.isWindow(n);
console.log(res);

isArray

​ 同上,判断参数是否为数组。

isFunction

​ 同上,判断参数是否为Function对象。

jQuery框架本质就是一个Function对象,它是一个匿名函数。

holdReady

$.holdReady(true);//在所有DOM元素加载完后,也不会执行$入口函数
$.holdReady(false);//开始执行$入口函数,可以放在事件中触发

JQuery内容选择器

  • :empty

    $(function(){
    	//empty
    	var emptyDiv=$("div:empty");
    	//查找既没有文本内容也没有子元素的div
    	console.log(emptyDiv);
    });
    
  • :parent

    $(function(){
    	//parent
    	var parentDiv=$("div:parent");
    	//查找有文本内容或子元素的div
    	//即不为空的div
    	console.log(parentDiv);
    });
    
  • :contains

    $(function(){
    	//contains
    	var containsDiv=$("div:contains('text')");
    	//查找包含文本内容'text'的div
    	//若div的子元素包含'text'也符合条件
    	console.log(containsDiv);
    });
    
  • :has

    $(function(){
    	//has
    	var hasDiv=$("div:has('span')");
    	//查找包含子元素span的div
    	//若div的子元素包含span元素也符合条件
    	console.log(hasDiv);
    });
    

属性和属性节点

属性

​ 对象身上保存的变量就是属性。

操作属性

  • 对象.属性名=属性值;:添加
  • 对象.属性值;:获取
  • 对象.["属性名"]=属性值;:添加
  • 对象.["属性名"];:获取

属性节点

<div name="it666"></div>

在编写HTML代码时,标签名内添加的属性就是属性节点。

所有的属性都保存在DOM元素的attributes属性中。

操作属性节点

DOM.setAttribute('属性名称','属性值');	//更改
DOM.getAttribute('属性名称');	//获取

属性和节点属性的区别

任何对象都有属性,但是只有DOM有属性节点。

attr方法

$(function(){
	// attr(name|pro|key,val|fn)
	// 作用:获取或设置属性节点的值,
	// 若传递一个参数,代表获得属性节点的值
	// 若传递两个参数,代表设置属性节点的值
	var div=$("div");
	div.attr('id','asd');
	//如果是获取,无论找到多少个元素,只会返回第一个
	//如果是设置,则会设置所有的符合元素,
	//	若设置的属性节点不存在,系统会自动添加
});

removeAttr方法

$(function(){
	// attr(name)
	// 作用:删除属性节点
	// 一个参数,表示被删除的属性节点名称
	var div=$("div");
	div.removeAttr('id');//删除div的id属性节点
	//会删除符合条件的所有指定节点
	//可同时删除多个属性节点,参数内用空格分隔
});

prop方法

$(function(){
	// prop方法特性和attr方法大同小异
	// 不同之处在于,prop添加属性,attr添加属性节点
	var div=$("div");
	div.eq(0).prop("demo","asd");//qe(0)为找到第1个
	//给第一个div添加属性demo,值为asd
	//prop方法不仅可以操作属性,也可以操作属性节点
});

removeProp方法

removeAttr()方法大同小异。

开发使用建议

​ 在操作属性节点时,具有truefalse两个属性的属性节点,如checkedselected或者disabled等,使用prop方法,其他的使用attr方法。

类的操作

addClass方法

<script type="text/javascript">
	$(function(){
		$('div').eq(0).addClass('color');
		$('div').eq(1).addClass('border');
		$('div').eq(2).addClass('border color');
		//同时添加多个类,用空格分隔
	});	
</script>
<style type="text/css">
	.color{
		width: 50px;
		height: 50px;
		background-color: greenyellow;
		margin-top: 10px;
	}
	.border{
		border: 5px solid black;
	}
</style>

removeClass方法

removeClass([class|fn])

  • 作用:删除一个类
  • 如果想删除多个,多个类名之间用空格隔开即可

toggleClass方法

toggIeCIass(cIass|fn[,sw])

  • 作用:切换类
  • 有就删除,没有添加

文本相关方法

  • html方法
    • 和原生JS中的innerHTML类似
  • text方法
    • 和原生JS中的innerText类似
  • val方法
    • 只能获取和改变文本框中的值
<!DOCTYPE html>
<html lang="zh">
<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>
	<script src="../jquery-1.12.4.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		$(function(){
			$('button')[0].onclick=function(){
				$('div').eq(0).html('<p>123</p>');
			};
			$('button')[1].onclick=function(){
				console.log($('div').eq(0).html());
			};
			$('button')[2].onclick=function(){
				$('div').eq(0).text('<p>123</p>');
			};
			$('button')[3].onclick=function(){
				console.log($('div').eq(0).text());
			};
			$('button')[4].onclick=function(){
				$('input').eq(0).val('<p>123</p>');
			};
			$('button')[5].onclick=function(){
				console.log($('input').eq(0).val());
			};
		});	
	</script>
	<style type="text/css">
		div{
			width: 100px;
			height: 50px;
			background-color: greenyellow;
			margin-top: 10px;
			border:1px solid black;
		}
	</style>
</head>
<body>
	<button>设置HTML</button>
	<button>获取HTML</button>
	<button>设置text</button>
	<button>获取text</button>
	<button>设置val</button>
	<button>获取val</button>
	<div></div>
	<input type="text" />
</body>
</html>

操作元素样式

逐个设置样式

$('div').css('width','100px');
$('div').css('height','100px');
$('div').css('backgroundColor','blue');

链式设置样式

$('div').css('width','100px').css('height','100px').css('backgroundColor','red');
//如果链式步数大于三步,建议分开设置,提高阅读性

批量设置

$('div').css({
	width:'100px',
	height:'100px',
	background:'blue',
});
//开发中建议使用该方法

获取CSS样式

$('div').css('width');

设置宽高

//获取
$('button').eq(0).click(function(){
	console.log($('.father').width());
});
//设置
$('button').eq(1).click(function(){
	$('.father').width(500);
	//$('.father').width('500px');
});

设置相对窗口位置

//获取
$('button').eq(0).click(function(){
	//获取元素距窗口的偏移量
	console.log($('.son').offset().left);
});
//设置
$('button').eq(1).click(function(){
	//设置元素距窗口的偏移量
	$('.son').offset({
	left:10
	});
});

设置相对定位元素位置

$('button').eq(0).click(function(){
	//获取元素距其定位元素的偏移量
	//该方法无法设置
	console.log($('.son').position().left);
});

获取和设置滚动条偏移量

$('button').eq(0).click(function(){
	console.log($('.scroll').scrollTop());
	//由于兼容性问题,获取窗体的滚动条偏移量需要如下代码
	console.log($('body').scrollTop()+$('html').scrollTop());
});
//设置
$('button').eq(1).click(function(){
	$('.scroll').scrollTop(300) ;
	//由于兼容性问题,设置窗体的滚动条偏移量需要如下代码
	$('body,html').scrollTop(300);
});

事件

事件绑定

jQuery的两种绑定事件方法,这两种方式绑定多个同事件名时,不会覆盖。

  1. eventName(fn);

    //使用jQuery时,不能使用[]获取第几个元素,而是通过eq()方法
    $('button').eq(0).click(function(){
    	alert('我被绑定给第一个按钮了');
    });
    //编码效率高,但是部分事件无法绑定
    
  2. on(eventName,fn);

    $('button').eq(1).on('click',function(){
    	alert('我被绑定给第二个按钮了');
    });
    //编码效率低,但是JS中所有事件都可以绑定
    

事件解绑

//不传递参数,解绑所有事件
$('button').eq(0).off();
//传递一个参数,会解绑所有指定事件
$('button').eq(0).off('click');
//传递两个参数,会解绑指定函数的指定事件
$('button').eq(0).off('click',test);

阻止事件冒泡和默认行为

  1. 阻止事件冒泡

    $('button').eq(0).click(function(event){
    	alert('我被绑定给第一个按钮了');
    	//通过事件对象
    	event.cancelBubble=true;//IE支持
    	event.stopPropagation();//W3C标准
    	//通过返回false
    	return false;
    });
    
  2. 阻止事件默认行为

    //阻止默认行为
    $('button').eq(0).click(function(event){
    	alert('我被绑定给第一个按钮了');
    	//通过事件对象
    	event.preventDefault();
    	//通过返回false
    	return false;
    });
    

自动触发事件

$('button').eq(0).click(function(event){
	alert('我被绑定给第一个按钮了');
});
//会触发事件冒泡,也会触发默认行为
$('button').eq(0).trigger('click');
//不会触发事件冒泡,也不会触发默认行为
$('button').eq(0).triggerHandler('click');

自定义事件

//必须通过on来绑定自定义事件
$('button').eq(0).on('myClick'(function(event){
	alert('我被绑定给第一个按钮了');
});
//必须通过trigger来触发自定义事件
$('button').eq(0).trigger('myClick');

事件的命名空间

//必须通过on来绑定自定义事件
$('button').eq(0).on('myClick.wc'(function(event){
	alert('我被绑定给第一个按钮了');
});
//必须通过trigger来触发自定义事件
$('button').eq(0).trigger('myClick.wc');
//利用trigger触发子元素带命名空间的事件,
//那么父元素的带相同命名空间的事件也会被触发
//利用trigger触发子元素不带命名空间的事件,
//那么子元素所有相同类型的事件和父元素所有相同类型的事件都会触发

事件的委托

​ 给某元素的子元素绑定事件,若后期再添加子元素,则这些新添加的子元素不具备这个事件,所以需要事件的委托。

​ 事件的委托就是,通过冒泡将子元素的事件冒泡到父元素,在通过父元素绑定事件。

$('ul').delegate('li','click',function(){
	console.log(this.html());
//这样以后新添加的li都会具有单击响应事件
});

鼠标移入移出事件

$('.father').mouseover(function(){
	console.log('移入father');
});
$('.father').mouseout(function(){
	console.log('移出father');
});

​ 在移入子元素时,会重新出发父元素的移入移出事件,但我们认为子元素同样在父元素内,所以不必重新触发。

$('.father').mouseenter(function(){
	console.log('移入father');
});
$('.father').mouseleave(function(){
	console.log('移出father');
});
//这样就不会重复触发

同时监听移入移出事件

$('.father').hover(移入函数,移出函数);
$('.father').hover(移入移出函数);

获取关系元素

  • 获取兄弟元素

    //返回除了当前元素的所有兄弟元素
    $('selector').siblings();
    
  • 获取父元素

    //查找son的father父元素
    $('son').parent('father');
    
  • 获取子元素

    //查找father的son子元素
    $('father').children('son');
    
  • 获取子孙元素

    $('father').find('son');
    //查找son的father父元素
    

动画

动画显示

//number 动画持续时间 毫秒
//function 动画完毕后执行 函数
$('selector').show(number,[swing],function);
//动画消失
//同上
$('selector').hide(number,[swing],function);
//动画切换 原本消失则显示 原本显示则消失
//同上
$('selector').toggle(number,[swing],function);

下滑显示

//滑动位置取决于元素符合以下条件
//元素开启绝对定位,若通过bottom定位,则从下往上滑动显示
//否则都是从上往下
$('selector').slideDown(number,[swing],function);
//上滑消失
$('selector').slideUp(number,[swing],function);
//切换
$('selector').slideToggle(number,[swing],function);

淡入淡出切换

//淡入
$('selector').fadeIn(number,[swing],function)
//淡出
$('selector').fadeOut(number,[swing],function)
//切换
$('selector').fadeToggle(number,[swing],function)
//淡入到 时间,透明度(0-1) 执行完后触发函数
$('selector').fadeTo(number,opacity,[swing],function)

自定义动画

//参数1 对象动画属性终值,不需要px 参数类型:object
    //一次性终值{width:100}  累加终值{width:"+=100"}
    //关键字终值{width:hide|toggle}
//参数2 持续时间(毫秒) 
//参数3(可忽略) 节奏(默认swing linear) swing 初终慢中快 linear匀速
//参数4 动画结束后执行的回调函数
$("selector").animate({},1000,[swing],function);

动画队列

//会等到前一动画执行完毕后执行后面动画
$('selector').stop().donghua1().donghua2()...();

动画控制

//停止符合选择器的当前动画,继续执行后面动画
$('selector').stop([false],[false]);
$('selector').stop();
$('selector').stop(false);
$('selector').stop(false,false);
//立即停止当前和后续所有的动画
$('selector').stop(true);
$('selector').stop(true,false);
//立即完成当前的,继续执行后面的
$('selector').stop(false,true);
//立即完成当前的,并且停止后面的
$('selector').stop(true,true);
//延时 number 延时时间毫秒
$('selector').stop(number);

节点相关方法

添加节点相关方法

var newDiv=$("<div>新增</div>")
//向选择器内部末尾添加新元素
$("selector").append(newDiv);//返回添加完后的$("selector")对象
newDiv.appendTo('selector');//返回newDiv中新添加的$("selector")对象
//向选择器内部起始添加新元素
$("selector").prepend(newDiv);
newDiv.prependTo('selector');
			
//向选择器外部后紧跟着添加新元素
$("selector").after(newDiv);
newDiv.insertAfter('selector');
//向选择器外部前驱跟着添加新元素
$("selector").before(newDiv);
newDiv.insertBefore('selector');

删除节点相关方法

//删除指定元素
$("selector").remove(['selector']);
$("selector").detach(['selector']);
//清空指定元素的内容,不删除本身
$("selector").empty();

替换元素节点

//替换元素
$("selector").replaceWith(newEle);
newEle.replaceWith("selector");

复制节点方法

//浅复制元素 仅复制元素
var li=$("selector").clone(false);
//深复制元素 额外复制事件
var li=$("selector").clone(true);

jQuery的本质

  1. jQuery的本质是一个闭包

  2. jQuery为什么要使用闭包实现?

    为了避免多个框架的冲突

  3. jQuery如何让外界访问内部定义的局部变量

    window.xxx=xxx

  4. jQuery为什么要给自己传递一个window参数?

    为了方便后期代码压缩

    为了提升查找的效率

  5. jQuery为什么要给自己接收一个undefined参数

    为了方便后期压缩代码

    IE9以下的浏览器undefined可以被修改,为了保证内部使用的undefined不被修改,所以需要接收一个正确的undefined

框架结构

//以后写框架对照以下
(function(window,undefined){
    var jQuery = function(){
        return new jQuery.prototype.init()
    }
    jQuery.prototype = {
        constructor:jQuery
    }
    jQuery.prototype.init.prototype = jQuery.prototype;
    window.jQuery = window.$ = jQuery;
})(window);
  1. 传入'' null undefined NaN 0 false,返回空的jQuery对象
  2. 字符串
    1. 代码片段:会将创建好的DOM元素存储到jQuery对象中返回
    2. 选择器:会将找到的所有元素存储到jQuery对象中返回
  3. 数组
    1. 会将数组中存储的元素依次存储到jQuery对象中返回
  4. 除上述类型以外的
    1. 会将传入的数据存储到jQuery对象中返回

补充

判断数组

//判断obj是否为数组
if(typeof obj==="object"&&"length" in obj && obj!==window)
    console.log("数组");

判断真伪数组

if({}.toString.apply(obj)=="[object Array]")
    console.log("真数组");
else{
    console.log("伪数组");
}