开发者社区> 科技小毛> 正文

jQuery学习笔记:核心(jQuery Core)<转>

简介:
+关注继续查看
学习并掌握jQuery,从熟悉jQuery核心开始。
一、核心函数
1、jQuery(expression,[context])

这个函数接收一个包含 CSS 选择器的字符串,然后用这个字符串去匹配一组元素。
jQuery 的核心功能都是通过这个函数实现的。 jQuery中的一切都基于这个函数,或者说都是在以某种方式使用这个函数。这个函数最基本的用法就是向它传递一个表达式(通常由 CSS 选择器组成),然后根据这个表达式来查找所有匹配的元素。默认情况下, 如果没有指定context参数,$()将在当前的 HTML 文档中查找 DOM 元素;如果指定了context 参数,如一个DOM 元素集或 jQuery 对象,那就会在这个context 中查找。
返回值 jQuery
参数
expression (String) : 用来查找的字符串
context (Element, jQuery) : (可选) 作为待查找的 DOM 元素集、文档或 jQuery 对象。
示例:

复制代码
ContractedBlock.gifExpandedBlockStart.gif
$(document).ready(function() {

    $(
"div>p").css("display""block"); //显示

    $("div>p").css("color""blue"); //颜色为绿色

    alert($(
"div>p").html()); //找到所有div元素的子元素p,并显示p元素的innerHTML

    
var chks = $("input:checkbox", document.forms[0]); //在文档的第一个表单中,查找所有的多选按钮(即:type为checkbox的input元素)
    alert(chks.length);
    
for (var i = 0; i < chks.length; i++
) {
        alert(chks[i].checked);
    }
})
复制代码
文档片段:
复制代码
ContractedBlock.gifExpandedBlockStart.gif
    <form id="form1" runat="server">
    
<p>one</p> <div><style="display:none">two</p></div> <p>three</p>
    
<br />
    
<div>
    
<input type="text" />&nbsp;&nbsp;<input id="chkTest" type="checkbox" checked="checked" />&nbsp;&nbsp;<input id="btnTest" type="button" value="button" /></div>
    
</form>
复制代码
2、jQuery(html,[ownerDocument])
根据提供的原始HTML标记字符串,动态创建由 jQuery 对象包装的DOM元素。
可以传递一个手写的HTML字符串,或者由某些模板引擎或插件创建的字符串,也可以是通过 AJAX 加载过来的字符串。但是在创建input 元素的时会有限制,可以参考第二个示例。当然这个字符串可以包含斜杠 (比如一个图像地址),还有反斜杠。
当创建单个元素时,请使用闭合标签或 XHTML 格式
。例如,创建一个span,可以用 $("<span/>") 或 $("<span></span>") ,但不推荐 $("<span>")。在jQuery 中,这个语法等同于$(document.createElement("span")) 。
返回值 jQuery
参数

html (String) : 用于动态创建DOM元素的HTML标记字符串
ownerDocument (Document) : 可选,创建DOM元素所在的文档
示例:

复制代码
ContractedBlock.gifExpandedBlockStart.gif
$(document).ready(function() {

    $(
"<div><p>This is a jQuery test.</p></div>").appendTo("body"
);

    
//创建一个input元素

    if (!$.browser.msie) {
        $(
"<input>").attr("type""checkbox").appendTo("body"); // 在 IE 中无效:

    }
    
else
 {
        
// 所有浏览器中有效

        $("<input type='checkbox'>").appendTo("body");
    }
})
复制代码

3、jQuery(elements)
将一个或多个DOM元素转化为jQuery对象。
这个函数也可以接收XML文档和Window对象(虽然它们不是DOM元素)作为有效的参数。
返回值 jQuery
参数

elements (Element, Array<Element>) : 用于封装成jQuery对象的DOM元素
示例:

$(document).ready(function() {

    $(document.body).css(
"background""cef"); //设置页面背景色

    $(document.forms[0].elements).hide(); //隐藏一个表单中的所有元素
})

 4、jQuery(callback)
