Web笔记:jQuery的使用

一、jQuery中的 $

1. 顶级对象

可以使用$('DOM对象')将 DOM 对象转换成一个jQuery对象,使其具备jQuery对象的方法。比如下文的入口函数,将 document 对象转换成了 jQuery 对象,调用了 ready 方法。

2.入口函数

$(function(){
  // DOMContentLoaded之后需要执行的代码
});

等价于

$(document).ready(function(){
// DOMContentLoaded之后需要执行的代码
});

其作用都等价于:

document.addEventListener("DOMContentLoaded", function(){
// DOMContentLoaded之后需要执行的代码
 });

3. jQuery对象和DOM对象的转换

jQuery 对象和 DOM 对象相互独立,各自有各自的方法和属性,不能混用,但是可以转换。

jQuery对象的本质是通过选择器进行筛选获取DOM对象后,对其进行伪数组形式的封装,让其具备jQuery对象的方法,观察下面的打印结果:

// html
<div class="first"></div>
<div></div>
// js
var divs = $('div');
console.dir(divs);
var domDiv = document.querySelector('div');
console.dir(domDiv);

结果:


jQuery对象

展开 __proto__ 就可以看到很多方法,比如 hide,也就是说,这个对象包含 2 个 DOM 中的 div 对象,额外添加了许多方法和属性。当调用这些方法时,默认会对 jQuery 对象中的伪数组中的所有元素生效,也就是隐式迭代,而伪数组中的元素就是 DOM 对象。

用图表示就是这样:


jQuery对象

因为是伪数组的形式,那么 jQuery 和 DOM 的转换就简单了,取出 jQuery 伪数组中的元素即可:

jQuery 对象转 DOM 对象:

// 直接取数组中的元素
divs[1].style.display = "none";
// 使用get方法获取数组中的元素
divs.get(1).style.display = "none";

DOM 对象转 jQuery 对象,使用 $ 符号所得到的对象就是 jQuery 对象:

// 标签选择器
var divs = $('div');
// 类型选择器
$('.first').hide();

注意:get 和 eq 含义不同。 get 是转换对象,eq 是取出 jQuery 对象

二、选择器

使用方法:

$("选择器")

1. 基础选择器:

基础选择器

2. 层级选择器

层级选择器

3. 筛选选择器

筛选选择器

使用:

$(function(){
    $(function(){
        // 获取结果中的第一个元素
        $("ul li:first").css("color", "red");
        // 奇数
        $("ul li:odd").css("color", "red");
        // 索引值
        $("ul li:eq(4)").css("color", "red");
    });
})

4. 筛选方法

筛选方法

prevAll():之前的所有的符合选择器的元素,默认无选择器表达式
prev():前一个符合选择器的元素,默认无选择器表达式

如下代码就不会改变,因为ul .item 的前一个不符合选择器要求:

$("ul .item").prev(".first").css("color", "red");

<li class="first">哈哈啊</li>
<li class="second">哈哈啊</li>
<li class="item">哈哈啊</li>
<!-- <li class="item">哈哈啊</li> -->

另外,siblings的执行对象中的元素不止一个的话,会出现问题,使用时最好确保调用对象只有一个:

<script>
$(function() {
    $("ul .item").siblings("li").css("color", "red");
})
</script>

<ul>
    <li class="first">哈哈啊</li>
    <li class="second">哈哈啊</li>
    <li class="item">哈哈啊</li>
    <li class="item">哈哈啊</li>
    <li>哈哈啊</li>
    <li>哈哈啊</li>
    <li>哈哈啊</li>
    <li>哈哈啊</li>
    <li>哈哈啊</li>
    <li>哈哈啊</li>
    <li>哈哈啊</li>
</ul>

结果就是所有的<li>都变成了红色。

5. 两个 eq

选择器中的 eq 遇到变量时,需要使用字符串拼接的方式来使用变量:

var index = 2;
$("ul li:eq("+index+")").css("color", "red");

方法 eq 则可以直接使用变量:

var index = 2;
// $("ul li:eq("+index+")").css("color", "red");
$("ul li").eq(index).css("color", "red");

