标签:
队列(先进先出)方法,执行顺序的管理。
<script type="text/javascript">
//大体框架
//队列先进先出
//队列其实就是一个数组
jQuery.extend([//工具方法
queue//相当于数组的push操作-往数组的后面添加数据 入队操作
dequeue//相当于数组的shift操作-从数组的前面取数据 出队操作
_queueHooks
]);
jQuery.fn.extend([//实例方法
queue //入队
dequeue //出队
delay //延迟队列
clearQueue //清除队列
promise //队列全部执行完后再执行
]);
</script>
队列中存的都是函数
队列操作存储的必须是函数,因为在出队的时候回对函数进行操作
工具方法操作:
<script type="text/javascript" src="../../jquery-2.1.4.js"></script>
<script type="text/javascript">
$(function(){
function fn1(){
alert(111);
}
function fn2(){
alert(222);
}
//工具方法操作
$.queue(document,‘q1‘,fn1);
$.queue(document,‘q1‘,fn2);//三个参数分别表示添加队列的对象、队列名称和队列中的函数数据
//也可以整体添加
//$.queue(document,‘q1‘,[fn1,fn2]);
console.log($.queue(document,‘q1‘));//[function, function]
$.dequeue(document,‘q1‘);//111 出队操作-从队列中取出第一个函数并执行,而不是仅仅取出来
//进行了一次出队操作后,数组就减少一项。只剩下[fn2]
$.dequeue(document,‘q1‘);//222 出队操作-从队列中取出第一个函数并执行
});
</script>
<script type="text/javascript">
//队列中存的都是函数
//队列操作存储的必须是函数,因为在出队的时候回对函数进行操作
$(function(){
function fn1(){
alert(111);
}
function fn2(){
alert(222);
}
//实例操作
$(document).queue(‘q1‘,fn1);//入队操作
$(document).queue(‘q1‘,fn2);
console.log($.queue(document,‘q1‘));//[function, function]
$(document).dequeue(‘q1‘);//111
$(document).dequeue(‘q1‘);//222
});
</script>
实例操作:
<script type="text/javascript" src="../../jquery-2.1.4.js"></script>
<script type="text/javascript">
$(function(){
function fn1(){
alert(111);
}
function fn2(){
alert(222);
}
//实例操作
$(document).queue(‘q1‘,fn1);//入队操作
$(document).queue(‘q1‘,fn2);
console.log($.queue(document,‘q1‘));//[function, function]
$(document).dequeue(‘q1‘);//111
$(document).dequeue(‘q1‘);//222
});
</script>
在jQuery中queue主要是针对动画操作的,与运动有关
Demo:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>queue</title>
<style type="text/css">
div{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
</style>
</head>
<body>
<div id="#div1"></div>
<script type="text/javascript" src="../../jquery-2.1.4.js"></script>
<script type="text/javascript">
$(function(){
$(‘div‘).click(function(){
$(this).animate({ //通过开启一个定时器setInterval来不断改变宽度
width:300
},2000);
$(this).animate({//通过开启一个定时器setInterval来不断改变高度
height:300
},2000);
$(this).animate({//通过开启一个定时器setInterval来不断改变left值
left:300
},2000);
});
});
</script>
</body>
</html>
当动画开始之前将三个定时器放到queue的队列数组中[setInterval1,setInterval2,setInterval3],然后调用dequeue出队,从前往后依次执行。
queue也可以对异步进行管理(定时器就是异步的),而且可以对多个异步进行管理
deferred是针对单个异步操作的
在队列操作中,如果不进行出队操作,则队列后面的操作永远不会执行。
Demo:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>queue</title>
<style type="text/css">
div{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
</style>
</head>
<body>
<div id="#div1"></div>
<script type="text/javascript" src="../../jquery-2.1.4.js"></script>
<!-- <script type="text/javascript">
$(function(){
$(‘div‘).click(function(){ $(this).animate({width:300},2000).queue(‘fx‘,function(){
//这里没有出队操作,后面的操作都不会执行,只会改变宽度值,不会改变高度值
}).animate({height:300},2000);
});
});
</script> -->
<script type="text/javascript">
$(function(){
$(‘div‘).click(function(){
//fx为默认的队列名称,可以省略
$(this).animate({width:300},2000).queue(‘fx‘,function(next){
//$(this).dequeue();//出队操作 可以进行后续操作
next();//和上面的代码功能一样,都是出队操作
}).animate({height:300},2000);
});
});
</script>
</body>
</html>
回调是不可控制的
queue是可以控制的,想什么出队就什么时候出队
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>queue</title>
<style type="text/css">
div{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
</style>
</head>
<body>
<div id="#div1"></div>
<script type="text/javascript" src="../../jquery-2.1.4.js"></script>
<script type="text/javascript">
$(function(){
$(‘div‘).click(function(){
$(this).animate({width:300},2000,function(){
$(this).css(‘left‘,300);
}).animate({height:300},2000);
});
});
</script>
<script type="text/javascript">
$(function(){
$(‘div‘).click(function(){
$(this).animate({width:300},2000,function(){
var that = this;
//因为定时器是异步的
//这里使用回调函数不会影响后续动画的执行
//所以回调里面的运动会和会面的运动一起发生
var timer = setInterval(function(){
that.style.left = that.offsetLeft + 1 + ‘px‘;
if(that.offsetLeft == 200){
clearInterval(timer);
}
},30);
}).animate({height:300},2000);
});
});
</script>
<script type="text/javascript">
$(function(){
$(‘div‘).click(function(){
$(this).animate({width:300},2000).queue(function(next){
//这里使用queue,保证left改变完成后再出队
//如果永远不出队,后面的操作永远不会执行
var that = this;
var timer = setInterval(function(){
that.style.left = that.offsetLeft + 1 + ‘px‘;
if(that.offsetLeft == 200){
next();//这里当left改变完成后再出队
//可以控制异步的执行顺序
clearInterval(timer);
}
},30);
}).animate({height:300},2000);
});
});
</script>
</body>
</html>
<body>
<div id="#div1"></div>
<script type="text/javascript" src="../../jquery-2.1.4.js"></script>
<script type="text/javascript">
$(function(){
$(‘div‘).click(function(){
//delay是延迟队列执行 $(this).animate({width:300},2000).delay(2000).animate({height:300},2000);
});
});
</script>
</body>
<body>
<div id="#div1"></div>
<script type="text/javascript" src="../../jquery-2.1.4.js"></script>
<script type="text/javascript">
$(function(){
$(‘div‘).click(function(){
//队列全部执行完后再执行 $(this).animate({width:300},2000).animate({height:300},2000);
$(this).promise().done(function(){//队列执行完毕后弹123
alert(123);
});
});
});
</script>
</body>
//队列(先进先出)方法
//执行顺序的管理
jQuery.extend({
//接收三个参数:要添加对列的对象、队列名称和函数数据
//入队
queue: function( elem, type, data ) {
var queue;
if ( elem ) //当元素存在时进行后续操作
//type || "fx" 取自定义的队列名或者默认的fx
type = ( type || "fx" ) + "queue";
//data_priv数据缓存对象
queue = data_priv.get( elem, type );
// Speed up dequeue by getting out quickly if this is just a lookup
if ( data ) {
if ( !queue || jQuery.isArray( data ) ) {
//jQuery.isArray( data )当data是数组时,重新进行设置队列
queue = data_priv.access( elem, type, jQuery.makeArray(data) );
} else {
queue.push( data );
}
}
return queue || [];
}
},
//出队
dequeue: function( elem, type ) {
type = type || "fx";
var queue = jQuery.queue( elem, type ),//获取队列数组
startLength = queue.length,//队列长度
fn = queue.shift(),//获取数组第一项
hooks = jQuery._queueHooks( elem, type ),
next = function() {//next就是执行出队操作
jQuery.dequeue( elem, type );//出队操作
};
// If the fx queue is dequeued, always remove the progress sentinel
if ( fn === "inprogress" ) {
fn = queue.shift();
startLength--;
}
if ( fn ) {
// Add a progress sentinel to prevent the fx queue from being
// automatically dequeued
if ( type === "fx" ) {
queue.unshift( "inprogress" );
}
// clear up the last queue stop function
delete hooks.stop;
fn.call( elem, next, hooks );
}
if ( !startLength && hooks ) {
hooks.empty.fire();
}
},
// not intended for public consumption - generates a queueHooks object, or returns the current one
_queueHooks: function( elem, type ) {
var key = type + "queueHooks";
return data_priv.get( elem, key ) || data_priv.access( elem, key, {
empty: jQuery.Callbacks("once memory").add(function() {
data_priv.remove( elem, [ type + "queue", key ] );
})
});
}
});
//扩展实例方法
jQuery.fn.extend({
//入队
queue: function( type, data ) {
var setter = 2;
if ( typeof type !== "string" ) {
data = type;
type = "fx";
setter--;
}
//根据参数长度来判断是应该获取还是设置
if ( arguments.length < setter ) {
return jQuery.queue( this[0], type );
}
return data === undefined ?
this :
this.each(function() {
var queue = jQuery.queue( this, type, data );
// ensure a hooks for this queue
jQuery._queueHooks( this, type );
//inprogress是针对动画的第一次出队操作
if ( type === "fx" && queue[0] !== "inprogress" ) {
jQuery.dequeue( this, type );
}
});
},
//出队
dequeue: function( type ) {
return this.each(function() {
jQuery.dequeue( this, type );
});
},
// Based off of the plugin by Clint Helfers, with permission.
// http://blindsignals.com/index.php/2009/07/jquery-delay/
// 延迟队列
delay: function( time, type ) {
time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
type = type || "fx";
return this.queue( type, function( next, hooks ) {
//next就是出队
var timeout = setTimeout( next, time );
hooks.stop = function() {
clearTimeout( timeout );
};
});
},
//清除队列
clearQueue: function( type ) {
return this.queue( type || "fx", [] );
},
// Get a promise resolved when queues of a certain type
// are emptied (fx is the type by default)
// 队列全部执行完后再执行
promise: function( type, obj ) {
var tmp,
count = 1,
defer = jQuery.Deferred(),
elements = this,
i = this.length,
resolve = function() {
if ( !( --count ) ) {
defer.resolveWith( elements, [ elements ] );
}
};
if ( typeof type !== "string" ) {
obj = type;
type = undefined;
}
type = type || "fx";
while( i-- ) {
tmp = data_priv.get( elements[ i ], type + "queueHooks" );
if ( tmp && tmp.empty ) {
count++;
tmp.empty.add( resolve );
}
}
resolve();
return defer.promise( obj );
}
});
<body>
<div id="box" title="盒子1">111111</div>
<div id="box" title="盒子2">222222</div>
<div id="box" title="盒子3">333333</div>
<script type="text/javascript" src="../../jquery-2.1.4.js"></script>
<script type="text/javascript">
$(function(){
$("div").attr(‘title‘,‘盒子‘);//这个是设置所有div的title属性值为盒子
alert($("div").attr(‘title‘));//这个只会获取到第一个div的title属性值
});
</script>
</body>
<body>
<div id="box">111111</div>
<script type="text/javascript" src="../../jquery-2.1.4.js"></script>
<script type="text/javascript">
$(function(){
$("#box").attr(‘title‘,‘hello‘);//两个参数是设置
alert($("#box").attr(‘id‘));//box 1个参数是获取
//原生实现
var oDiv = document.getElementById("box");
oDiv.setAttribute(‘title‘,‘hello‘);
oDiv.getAttribute(‘title‘);
// attr在原生js是基于setAttribute和getAttribute来实现的
// prop是基于dot(.)和方括号语法[]来实现的
//原生实现
var oDiv = document.getElementById("box");
oDiv.title = ‘hello‘;
oDiv[‘title‘] = ‘hello‘;
$("#box").prop(‘title‘,‘hello‘);//两个参数是设置
alert($("#box").prop(‘id‘));//box 1个参数是获取
});
</script>
</body>
<body>
<div id="box" title="盒子1">111111</div>
<div id="box" title="盒子2">222222</div>
<div id="box" title="盒子3">333333</div>
<script type="text/javascript" src="../../jquery-2.1.4.js"></script>
<script type="text/javascript">
$(function(){
$("div").attr(‘title‘,‘盒子‘);//这个是设置所有div的title属性值为盒子
alert($("div").attr(‘title‘));//这个只会获取到第一个div的title属性值
});
</script>
</body>
<body>
<div id="box">111111</div>
<a href="hello.html" id="link"></a>
<input type="checkbox" name="" value="" checked="checked">
<script type="text/javascript" src="../../jquery-2.1.4.js"></script>
<script type="text/javascript">
$(function(){
//获取链接的href属性值也不一样
console.log($("#link").attr(‘href‘));//hello.html
console.log($("#link").prop(‘href‘));//file:///C:/Users/lj/Desktop/%E6%88%91%E7%9A%84%E5%89%8D%E7%AB%AF%E5%AD%A6%E…%E5%85%83%E7%B4%A0%E5%B1%9E%E6%80%A7%E7%9A%84%E6%93%8D%E4%BD%9C/hello.html
$("#link").removeAttr(‘href‘);
alert($("#link").attr(‘href‘));//undefined
$("#link").removeAttr(‘id‘);
alert($("#link").attr(‘id‘));//undefined
$("#link").removeProp(‘id‘);//不会删除掉
alert($("#link").prop(‘id‘));//link
alert($(‘input‘).attr(‘checked‘));//checked
alert($(‘input‘).prop(‘checked‘));//true
});
</script>
</body>
对于自定义属性,attr起作用,prop不起作用。
<body>
<div id="box" muke="学前端">111111</div>
<script type="text/javascript" src="../../jquery-2.1.4.js"></script>
<script type="text/javascript">
//设置自定义属性,attr起作用,prop不起作用
$("#box").attr(‘muke‘,‘学前端‘);
$("#box").prop(‘muke‘,‘学前端‘);//不起作用
//获取自定义属性
alert($("#box").attr(‘muke‘));//可以获取到
alert($("#box").prop(‘muke‘));//undefined 获取不到
</script>
</body>
attr()和prop()方法分别取的是节点的attribute值、property值
attr: function( name, value ) {
//this当前的元素
//jQuery.attr对应回调函数
//name和value就是属性和值
//arguments.length > 1判断是读取还是设置,1个参数是读取,两个参数是设置
//实例attr实际操作的是工具方法jQuery.attr
//下面方法也都是调用的工具方法
return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
},
prop: function( name, value ) {
return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
}
attr()和prop()实际上是调用jQuery.access()方法。jQuery.access主要作用是修正参数。access函数里的第二个参数jQuery.attr. 这个参数的作用是告诉access方法, 修正完参数后再去调用 静态方法jQuery.attr()。
实例方法都是调用最终的静态方法来实现的
access方法最后把参数又传递给了jQuery.attr, 在jQuery.attr里才真正进行setAttribute和getAttribute操作.
access源码部分:
//多功能值操作(内部)
//chainable控制设置或者获取
access: function( elems, fn, key, value, chainable, emptyGet, raw ) {
var i = 0,
length = elems.length,
bulk = key == null;
// Sets many values
// 设置多组值
if ( jQuery.type( key ) === "object" ) {
chainable = true;
for ( i in key ) {
jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
}
// Sets one value
} else if ( value !== undefined ) {
chainable = true;
if ( !jQuery.isFunction( value ) ) {
raw = true;
}
if ( bulk ) {
// Bulk operations run against the entire set
//是字符串
if ( raw ) {
fn.call( elems, value );
fn = null;
// ...except when executing function values
//是函数
} else {
bulk = fn;
fn = function( elem, key, value ) {
return bulk.call( jQuery( elem ), value );
};
}
}
if ( fn ) {
for ( ; i < length; i++ ) {
fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
}
}
}
//chainable为真是设置
//为假就是获取 视频27
return chainable ?
elems :
// Gets
bulk ?
fn.call( elems ) :
length ? fn( elems[0], key ) : emptyGet;
}
<body>
<div id="box" muke="学前端" class="div">111111</div>
<script type="text/javascript" src="../../jquery-2.1.4.js"></script>
<script type="text/javascript">
$(function(){
//可以同时删除多个属性和属性值
//attrNames = value && value.match( core_rnotwhite );
//value.match( core_rnotwhite )返回一个数组
//["id","muke","class"]
$("div").removeAttr("id muke class");
});
</script>
</body>
基本用法:
<body>
<div id="box" class="box1 box2">111111</div>
<script type="text/javascript" src="../../jquery-2.1.4.js"></script>
<script type="text/javascript">
$(function(){
//添加类名
$("#box").addClass("box3");
//添加多个类名
$("#box").addClass("box3 box4");
// 特别注意空字符串和空格字符串不一样
alert(Boolean(""));//false
// 空格字符串会返回真
alert(Boolean(" "));//true
});
</script>
</body>
<body>
<div id="box">111111</div>
<div id="box">222222</div>
<div id="box">333333</div>
<script type="text/javascript" src="../../jquery-2.1.4.js"></script>
<script type="text/javascript">
$(function(){
// addClass()支持回调函数的形式,这种形式用的少
$("div").addClass(function(index){
// alert(index);//0
return ‘box‘+index;//这里根据index的不同,添加不同的class
});
});
</script>
</body>
<body>
<div id="box" class="box1 box2">111111</div>
<script type="text/javascript" src="../../jquery-2.1.4.js"></script>
<script type="text/javascript">
$(function(){
//如果removeClass()中什么都不写,则会将class属性值清空
//相当于全部删除的操作
$("#box").removeClass();
});
</script>
</body>
<body>
<div id="box" class="box1 box2">111111</div>
<script type="text/javascript" src="../../jquery-2.1.4.js"></script>
<script type="text/javascript">
$(function(){
//toggleClass()有相应的class则删除,没有就添加
//这是接收一个参数的情况
$("#box").toggleClass("box3");
// 这里会删除box2,添加box3
$("#box").toggleClass("box2 box3");
//接收两个参数
//true表示不管原来元素有没有相应的class,都会进行添加操作
//这样一来toggleClass()就变成了添加操作
//添加第二个参数true后,box2和box3都会添加
$("#box").toggleClass("box2 box3",true);
// 当第二个参数为false时,box2和box3都会删除
$("#box").toggleClass("box2 box3",false);
});
</script>
</body>
<body>
<div id="box" class="box1 box2">111111</div>
<script type="text/javascript" src="../../jquery-2.1.4.js"></script>
<script type="text/javascript">
$(function(){
//只传递一个布尔值,false表示全部删除class
//这里会先将所有的class保存在一个缓存数据中,方便在需要的时候再添加回来
$("#box").toggleClass(false);
//重新添加
$("#box").toggleClass(true);
});
</script>
</body>
源码部分:
//添加class,实例方法
addClass: function( value ) {
var classes, elem, cur, clazz, j,
i = 0,
len = this.length,//缓存操作元素的个数
//如果value是字符串,则直接返回这个字符串
//这里之所以判断是不是字符串,是因为addClass()还支持参数是回调函数的形式
proceed = typeof value === "string" && value;
//这里就是判断参数是不是函数
if ( jQuery.isFunction( value ) ) {
return this.each(function( j ) {
//j就是当前的索引值
jQuery( this ).addClass( value.call( this, j, this.className ) );
});
}
//判断proceed是否为真
//为真,则是字符串类型
if ( proceed ) {
// The disjunction here is for better compressibility (see removeClass)
// match( core_rnotwhite )进行正则分割,分割成数组
// $("#box").addClass("box3 box4");
// 分割成[box3,box4]
// 支持同时添加多个类名,添加多个类名前需要先用空格分割一下
classes = ( value || "" ).match( core_rnotwhite ) || [];
//循环添加
for ( ; i < len; i++ ) {
elem = this[ i ];//获取到相应的元素
//elem.nodeType === 1判断是不是元素节点
//elem.className判断元素的class属性中有没有值,有值就获取到,没有值则返回空格字符串
//rclass = /[\t\r\n\f]/g,是一个正则
cur = elem.nodeType === 1 && ( elem.className ?
( " " + elem.className + " " ).replace( rclass, " " ) :
" "
);
//空格字符串会返回真
if ( cur ) {
j = 0;
//classes是要添加的的class
//cur是当前元素已经存在的class
//(clazz = classes[j++])依次取到要添加的class
//cur.indexOf()调用indexOf()方法判断当前元素中是否存在相应的class
while ( (clazz = classes[j++]) ) {
//返回-1则表示没有相应的class,可以添加
if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
cur += clazz + " ";
}
}
elem.className = jQuery.trim( cur );//去空格
}
}
}
//jQuery的链式操作就是通过返回this来实现的
return this;
},
//删除class
removeClass: function( value ) {
var classes, elem, cur, clazz, j,
i = 0,
len = this.length,
//与操作先于或操作执行
//arguments.length === 0是什么都不传的情况,会清空class的所有属性值
proceed = arguments.length === 0 || typeof value === "string" && value;
if ( jQuery.isFunction( value ) ) {
return this.each(function( j ) {
jQuery( this ).removeClass( value.call( this, j, this.className ) );
});
}
if ( proceed ) {
classes = ( value || "" ).match( core_rnotwhite ) || [];
for ( ; i < len; i++ ) {
elem = this[ i ];
// This expression is here for better compressibility (see addClass)
cur = elem.nodeType === 1 && ( elem.className ?
( " " + elem.className + " " ).replace( rclass, " " ) :
""
);
if ( cur ) {
j = 0;
while ( (clazz = classes[j++]) ) {
// Remove *all* instances
while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
//这里是当存在要删除的class时,将其替换为空格字符串
cur = cur.replace( " " + clazz + " ", " " );
}
}
elem.className = value ? jQuery.trim( cur ) : "";
}
}
}
return this;
},
//切换
//toggleClass可以接收两个参数
toggleClass: function( value, stateVal ) {
var type = typeof value;
if ( typeof stateVal === "boolean" && type === "string" ) {
//当stateVal为真就调用添加,为假就调用删除
return stateVal ? this.addClass( value ) : this.removeClass( value );
}
//也支持回调函数的形式
if ( jQuery.isFunction( value ) ) {
return this.each(function( i ) {
jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
});
}
return this.each(function() {
if ( type === "string" ) {
// toggle individual class names
var className,
i = 0,
self = jQuery( this ),
classNames = value.match( core_rnotwhite ) || [];
while ( (className = classNames[ i++ ]) ) {
// check each className given, space separated list
// 判断当前元素是否包含相应的class
// 有就删除,没有就添加
if ( self.hasClass( className ) ) {
self.removeClass( className );
} else {
self.addClass( className );
}
}
// Toggle whole class name
// 平时用的很少
// 是只给toggleClass(布尔值)传递一个布尔值的情况
} else if ( type === core_strundefined || type === "boolean" ) {
if ( this.className ) {
// store className if set
// 将class存起来
data_priv.set( this, "__className__", this.className );
}
// If the element has a class name or if we‘re passed "false",
// then remove the whole classname (if there was one, the above saved it).
// Otherwise bring back whatever was previously saved (if anything),
// falling back to the empty string if nothing was stored.
this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || "";
}
});
},
//判断有没有相应的class
hasClass: function( selector ) {
var className = " " + selector + " ",
i = 0,
l = this.length;
for ( ; i < l; i++ ) {
//this[i].className是获取到当前元素的class值
//使用indexOf()方法判断是否存在相应的class,存在返回true,不存在返回false
if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
return true;
}
}
return false;
}
<body>
<input type="text" name="" value="请输入" id="input1">
<select multiple>
<option value="哈哈">1111</option>
<option>2222</option>
<option>3333</option>
</select>
<select>
<option>1111</option>
<option>2222</option>
<option>3333</option>
</select>
<input type="checkbox" name="" value="" id="check">
<script type="text/javascript" src="../../jquery-2.1.4.js"></script>
<script type="text/javascript">
$(function(){
alert($("#input1").val());//获取value值
$("#input1").val("修改value值");//设置value值
alert($("#check").get(0).type);//checkbox
// 下拉菜单类型可以有单选可多选两种
alert($("select").get(0).type);//select-multiple
alert($("select").get(1).type);//select-one
alert($("select").get(0).nodeName);//SELECT
//因为option没有type操作,但是有nodeName
alert($("option").eq(0).get(0).type);//undefined
alert($("option").eq(0).get(0).nodeName);//OPTION
alert($("option").eq(0).get(0).value);//1111 说明默认的value值就是option的内容
$("#check").click(function(){
alert($("select").eq(0).val());
});
});
</script>
</body>
源码部分:
//获取属性值方法
val: function( value ) {
var hooks, ret, isFunction,
elem = this[0];//获取第一个元素
//因为获取操作都是针对集合中的第一个元素
//arguments.length等于0则是获取操作
if ( !arguments.length ) {//获取
if ( elem ) {
//先获取元素的elem.type类型
//或者获取元素的elem.nodeName.toLowerCase()节点类型的小写形式
//valHooks:option select radio checkbox只有这四个
//所以对于select-multiple和select-one都无法找到,这样就需要获取相应元素的nodeName
//select的nodeName是SELECT,转为小写就是select
//对于option select我们取的是相应的nodeName
//对于radio checkbox我们取的是相应的elem.type
hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
return ret;
}
//如果没有兼容性,则直接获取value值
ret = elem.value;
return typeof ret === "string" ?
// handle most common string cases
ret.replace(rreturn, "") :
// handle cases where value is null/undef or number
ret == null ? "" : ret;
}
return;
}
//判断value是不是函数
isFunction = jQuery.isFunction( value );
return this.each(function( i ) {
var val;
//只有元素才能够添加value值
if ( this.nodeType !== 1 ) {
return;
}
//如果value函数,则走下面的回调进行处理
if ( isFunction ) {
val = value.call( this, i, jQuery( this ).val() );
} else {//如果不是函数,则进行简单的赋值就可以了
val = value;
}
// Treat null/undefined as ""; convert numbers to string
//这里是将元素的value值变为""
if ( val == null ) {
val = "";
}
//如果传一个数字进来,则会将数字转为字符串
else if ( typeof val === "number" ) {
val += "";
}
//如果传的是一个数组
else if ( jQuery.isArray( val ) ) {
//则针对数组中的每一项进行判断,并返回一个新数组
val = jQuery.map(val, function ( value ) {
//如果value == null则返回""
//为数字,则将数字转为字符串
return value == null ? "" : value + "";
});
}
hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
// If set returns undefined, fall back to normal setting
if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
this.value = val;
}
});
}
标签:
原文地址:http://blog.csdn.net/liujie19901217/article/details/51694708