$(document).ready()的简写。
允许绑定一个在DOM文档载入完成后执行的函数。这个函数的作用如同$(document).ready()一样,只不过用这个函数时,需要把页面中所有需要在DOM 加载完成时执行的$()操作符都包装到其中来。可以在一个页面中使用任意多个$(document).ready事件。
返回值 jQuery
参数

callback (Function) : 当DOM加载完成后要执行的函数
示例:

$(function() {
    alert(
"文档加载就绪"
);
    
// 文档加载就绪

}); 

注意:
使用 $(document).ready() 的简写,同时内部的 jQuery 代码依然使用 $ 作为别名,而不管全局的 $ 为何。
jQuery 代码:
jQuery(function($) {
// 可以在这里继续使用$作为别名...
});
二、对象访问
1、each(callback)
以每一个匹配的元素作为上下文来执行一个函数。
意味着,每次执行传递进来的函数时,函数中的this关键字都指向一个不同的DOM元素(每次都是一个不同的匹配元素)。而且,在每次执行函数时,都会给函数传递一个表示作为执行环境的元素在匹配的元素集合中所处位置的数字值作为参数(从零开始的整形)。 返回 'false' 将停止循环 (就像在普通的循环中使用 'break')。返回 'true' 跳至下一个循环(就像在普通的循环中使用'continue')。
返回值 jQuery
参数
callback (Function) : 对于每个匹配的元素所要执行的函数
示例:

$("img").each(function(i) {
this.src = "images/test" + (i + 1).toString() + ".jpg"// 结果: <img src="images/test1.jpg" />

});

 如果你想得到 jQuery对象,可以使用 $(this) 函数。
jQuery 代码:
$("img").each(function(){
  $(this).toggleClass("example");
});
下面再实现一个使用 'return' 来提前跳出 each() 循环:

ContractedBlock.gifExpandedBlockStart.gifCode
$("button").click(function() {
    $(
"div").each(function
(index, domEle) {
        
// domEle == this 

        $(domEle).css("backgroundColor""yellow");
        
if ($(this).is("#stop"
)) {
            $(
"span").text("Stopped at div index #" +
 index);
            
return false//使用 'return'来提前跳出each()循环

        }
    });
});

文档片段:

复制代码
<button>改变背景色</button>
<span></span> 
<div></div>
 
<div></div>


<div></div> 
<div></div>

<div id="stop">在这里停止</div> 
<div></div>


<div></div>
<div></div>
复制代码

 3、size()和length
jQuery 对象中元素的个数。
这个函数的返回值与 jQuery 对象的length属性一致。
返回值 Number
参数    没有参数
示例:

$(function() {
    
var len = $("img").size(); //计算文档中所有图片数量

    alert(len);
    alert($(
"img").length == len); //与jQuery对象的length属性一致

})

 4、selector
jQuery 1.3新增。返回传给jQuery()的原始选择器。
换句话说,就是返回你用什么选择器来找到这个元素的。可以与context一起使用,用于精确检测选择器查询情况。这两个属性对插件开发人员很有用。
返回值 String
参数    没有参数
示例:

ContractedBlock.gifExpandedBlockStart.gifCode
$(function() {
    
//确定查询的选择器 

    $("ul")
  .append(
"<li>" + $("ul").selector + "</li>"
)
  .append(
"<li>" + $("ul li").selector + "</li>"
)
  .append(
"<li>" + $("div#foo ul:not([class])").selector + "</li>"
);

})

5、context
jQuery 1.3新增。返回传给jQuery()的原始的DOM节点内容,即jQuery()的第二个参数。如果没有指定,那么context指向当前的文档(document)。
可以与selector一起使用,用于精确检测选择器查询情况。这两个属性对插件开发人员很有用。
返回值 HTMLElement
示例

ContractedBlock.gifExpandedBlockStart.gifCode
$(function() {
    
//检测使用的文档内容

    $("ul")
    .append(
"<li>" + $("ul").context + "</li>"
)
  .append(
"<li>" + $("ul").context.nodeName + "</li>"
)
  .append(
"<li>" + $("ul", document.body).context.nodeName + "</li>"
);

})