所以,推荐使用 eq 方法。

另外,eq(index) 是取得对应 inde 的 jQuery 对象,而 get(index) 方法是将 jQuery 对象转换成 DOM 对象。

6. 排他思想

使用 this + siblings来实现:

<button>按钮</button>
<button>按钮</button>
<button>按钮</button>
<button>按钮</button>
<button>按钮</button>
<button>按钮</button>

<script>

    $(function () {
        $("button").click(function() {
            $(this).css("background", "red");
            $(this).siblings().css("background", "none");
        });
    })
</script>

三、样式操作

1. 操作CSS

获取属性值

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

修改单一属性值

$("div").css("width", "300px"); // px可以省略

修改多个属性值
使用对象的形式来修改多个属性值

$("div").css({
    "width": "300px",
    "height" : "200px",
    "background-color" : "red" 
})

注意:

  1. 属性和数字可以不加引号;
  2. 如果属性不加引号,命名方式是驼峰命名,而不是带 "-";
  3. 非数字和属性都要加引号,比如颜色;
  4. jQuery会默认识别数字单位

上述的第二种写法:

$("div").css({
    width: 300,
    height : 200,
    backgroundColor : "red"
})

总结:
加引号是最好的

2. 添加/删除类

写好一个类的样式之后,直接将这个类添加到元素中,这样就不需要一个个地去修改样式了

添加类:addClass
删除类:removeClass
切换类(没有就加,有就删除):toggleClass

举个栗子🌰:

<style>
    div {
        background-color: yellow;
        width: 50px;
        height: 50px;
    }

    .redBox {
        background-color: red;
        width: 300px;
        height: 200px;
    }
</style>

<body>
    <div></div>

    <script>
        $(function () {
            $("div").mouseover(function () {
                $(this).addClass("redBox")
            });

            $("div").click(function () {
                $(this).removeClass("redBox")
            });
        })
    </script>
</body>

以上代码可以直接使用切换类:

 $("div").click(function () {
    $(this).toggleClass("redBox")
 });

再来看一个过渡动画的栗子🌰:

<style>

    div {
        background-color: yellow;
        width: 50px;
        height: 50px;
        /* 所有可以动画的属性都添加上过渡效果 */
        transition: all 0.5s;
    }

    .redBox {
        background-color: red;
        transform: rotate(360deg);
    }
</style>

<body>
    <div></div>

    <script>
        $(function () {
            $("div").click(function () {
                $(this).toggleClass("redBox")
            });
        })
    </script>
</body>

结果是:


过渡动画

例子中主要是 使用了 transition: all 0.5s; 让所有可动画的属性在变换时都进行动画,接下来看看真正的动画效果~~

四、动画

1. show/hide

show([speed], [easing], [fn])
speed:速度,slow、normal、fast、毫秒数
easing:swing(秋千)、linear(线性)
fn:完成后的回调函数

2. slide

<style>
    div {
        background-color: red;
        width: 150px;
        height: 400px;
        display: none;
    }
</style>

<body>
    <button>下拉</button>
    <button>上滑</button>
    <button>切换</button>
    <div></div>
    
    <script>
        $(function(){
            $("button").first().click(function(){
                $("div").slideDown()
            })

            $("button").eq(1).click(function(){
                $("div").slideUp()
            })

            $("button").last().click(function(){
                $("div").slideToggle()
            })
        })
    </script>
</body>

效果:


slide效果

3. hover

hover([over,]out):鼠标经过时的事件,附带切换功能;

第一个参数是经过时的回调,第二个是离开时的回调。至少需要传一个函数。

如果只有一个 function,那么鼠标经过和离开都会调用这个函数,所以和 toggle 来配合使用代码会非常简洁,如下:

$("button").hover(function(){
    $("div").slideToggle()
})

4. 动画队列和停止排队

简易的下拉菜单的 JS 代码如下:

<script>
    $(function(){
        $(".nav>li>a").hover(function(){
            $(this).next("ul").slideToggle(300)
        })
    })
</script>

