jQuery中选择器的基础使用教程


Posted in Javascript onMay 23, 2016

其实选择器就像开罐器一样,会用这个工具的人,自然吃的到甜头,但不会用这个工具的人,不管罐头里面的面筋土豆有多美味,吃不到就是吃不到,就如同jquery再怎么强大,也只能看着荧幕,而不知该如何下手,不过虽然选择器不难,也容易上手,但老实说,我用了一年多下来,还是觉得自己只有用皮毛而已,所以希望藉着这一系列的笔记,让自己能更长进一些
DOM怎么吃
DOM可以说是JavaScript与网页之间的联系管道,他提供了一个模型,让JavaScript能藉由此模型来改变或操作整个网页,

<div class="one">
  <p>two_1</p>
  <p>two_2</p>
  <p>two_2</p>
</div>

我这边就简单介绍一下DOM模型,有个元素class名为one的是父元素,底下有三个儿子元素<p>,每个元素都视为一个节点,也可以看成一个树形图,因为我认为有些东西是Google会讲得比我好,所以还想知道更多纠结的父子关系...,可以去这,那边有很好的说明,这边就不多加解释,而当Jquery利用选择器抓取到DOM元素以后,就会将他包装成一个Jquery object,并且回传
$('#MyDiv')<-- 他是一个物件
这里有个观念十分重要,因为许多初学者,甚至是一些从Jquery开始学起Javascript的开发者(包括我),常常会把以下两个程序码搞混在一起

//原生JavaScript取id为a的div
var result1 = document.getElementById('a');
console.log(result1);

//用jquery取id为a的div
var result2=$('#a');
console.log(result2);

如果你执行这段程序码出来,??会发现console出来的结果,用JavaScript取出来的结果是DOM,可是一样的div用Jquery取出来的却是个包装过后的物件,换句话说,你不能直接对包装过后的Jquery物件增加DOM的事件,而是要用Jquery提供的事件,有人会说,那意思是不是说以后只能河水不犯井水,往后互不干涉,从此分道扬镳呢? 到也不是

var b=$('#a')[0];

只要跟上述程序码一样就可以取得DOM的元素了
$()工厂
不管是如何选择,我们都会用相同的函式$(),就如之前所讲的,他能接受CSS选择器的语法做为参数,而最主要的三个参数分别为tag name、ID与class,当然,这三个参数可以再与其他CSS语法做结合

//tag name
$('div')

//ID
$('#myId')

//class
$('.myClass')

而上述函式都会如同第一章所介绍的,都有隐式迭代的特色,而为了做到跨览器的支援,Jquery的选择器包含了CSS1-3,所以不用担心一些比较特别的浏览器(对就是IE6)不能执行,除非浏览器没有开启JavaScript
接着接下来我简单介绍几个用法
http://jsfiddle.net/XZnQ7/

//将不含color1 class的p增加一个color2 class
$('p:not(.color1)').addClass('color2');

http://jsfiddle.net/bpJct/3/

//这里是用正规表示法
$('a[href^="mailto:"]').addClass('font1');
$('a[href^="http"]').addClass('font2');
$('a[href$=".pdf"]').addClass('font3');

当然还提供了一些客制化(custom)的选择器,但一般来说原生(native)的方式会来的效能比较快,如果有注重这块的朋友,可能要尽量避免使用客制化的选择器例如以下范例

http://jsfiddle.net/MF8mu/
//替index为1的tr加上class
$('tr:eq(1)').addClass('color1');

//替index为1的tr加上class
$('tr:nth-child(1)').addClass('color2');

这里很特别的是,为什么都是替index为1的tr加上class,却是不同的结果呢?,因为:eq()算是一个JavaScript阵列,index是0起始,所以才会选到第二个,而nth-child()是CSS选择器的一种,所以index是以1起始,选到的就是第一个,以下的范例意思相同

http://jsfiddle.net/3PrJt/
//选择偶数的tr增加class
$('tr:even').addClass('color1');

//选择偶数的tr增加class
$('tr:nth-child(even)').addClass('color2');

就如同刚刚所讲的,index起始不同(JavaScript起始为0,CSS为1),所以虽然都是取偶数,但却是不同列
再来就一些FORM常用的选择器 http://jsfiddle.net/qcXSy/3/

$(':button').click(function(){
    alert('a');
});

这就代表说绑定所有的bitton一个click事件,其他还有像:input、:button、:enabled、:disabled都可以跟其他选择器一起组合成新的选择器
更加强大的.filter()
当有时候一般的选择器已经不能不能满足我们复杂的DOM时,例如要抓div的爸爸的哥哥的儿子的妹婿的二姑的大舅时...,这时候还可以用一个方法filter,这个方法特别的地方在于他可以带function进去 http://jsfiddle.net/wGz3k/
可以看到function里面限制return index == 1才可以增加CSS,这个好处就在于可以在里面做很多复杂的逻辑运算
当然Jquery还有太多太多选择器可以使用,像还有.next()、.parent()、.children()一般常用的这几个,其实就很够用了我认为,再多的选择器有时候好像只是展示不同的写法,但其实只要能抓取到你想要的元素,解决问题
你甚至想要这样写$('div').children().children().children().children().children()也不会有人说不行..