6、get()
取得所有匹配的 DOM 元素集合。
这是取得所有匹配元素的一种向后兼容的方式(不同于jQuery对象,而实际上是元素数组)。如果你想要直接操作 DOM 对象而不是 jQuery 对象,这个函数非常有用。
返回值 Array<Element>
参数    没有参数
示例:


$(
function() {
$(
"img").get().reverse(); //选择文档中所有图像作为元素数组,并用数组内建的reverse方法将数组反转

})

 文档片段:

    <form id="form1" runat="server" >
    
<img src="images/test1.jpg"/><br /> <img src="images/test2.jpg"/>
    
</form>

 7、get(index)
取得其中一个匹配的元素。 index表示取得第几个匹配的元素。
这能够让你选择一个实际的DOM 元素并且对他直接操作,而不是通过 jQuery 函数。$(this).get(0)与$(this)[0]等价。
返回值 Element
参数   
index (Number) :取得第 index 个位置上的元素
示例:

$(function() {
    
var imgSrc = $("img").get(0).src; //取图片对应路径

    alert(imgSrc);
})

8、index(subject)
搜索与参数表示的对象匹配的元素,并返回相应元素的索引值。
如果找到了匹配的元素,从1开始返回;如果没有找到匹配的元素,返回-1。
返回值 Number
参数   
subject (Element) : 要搜索的对象
示例:

ContractedBlock.gifExpandedBlockStart.gifCode

$(
function() {
    
//返回对应ID值的元素的索引值

    alert($("div").index($('#f'))); // -1
    alert($("div").index($('#foobar'))); // 1
    alert($("div").index($('#fo'))); // 2
    alert($("div").index($('#foo'))); // 3
})

文档片段:

<div id="foobar">
<div id="fo"></div>
<div id="foo"></div>
</div>

三、数据缓存
1、data(name)
返回元素上储存的相应名字的数据,可以用data(name, value)来设定。
如果jQuery集合指向多个元素,那将只返回第一个元素的对应数据。
这个函数可以用于在一个元素上存取数据而避免了循环引用的风险。jQuery.data是1.2.3版的新功能。可以在很多地方使用这个函数,另外jQuery UI里经常使用这个函数。
返回值 Any
参数   
name (String) :存储的数据名
示例:

ContractedBlock.gifExpandedBlockStart.gifCode
$(function() {
    
//在一个div上存取数据

    $("div").data("blah"); // undefined
    alert($("div").data("blah"));
    $(
"div").data("blah""hello world"); // blah设置为hello world


    $(
"div").data("blah"); // hello
    $("div").data("blah"123); // 设置为123

    $(
"div").data("blah"); // 123
    alert($("div").data("blah"));
    $(
"div").removeData("blah"); //移除blah

    $("div").data("blah"); // undefined 

    
//在一个div上存取名/值对数据 
    $("div").data("test", { first: 456, last: "jeff wong!" });
    alert($(
"div").data("test").first); //456;

    alert($("div").data("test").last); //jeff wong 
})

2、removeData(name)
在元素上移除存放的数据
与$(...).data(name, value)函数作用相反
返回值 jQuery
参数   
name (String) :存储的数据名
示例:

ContractedBlock.gifExpandedBlockStart.gifCode
$(function() {
    $(
"div").data("test", { first: 456, last: "jeff wong!"
 });
    alert($(
"div").data("test").first); //456;

    alert($("div").data("test").last); //jeff wong
    $("div").removeData("test"); //移除test
    alert($("div").data("test")); //undefined;
})

3、queue([name])
返回指向第一个匹配元素的队列(将是一个函数数组)
返回值 Array<Function>
参数   
name (String) :队列名,默认为fx
示例:

ContractedBlock.gifExpandedBlockStart.gifCode
//通过设定队列数组来删除动画队列
$("#btnShow").click(function() {
    
var n = $("div").queue("fx"
);
    $(
"span").text("Queue length is: " +
 n.length);
});
function
 runIt() {
    $(
"div").show("slow"
);
    $(
"div").animate({ left: '+=200' }, 2000
);
    $(
"div").slideToggle(1000
);
    $(
"div").slideToggle("fast"
);
    $(
"div").animate({ left: '-=200' }, 1500
);
    $(
"div").hide("slow"
);
    $(
"div").show(1200
);
    $(
"div").slideUp("normal"
, runIt);
}
runIt();