默认情况下的效果是这样的:


动画排队执行

如图,当快速在导航栏滑动时,滑动停止之后会出现动画排队必须执行完,所以就有了鼠标离开了仍然继续加载动画的情况。因为默认情况下,事件触发了多少次,动画就会排队执行多少次,所以需要使用stop() 来终止之前的动画。

stop():停止之前的动画,开始最新的动画
代码如下:

$(this).next("ul").stop().slideToggle(300)

切记必须写在动画方法的前面,写到后面就想到与停止动画了,代码如下:

$(this).next("ul").slideToggle(300).stop()

如果这样写,结果会出错。

5. 淡入淡出

fadeIn:由透明变成不透明,0->1;
fadeOut:由不透明变成透明,1->0;
fadeTo:变化到指定的透明度;
fadeToggle:切换;

仍然是接收三个参数:speed、easing、fn

其中,fadeTo 第二个参数为新增参数:opacity

6. 自定义动画

animate(params,[speed],[easing],[fn])

第一个参数是需要动画的属性,以对象形式表示。和 .css() 是一样的道理,最好都使用引号。

代码如下:

<style>

    div {
        position: absolute;
        left: 50px;
        top: 0;
        background-color: yellow;
        margin: 100px auto;
        width: 100px;
        height: 100px;
        /* 所有可以动画的属性都添加上过渡效果 */
        /* transition: all 0.5s; */
    }
</style>

<body>
    <div></div>

    <script>
        $(function () {
            $("div").animate({
                width: 200,
                left: 200,
                top: 300
            }, 1000, "swing", function(){
                console.log("动画执行完毕")
            })
        })
    </script>
</body>

五、属性操作

1. prop

意义:只能获取和设置元素的固有属性,返回字符串。

示例如下:

<input type="checkbox">

<script>
    console.log($("input").prop("checked"));
</script>

2. attr

意义:获取和设置自定义属性,返回字符串。设置时没有就新增,可获取和设置的属性包括 H5 新增的以data-开头的自定义属性。

示例:

<div data-index="2">1</div>
<script>
    console.log($("div").attr("index")); // undefined
    console.log($("div").attr("data-index")); // 2
    $("div").attr("index","1")
    console.log($("div").attr("index")); // 1
</script>

因为自定义的属性如果没有规范,很容易和固有属性引起歧义,结果就是使用 attribute 和 点方法属性获取到为空。所以 H5 新增 data-xxx 就是规范了自定义属性,由此就成就了 propattr 两套独立的方法。

3. data

意义:数据缓存,可以理解成attr,但是和attr最大的不同是data()方法不会改变 DOM 的结构。所以这个方法更适合理解成数据缓存。

该方法同样可以获取 H5 中新规定的以 "data-" 开头的自定义属性,但是不能加"data-"。但是设置时,不管有没有"data-",都不会在 DOM 中显示。

总之:就用这个方法来存储数据即可。

示例代码:

<input type="checkbox" data-index2="2">

<script>
    // 获取和设置存储数据,不改变DOM结构
    $("input").data("data-index", "1");
    console.log($("input").attr("data-index"));
    // 获取自定义属性时,data不能加data-,attr必须加
    console.log($("input").attr("data-index2"));
    console.log($("input").data("index2"));
</script>

六、文本操作

html():获取和设置文本/元素
text():获取和设置文本
val():获取和设置 val 属性,没有 val 属性时无效

代码示例:

    <div>
        <div><span>我是span</span></div>
        <input type="text" name="" id="" value="" placeholder="请输入文字">
    </div>
    <script>
        // html
        console.log($("div>div").html());
        $("div>div").html("123");
        $("div>div").html("<p>我是段落</p>");

        // text
        $("div>div p").text("段落文本被修改了");

        // val
        $("div>input").val("文本框的值被修改了")
    </script>

七、元素操作

1. 遍历

方法一:$("div").each(function(index, domEle){})

注意:domEle 是 DOM 对象,而不是 jQuery 对象,所以需要使用 $() 转换。

方法二:$.each(object, function(index, domEle){})