实例
一个网站中有10种的文章分类,我们设计一个类似WordPress显示各文章分类的名称及其文章数量的栏目,当用户进入一个页面时,默认显示前面5个分类的名称以及最后一个分类——其他分类,用户可以通过单击“显示全部分类”按钮来显示全部分类,同时一些推荐的分类会加下划线显示,按钮中的文字会改变为“显示部分分类”,再次单击“显示部分分类”后会回到之前的页面状态。

首先为了实现这个功能,我们需要写出相应的 html

<div class="CategoryBox">
  <h2>分类列表</h2>
  <ul>
    <li><a href="#">互联网(55)</a></li>
    <li><a href="#">前端(22)</a></li>
    <li><a href="#">css(10)</a></li>
    <li><a href="#">jQuery(12)</a></li>
    <li><a href="#">后台(28)</a></li>
    <li><a href="#">Php(10)</a></li>
    <li><a href="#">jsp(6)</a></li>
    <li><a href="#">.net(5)</a></li>
    <li><a href="#">CMS(9)</a></li>
    <li><a href="#">其他分类(3)</a></li>  
  </ul>
  <div class="more">
    <a href="more.html"><span>显示全部分类</span></a>
  </div>
</div>

 

在Html写后好再添加一些简单的css,然后就可以开始jQuery的编写。

 

下面的代码将实现页面加载完毕后选取相应的对象并隐藏,这里选取的是第6个分类到第9个分类4个对象,因为需要控制隐藏和显示的便是这四个分类。

var $category = $('ul li:gt(4):not(:last)');
$category.hide();

$('ul li:gt(4):not(:last)')的意思便是获取索引值大于4的li元素并且去掉最后一个,需要注意的是索引值是从0开始,所以这样便可以获取第6到第9个分类。

下面将会获取“显示全部分类”按钮,并且给该按钮添加一个事件,单击该按钮后显示所有分类

var $toggleBtn = $('.more a');
$toggleBtn.click(function() {
  $category.show();
  return false;
});

 
.show()是用于显示元素的动画,另外由于给超链接添加onclick事件,因此需要添加return false语句阻止该超链接跳转。

写到这里,我们不难发现,jQuery的选择器跟css选择器有相近之处,其原理都是先以选择器选择对象,再添加操作,不过jQuery的选择器明显比css的丰富和简便得多,这也是使用jQuery能大大提高网站开发效率的重要原因。

接着上面的例子,根据文章开头设定的条件,在单击“显示全部分类”的按钮后,部分推荐的分类会添加下划线,同时按钮中的文字会变成“显示部分分类”,因此我们还需要在.show()和return false之间添加以下代码:

$('.more a span').text("显示部分分类");
$('ul li').filter(":contains('前端'),:contains('css'),:contains('jQuery'),:contains('CMS')").addClass("feature");

 
.text()用于改变对象中的文字,filter()可以用于选出推荐对象,这里推荐的是前端,CSS,jQuery,CMS,然后使用addClass()为它们添加“feature”类,因为我已预先写feature类的css,所以以上推荐对象在单击按钮后便会加上下划线。至此,可以说基本完成了这次需要的jQuery,当然用户单击“显示部分分类”后的效果还没有写上相应的jQuery。但有了前面的一段jQurey代码,相信写出单击“显示部分分类”后的代码应该不难。

在单击“显示部分分类”后的效果中其中一个是需要去掉推荐分类的下划线效果,我们可以使用removeClass(),用法与addClass相同。

现在余下的问题是如何把两段代码写在一起,由于用户在两个事件上单击的是同一个按钮,因此事件仍然是在刚才的按钮元素上,要使两种状态在一个元素上进行,我们可以使用判断:

if(元素显示状态 ) {
//隐藏元素
}else{
//显示元素
}

 
整个完整的jQuery代码如下:

$(document).ready(function() {
    var $category = $('ul li:gt(4):not(:last)');
    $category.hide();
    var $toggleBtn = $('.more a');
    $toggleBtn.click(function() {
      if($category.is(":visible")) {
        $category.hide();
        $('.more a span')
          .text("显示全部分类");
        $('ul li').removeClass("feature");
      }else{
        $category.show();
        $('.more a span')
          .text("显示部分分类");
        $('ul li').filter(":contains('前端'),:contains('css'),:contains('jQuery'),:contains('CMS')")
          .addClass("feature");
      }
      return false;
    });
});

 
上面的判断语句,用法与一般的高级编程语言相近,但放在jQuery这个以轻便闻名的js库中不免显得繁琐,其实在jQuery中有更为轻便的方法去实现上面的例子,即toggle()方法,代码如下:

$(document).ready(function(){
    var $category = $('ul li:gt(4):not(:last)');
    $category.hide();
    var $toggleBtn = $('.more a');
    $toggleBtn.toggle(function(){
      $category.show();
      $('.more a span')
        .text("显示部分分类");
      $('ul li').filter(":contains('前端'),:contains('css'),:contains('jQuery'),:contains('CMS')")
        .addClass("feature");
    },function(){
      $category.hide();
      $('.more a span')
        .text("显示全部分类");
      $('ul li').removeClass("feature");
    });
});

具体的效果可以看demo note-selector

Javascript 相关文章推荐
Javascript的IE和Firefox兼容性汇编(zz)
Feb 02 Javascript
List Installed Software Features
Jun 11 Javascript
js获取域名的方法
Jan 27 Javascript
7个让JavaScript变得更好的注意事项
Jan 28 Javascript
AspNet中使用JQuery上传插件Uploadify详解
May 20 Javascript
angular仿支付宝密码框输入效果
Mar 25 Javascript
js实现HTML中Select二级联动的实例
Jan 05 Javascript
JQuery常见节点操作实例分析
May 15 jQuery
vue+koa2搭建mock数据环境的详细教程
May 18 Javascript
详解React 元素渲染
Jul 07 Javascript
JS call()及apply()方法使用实例汇总
Jul 11 Javascript
vue3.0自定义指令(drectives)知识点总结
Dec 27 Vue.js
基于BootStrap的图片轮播效果展示实例代码
May 23 #Javascript
AngularJS上拉加载问题解决方法
May 23 #Javascript
在IE8上JS实现combobox支持拼音检索功能
May 23 #Javascript
浅析JavaScript 箭头函数 generator Date JSON
May 23 #Javascript
用js实现放大镜的效果的简单实例
May 23 #Javascript
jQuery实现摸拟alert提示框
May 22 #Javascript
javascript实现标签切换代码示例
May 22 #Javascript
You might like
Laravel 4.2 中队列服务(queue)使用感受
2014/10/30 PHP
微信获取用户地理位置信息的原理与步骤
2015/11/12 PHP
PHP CURL采集百度搜寻结果图片不显示问题的解决方法
2017/02/03 PHP
PHP简单实现合并2个数字键数组值的方法
2017/05/30 PHP
判定是否原生方法的JS代码
2013/11/12 Javascript
网站基于flash实现的Banner图切换效果代码
2014/10/14 Javascript
jQuery检测某个元素是否存在代码分享
2015/07/09 Javascript
jQuery+HTML5加入购物车代码分享
2020/10/29 Javascript
node.js使用cluster实现多进程
2016/03/17 Javascript
JavaScript实现简单Tip提示框效果
2016/04/20 Javascript
JavaScript第一篇之实现按钮全选、功能
2016/08/21 Javascript
AngularJS中的按需加载ocLazyLoad示例
2017/01/11 Javascript
jQuery遍历节点方法汇总(推荐)
2017/05/13 jQuery
详解webpack异步加载业务模块
2017/06/23 Javascript
原生js实现仿window10系统日历效果的实例
2017/10/31 Javascript
原生JS实现前端本地文件上传
2018/09/08 Javascript
JS中call()和apply()的功能及用法实例分析
2019/06/28 Javascript
ES6之Proxy的get方法详解
2019/10/11 Javascript
vue实现图片裁剪后上传
2020/12/16 Vue.js
Python中的装饰器用法详解
2015/01/14 Python
python traceback捕获并打印异常的方法
2018/08/31 Python
Python Gluon参数和模块命名操作教程
2019/12/18 Python
jupyter notebook清除输出方式
2020/04/10 Python
宝塔面板出现“open_basedir restriction in effect. ”的解决方法
2021/03/14 PHP
css3实现六边形边框的实例代码
2019/05/24 HTML / CSS
HTML5 常用语法一览(列举不支持的属性)
2010/01/26 HTML / CSS
博士研究生自我鉴定范文
2013/12/04 职场文书
写给女朋友的道歉信
2014/01/08 职场文书
《去年的树》教学反思
2014/04/11 职场文书
法院干警四风问题自我剖析材料
2014/09/29 职场文书
个人租房协议书样本
2014/10/01 职场文书
优秀共产党员事迹材料
2014/12/18 职场文书
监护人证明
2015/06/19 职场文书
三八节活动主持词
2015/07/04 职场文书
24句精辟的现实社会语录,句句扎心,道尽人性
2019/08/29 职场文书
详解nginx进程锁的实现
2021/06/14 Servers