文档片段:

ContractedBlock.gifExpandedBlockStart.gifCode
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    
<title></title>
    
<style>
        div
        
{
            margin
: 3px;
            width
: 40px;
            height
: 40px;
            position
: absolute;
            left
: 0px;
            top
: 30px;
            background
: green;
            display
: none;
        
}
        div.newcolor
        
{
            background
: blue;
        
}
        span
        
{
            color
: red;
        
}
    
</style>

    
<script src="js/jquery-1.3.1.js" type="text/javascript"></script>

</head>
<body>
    
<form id="form1" runat="server">
       
<button id="btnShow" type="button">
        Show Length of Queue
</button>
    
<span style="color:Red"></span>
    
</form>

    
<script src="js/jQTest.js" type="text/javascript"></script>

</body>
</html>

4、queue([name],callback)
在匹配的元素的队列最后添加一个函数
返回值 jQuery
参数   
name (String) :队列名,默认为fx 
callback (Function) : 要添加进队列的函数
示例:

ContractedBlock.gifExpandedBlockStart.gifCode
//插入一个自定义函数 如果函数执行后要继续队列,则执行 jQuery(this).dequeue();
jQuery(document).ready(function() {
    $(document.body).click(
function
() {
        $(
"div").show("slow"
);
        $(
"div").animate({ left: '+=200' }, 2000
);
        $(
"div").queue(function
() {
            $(
this).addClass("newcolor"
);
            $(
this
).dequeue();
        });
        $(
"div").animate({ left: '-=200' }, 500
);
        $(
"div").queue(function
() {
            $(
this).removeClass("newcolor"
);
            $(
this
).dequeue();
        });
        $(
"div"
).slideUp();
    });
});

文档片段:

ContractedBlock.gifExpandedBlockStart.gifCode
<html>
<head>  
<style>

  div 
{ margin:3px; width:40px; height:40px;
        position
:absolute; left:0px; top:30px; 
        background
:green; display:none; }
  div.newcolor 
{ background:blue; }
</style>
</head>
<body>
  Click here
  
<div></div>
</body>
</html>

5、queue([name],queue)
将匹配元素的队列用新的一个队列来代替(函数数组).
返回值 jQuery
参数   
name (String) :队列名,默认为fx 
queue (Array<Function>) : 用于替换的队列。所有函数都有同一个参数,这个值与queue(callback)相同
示例:

ContractedBlock.gifExpandedBlockStart.gifCode
//通过设定队列数组来删除动画队列 
jQuery(document).ready(function() {
    $(
"#start").click(function
() {
        $(
"div").show("slow"
);
        $(
"div").animate({ left: '+=200' }, 5000
);
        $(
"div").queue(function
() {
            $(
this).addClass("newcolor"
);
            $(
this
).dequeue();
        });
        $(
"div").animate({ left: '-=200' }, 1500
);
        $(
"div").queue(function
() {
            $(
this).removeClass("newcolor"
);
            $(
this
).dequeue();
        });
        $(
"div"
).slideUp();
    });
    $(
"#stop").click(function
() {
        $(
"div").queue("fx", []); //通过设定队列数组来删除动画队列 

        $("div").stop();
    });
});

文档片段:

ContractedBlock.gifExpandedBlockStart.gifCode
<html>
<head>  
<style>

  div { margin:3px; width:40px; height:40px;
        position:absolute; left:0px; top:30px; 
        background:green; display:none; }
  div.newcolor { background:blue; }
  
</style>
</head>
<body>
  
<button id="start">Start</button>
  <button id="stop">Stop</button>
  <div></div>
</body>
</html>

6、dequeue([name])
从队列最前端移除一个队列函数,并执行它。
返回值 jQuery
参数   
name (String) :队列名,默认为fx 
示例:

ContractedBlock.gifExpandedBlockStart.gifCode