该方法区别于以上方法,方法一主要用于元素循环添加一些操作,方法二一般用来处理数据。新增的 object 对象可以是数组,也可以是对象,可以是 DOM 对象,也可以是 JS 对象,还可以是 jQuery 对象。

遍历数组:

var array = [1, 2, 3]
$.each(array, function(index, ele){
    console.log(index)
    console.log(ele)
})

遍历对象:

var obj = {"name" : "Jack", "height" : 180, "weight" : 50.0}
$.each(obj, function(index, ele){
    console.log(index)
    console.log(ele)
})

遍历 jQuery 对象:

$.each($("div"), function(index, ele){
    console.log(index)
    console.log(ele)
})

2. 创建

jQuery:$("<div>0</div>")
DOM:ele.html("<div>0</div>")document.createElement("<div>0</div>")document.write("<div>0</div>")

3. 添加

内部添加:ele.append()ele.prepend()
外部添加:ele.after()ele.before()

4. 删除

删除自身:ele.remove()
删除自身所有子元素:ele.empty()ele.html("")

这里需要注意 html ("") 的用法。html() 本来就是设置自身的子元素,只不过比 text() 具备识别标签的能力,同时具备创建元素的能力,所以字符串为非标签时,就是设置元素的文本属性,字符串为标签时,就是给元素添加子元素。

示例代码:

<div>1</div>
<div>2</div>
<div class="lastDiv">3</div>

<ul>
    <li>1</li>
    <li>2</li>
    <li class="lastLi">3</li>
</ul>
<script>
    // 创建元素
    var newDiv = $("<div>4</div>")
    var newLi = $("<li>4</li>")

    // 内部添加
    $("ul").append(newLi)
    $("ul").prepend($("<li>0</li>"))

    // 外部添加
    $("ul").before($(newDiv))
    $("ul").after($("<div>5</div>"))
    
    // 删除
    newLi.remove() // 删除自身
    $("ul").empty() // 删除自身所有子元素,但是不删除自身
    newDiv.html("") // 删除自身所有子元素,但是不删除自身
    newDiv.text("123")
    newDiv.html("<span>789</span>")
    
</script>

八、事件绑定

使用 on 来进行事件绑定,使用 one() 来添加一次性事件绑定。

语法:on(events,[selector],[data],fn)

1. 绑定多个事件

$("div").on("mouseenter mouseout", function(){
    // 这里不能携程".pink""
    $(this).toggleClass("pink")
})

2. 对象形式传参

$("div").on({
    "mouseenter": function(){
        console.log("mouseenter");
    }, 
    "mouseout": function(){
        console.log("mouseout");
    }
})

3. 数据传递

function myHandler(event) {
alert(event.data.foo);
}
$("p").on("click", {foo: "bar"}, myHandler)

4. 事件委派

事件委派只能是将后代元素的事件委派给父元素来处理,第三个参数就是要进行委派的子元素,注意必须是后代。

举个栗子🌰:

<script>
    // 设置自身子元素的事件委派
    $("ul").on("mouseenter mouseout", "li", function () {
        $(this).toggleClass("pink")
    });

    // 子元素
    $(".box").on("mouseenter mouseout", ".childDiv", function () {
        $(this).toggleClass("pink")
    });

    // 后代元素
    $(".box").on("mouseenter mouseout", ".grandsonDiv", function () {
        $(this).toggleClass("pink")
    });
</script>

5. 动态元素事件绑定

即使符合选择器的要求,事件绑定之后创建的元素也不会有对应的事件,而 on 是动态的,即使在 on 函数之后创建的元素,也具备对应的事件。

注意:仅限事件委派条件下

举个栗子:

<script>
    // 不影响后续动态创建的li
    $("ul>li").click(function(){
        console.log("normal-click");
    })

    // 不影响后续动态创建的li
    $("ul>li").on("click", function(){
        console.log("on--click");
    })

     // 影响后续动态创建的li
    $("ul").on("click", "li", function(){
        console.log("on-delegate-click");
    })

    $("ul").append($("<li>5</li>"))
</script>

结果:


on函数的事件委派和动态创建

on 的这个特性其实很有用,在动态列表页的需求上,利用 on + 事件委派可以保证每一个 cell 都具备相同的事件。否则就需要创建之后再添加对应的事件,稍微麻烦。

6. 一次性事件绑定

意义:绑定的事件只执行一次。one 方法不能进行委托绑定,不需要解绑。

语法:one(type,[data],fn)

使用 one 绑定的事件如果在执行之前被解绑了,那么就不会执行。但是,必须使用 off() 来解除所有事件绑定,只使用 off("eventName") 并不会解除所有绑定。

示例代码:

$("ul>li").one("click", function(){
    console.log("click");\
})

7. 事件解绑

意义:用 off 来解绑使用 on 绑定的时间,one() 事件不需要解绑,但可以使用 off() 来解除所有事件绑定的同时一并解除。

语法:off(events,[selector],[fn])

用法:

  1. 解绑所有事件
  2. 结束特定事件
  3. 解除事件委托

示例代码:

// 解除 li 的所有绑定事件
$("ul>li").off()
// 解除 ul 的所有绑定事件,包括委托事件
$("ul").off()
// 解除特定事件
$("ul>li").first().off("click", "li")

8. 自动触发事件

ele.event():直接调用
trigger():自动触发,但是会触发元素默认行为,比如光标
triggerHandle():自动触发,不会触发元素默认行为

示例代码:

$("input").focus(function(){
    console.log("focus");
})
// 触发默认行为
$("input").focus()
$("input").trigger("focus")
// 不触发默认行为
$("input").triggerHandler("focus")

9. 事件对象

10.

九、jQuery其他使用

1. 拷贝对象

浅拷贝:被拷贝的对象中包含对象时,拷贝的是地址,对象属性不递归合并。
深拷贝:被拷贝的对象中包含对象时,产生新的对象,拷贝的是新对象的地址,对象属性会进行递归合并。

举个栗子🌰:

var targetObj = {classMsg: {
    rank: "1"
}}
var obj = {
    name: "Jack",
    age: 18,
    classMsg: {
        classNo: "201",
        studentNo: "001"
    }
}

浅拷贝:

// 浅拷贝只拷贝内存地址
$.extend(targetObj, obj);
targetObj.classMsg.studentNo = "002"
console.log(obj.classMsg.studentNo); // 002
// 浅拷贝不递归合并
console.log(targetObj.classMsg); // classMsg包含classNo、studentNo

深拷贝:

// 深拷贝是创建一个新的对象
$.extend(true, targetObj, obj);
targetObj.classMsg.studentNo = "002"
console.log(obj.classMsg.studentNo); // 001
// 深拷贝会递归合并
console.log(targetObj.classMsg); // classMsg包含classNo、studentNo、rank

总结:

  1. 拷贝时,非对象属性冲突都会覆盖;
  2. 对象属性在深拷贝时,会递归合并,即属性不冲突时会合并,属性冲突时会覆盖;
  3. 对象属性在💰拷贝时,该对象属性会被直接覆盖,不会递归合并;
  4. 深浅拷贝针对的是对象属性而言;

2. 多库共存

原因:因为 可以用来命名函数,所以多个三方库可能存在 `` 冲突;
目的:解决冲突;

方案:

  • 使用 jQuery 来代替 $
  • 使用 $.noConflict() 或者 jQuery.noConflict()自定义前缀;

代码如下:

$(function(){
    // 自定义名为$的函数
    function $(ele){
        return document.querySelector(ele)
    }
    console.log($("div"));
    // 此时使用 $ 调用 jQuery 方法就会报错
    // $.each()

    // 方案一:使用 jQuery 代替 $
    jQuery.each();

    // 方案二:自定义前缀
    var heheda = jQuery.noConflict()
    console.log(heheda("div")[0]);
})
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,312评论 5 473
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,578评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,337评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,134评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,161评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,303评论 1 280
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,761评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,421评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,609评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,450评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,504评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,194评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,760评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,836评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,066评论 1 257
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,612评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,178评论 2 341