$(
"button").click(function() {
    $(
"div").animate({ left: '+=200px' }, 2000
);
    $(
"div").animate({ top: '0px' }, 600
);
    $(
"div").queue(function
() {
        $(
this).toggleClass("red"
);
        $(
this).dequeue(); //用dequeue来结束自定义队列函数,并让队列继续进行下去。 

    });
    $(
"div").animate({ left: '10px', top: '30px' }, 700
);
});

文档片段:

ContractedBlock.gifExpandedBlockStart.gifCode
<html>
<head>  
<style>

  div 
{ margin:3px; width:50px; position:absolute;
        height
:50px; left:10px; top:30px; 
        background-color
:yellow; }
  div.red 
{ background-color:red; }
  
</style>
</head>
<body>
  
<button>Start</button>
  
<div></div>
</body>
</html>

 ps:上面的一些示例用到了一些jquery特效函数,因为本篇主要阐述核心函数,对于单个特效函数这里不再详细说明使用细节。
四、插件机制
1、jQuery.fn.extend(object)
扩展 jQuery 元素集来提供新的方法(通常用来制作插件)
返回值 jQuery
参数   
object (Object) :用来扩充 jQuery 对象。
示例:

ContractedBlock.gifExpandedBlockStart.gifCode

//增加两个插件方法。
jQuery.fn.extend({
    check: 
function
() {
        
return this.each(function() { this.checked = true
; });
    },
    uncheck: 
function
() {
        
return this.each(function() { this.checked = false
; });
    }
});


$(
"input[type=checkbox]"
).check();
$(
"input[type=radio]").uncheck(); 

文档片段:

    <input  type="checkbox" />
    
<input type="radio"  checked="checked"/>

2、jQuery.extend(object)
扩展jQuery对象本身,用来在jQuery命名空间上增加新函数
返回值 jQuery
参数   
object (Object) :用来扩充 jQuery 对象。
示例:

ContractedBlock.gifExpandedBlockStart.gifCode
//在jQuery命名空间上增加两个函数
jQuery.extend({
    min: 
function(a, b) { return a < b ?
 a : b; },
    max: 
function(a, b) { return a > b ?
 a : b; }
});


alert(jQuery.min(
23)); // => 2

alert(jQuery.max(45)); // => 5 

五、多库共存
1、jQuery.noConflict()
运行这个函数将变量$的控制权让渡给第一个实现它的那个库。这有助于确保jQuery不会与其他库的$对象发生冲突。在运行这个函数后,就只能使用jQuery变量访问jQuery对象。
例如,在要用到$("div p")的地方,就必须换成jQuery("div p")。
注意:这个函数必须在导入jQuery文件之后,并且在导入另一个导致冲突的库之前使用。当然也应当在其他冲突的库被使用之前,除非jQuery是最后一个导入的。
返回值 jQuery
示例:

ContractedBlock.gifExpandedBlockStart.gifCode

//1、将$引用的对象映射回原始的对象。
jQuery.noConflict();
// 使用 jQuery

jQuery("div p").hide();
// 使用其他库的 $()

$("content").style.display = 'none';


//2、恢复使用别名$,然后创建并执行一个函数,在这个函数的作用域中仍然将$作为jQuery的别名来使用。

//
在这个函数中,原来的$对象是无效的。这个函数对于大多数不依赖于其他库的插件都十分有效。 
jQuery.noConflict();
(
function
($) {
    $(
function
() {
        
// 使用 $ 作为 jQuery 别名的代码

    });
})(jQuery);
// 其他用 $ 作为别名的库的代码



//3、创建一个新的别名用以在接下来的库中使用jQuery对象。
var j = jQuery.noConflict();
// 基于 jQuery 的代码

j("div p").hide();
// 基于其他库的 $() 代码

$("content").style.display = 'none'

2、jQuery.noConflict(extreme)
将$和jQuery的控制权都交还给原来的库(用之前请考虑清楚!)
这是相对于简单的 noConflict 方法更极端的版本,因为这将完全重新定义jQuery。这通常用于一种极端的情况,比如你想要将jQuery嵌入一个高度冲突的环境。注意:调用此方法后极有可能导致插件失效。
返回值 jQuery
参数   
extreme (Boolean) : 传入 true 来允许彻底将jQuery变量还原示例:
示例:

ContractedBlock.gifExpandedBlockStart.gifCode
//完全将 jQuery 移到一个新的命名空间。 
var dom = {};
dom.query 
= jQuery.noConflict(true
); 

// 新jQuery的代码

dom.query("div p").hide();
// 另一个库 $() 的代码

$("content").style.display = 'none';
// 另一个版本 jQuery 的代码

jQuery("div > p").hide(); 

好了,核心部分就介绍到这里。现在回头来看,jQuery函数封装的方式比直接调用js和dom的各种函数,真是方便直接多了。 振作精神,下一篇接着把jQuery的选择器属性介绍一下。函数很多,现在记不住就记不住算了,多写多用熟练了就好。以后用到的时候,可以直接当自己的在线参考书。希望对你也有帮助。
原文地址:
原文地址:http://www.cnblogs.com/wjfluisfigo/archive/2009/08/08/1530624.html

 

 

 

本文转自温景良(Jason)博客园博客,原文链接:http://www.cnblogs.com/wenjl520/archive/2009/08/08/1541992.html,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
从零开始学习jQuery (七) jQuery动画-让页面动起来!
原文:从零开始学习jQuery (七) jQuery动画-让页面动起来! 本系列文章导航 从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 从零开始学习jQuery (四) 使用...
936 0
从零开始学习jQuery (十一) 实战表单验证与自动完成提示插件
原文:从零开始学习jQuery (十一) 实战表单验证与自动完成提示插件 本系列文章导航 从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 从零开始学习jQuery (四) 使用...
1055 0
从零开始学习jQuery (十) jQueryUI常用功能实战
原文:从零开始学习jQuery (十) jQueryUI常用功能实战 本系列文章导航 从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 从零开始学习jQuery (四) 使用jQ...
1056 0
jQuery学习笔记之jQuery的Ajax(3)
jQuery学习笔记之jQuery的Ajax(3) 6.jQuery的Ajax插件 源码地址: https://github.com/iyun/jQueryDemo.git ———————————————————————————— 6.0 jQuery ajax 浏览器给我们提供的XMLHttpRequest的作用是来发送http请求。 js代码发送一个ht
1351 0
jQuery学习笔记--JqGrid相关操作 方法列表 备忘 重点讲解(超重要)
JqGrid相关操作备忘 方法列表 1.获得当前列表行数:$("#gridid").getGridParam("reccount"); 2.获取选中行数据(json):$("#gridid").
1512 0
PredNet --- Deep Predictive coding networks for video prediction and unsupervised learning --- 论文笔记
PredNet --- Deep Predictive coding networks for video prediction and unsupervised learning   ICLR 2017  2017.03.12    Code and video examples can be found at: https://coxlab.github.io/prednet/   摘要:基于监督训练的深度学习技术取得了非常大的成功,但是无监督问题仍然是一个未能解决的一大难题(从未标注的数据中学习到一个领域的结构)。
1769 0
一个.NET Core开发者的Linux入门学习笔记
用.NET Core开发也有一段时间了,但是由于工作原因一直都是在Windows系统上进行的开发,一直想学习Linux然后把.NET Core开发的程序跑在Linux上,然后把心得体会记录一下发布再博客园,奈何拖延症泛滥,所以只写过一篇《CentOS开发ASP.NET Core入门教程》之后就继续征战Windows了!作为新年Flag之一就是学习Docker,K8S,虽然windows系统也能进行开发,但是毕竟Linux才是正途,因此这两天特地学习了一下Linux系统,并整理成这篇学习笔记,希望对.NET Core开发者学习Linux有所帮助。
7248 0
jQuery学习笔记之概念(1)
jQuery学习笔记之概念(1) ——————————————————————学习目录———————————————————— 1.概念 2.特点 3.选择器 4.DOM操作 5.事件 6.jQuery的Ajax ———————————————————————————————————————————————— 前言:当前流行的JavaScript库有:
1340 0
+关注
580
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载