jQuery-DOM操作

原生JS进行DOM创建节点及节点属性

事先不确定HTML结构,需要JS动态的处理节点。
这就包括了创建节点属性创建节点样式两部分内容,
其中,创建的大致流程为:

  1. 创建节点
  2. 添加节点的一些属性
  3. 加入到文档中

这个流程中涉及到的方法:

  • 创建元素document.createElement,
  • 设置属性setAttribute,
  • 添加文本innerHTML,
  • 加入文档appendChild

JS实现元素创建会有几个问题:

  1. 每个元素节点都必须单独创建
  2. 节点的属性需要单独设置,而且设置的接口不统一
  3. 添加到指定的元素位置不灵活
  4. 兼容问题

jQuery节点创建与属性的处理

1创建元素节点:
直接把这个节点的结构通过HTML标记字符串描述出来,通过$()函数处理,$("html结构“)
譬如$("<div></div>")
2创建文本节点:
直接把文本内容一并描述
譬如$("<div>这是文本节点</div>")
3创建属性节点:
譬如$("<div id="test" class="demo">这是文本节点</div>")

然而啊,光光动态创建元素是不够的,它只能临时存放在内存中,还差最后一步将其在页面文档中呈现出来.

内部插入之append/appendTo

这就涉及到一个位置的问题,常见的办法是将新建的节点作为某一个节点的子节点放其内部,

  • append(content)    向每个匹配的元素内部追加内容,该操作和原生JS的appendChild方法类似
  • appendTo(content)  把所有匹配的元素追加到另一个指定的元素集合中,该方法颠倒了常规的$(A).append(B),不是将B追加到A中,而是把A追加到B中

append()和appendTo()的区别:

  1. append()前面是被插入的对象,后面是要在对象内插入的新内容
  2. appendTo()前面是要被插入的新内容,后面才是将被插入的对象

好,以上学习的是如何插入一个新创的节点,还是在节点内部插入,这就不得不考虑节点插入时节点之间的关系,只有知道了这些关系才能够知道插到哪里去.

外部插入之after/before

节点和节点之间有父子,祖辈,兄弟关系,其中兄弟关系就是外部插入的处理.

  • .after(content) 在匹配元素集合中的每个元素后面插入参数所指定的内容,作为其兄弟节点
  • .before(content) 据参数设定,在匹配元素的前面插入内容

.after()和.before()的异同:

  1. before和after都是用来相对选中元素外部增加相邻的兄弟节点
  2. before和after都可以接收HTML字符串,DOM元素,元素数组,jQuery对象
  3. before和after都支持多个参数传递
  4. after向元素的后边添加HTML代码,如果元素后原本就有元素了,那就将后面原有的元素后移,把HTML代码插进去
  5. before向元素前面添加HTML代码,如果元素前原本就有元素了,那就将前面原有的元素前移,把HTML代码插进去

内部插入的方法再具体讲一讲.

内部插入之prepend/prependTo

在元素内部操作的方法,除了之前提到的append和appendTo,还有的:

  • prepend     向每个匹配元素内部前置内容,也就是说,将要添加的内容插入到目标元素内部作为其第一个子元素,这么一说,之前提到的append()就是将指定元素作为最后一个元素插入
  • prependTo 把所有匹配的元素前置到另一个指定的元素集合中

prepend()和prependTo()的区别:

  1. .prepend()将选择器表达式写在方法的前面,作为待插入内容的容器,将要被插入的内容作为方法的参数
  2. .prependTo()将要被插入的内容写在方法的前面,可以是选择器表达式或动态创建的标记,待插入内容的容器作为参数

append()和appendTo()与prepend()和prependTo()的区别:

  1. append()向每个匹配的元素内部追加内容
  2. prepend()向每个匹配的元素内部前置内容
  3. appendTo()把所有匹配的元素追加到另一个指定元素的集合中
  4. prependTo()把所有匹配的元素前置到另一个指定的元素集合中

既然内部插入有补充,那也补充一下外部插入

外部插入之insertBefore/inertAfter

  • insertBefore  在目标元素前面插入集合中每个匹配的元素,如果元素前面有元素了,那将前面的元素前移,然后将新对象插入;
  • inertAfter    在目标元素后面插入集合中每个匹配的元素,如果元素后面有元素了,那将后面的元素后移,然后将新对象插入

.before()和.after()与.insertBefore()和.inertAfter()的区别:

  1. .before()选择表达式在函数前面,内容作为参数
  2. .insertBefore()内容在方法前面,它将被方法参数里元素的前面
  3. .after()选择表达式在函数的前面,参数是将要插入的内容
  4. .insertAfter()内容在方法前面,它将被放在参数里元素的后面

上述都是新增节点插入,那么该如何删除呢?

删除操作

其中删除操作中有一个empty()方法.
empty和常规删除不一样,它只移除指定元素的所有子节点,不仅移除子元素(和其他后代元素 ),而且可移除元素里的文本

<div class="demo"><p>这就是测试</p></div>
<!--使用empty()方法移除div中所有元素-->
<script>
$(".demo").empty();
</script>
<!--结果会移除<p>这就是测试</p>,剩下了<div class="demo"></div> -->

还有一个删除的方法remove()
这个方法和empty()同效,但是它比empty()多一点,它可以把自身也移除掉,包括绑定的事件和该元素相关的jQuery数据
譬如,一段绑定了事件的节点:

<div class="demo"><p>这就是个测试嘛</p></div>
<script>
$(".demo").on("click",fn)
</script>

使用remove()方法移除div及其内部所有元素,它会自动销毁事件

$(".demo").remove();

remove()方法还很灵活,它可以传递一个选择器表达式用来过滤将被移除的匹配元素集合,可以选择性的删除指定的节点

现在已经有两个删除的方法了,对比一下它们还是有一定的区别:

empty()

  1. 严格地讲,它不是删除节点,而是清空节点,清空元素中所有后代节点
  2. empty不能删除自己本身这个节点

remove()

  1. 需删除的节点和该节点包含的所有后代节点会被同时删除
  2. 可传递一个筛选的表达式,删除指定合集中的元素

我们想要的不仅仅是这点,我们希望临时删除页面上的节点,但又希望节点上的数据和事件不丢失,并且在下一个时间段恢复这个删除掉的节点,那么之前的两个删除方法就不够看的了.

这可以使用detach方法来处理.
detach(),让一个web元素托管,即从当前页面中移除元素,但保留这个元素的内存模型对象.
来看看jquery官方文档的解释:

这个方法不会把匹配的元素从jQuery对象中删除,因而可以在将来再使用这些匹配的元素。
与remove()不同的是,所有绑定的事件、附加的数据等都会保留下来。
譬如$("div").detach()这一句会移除对象,仅仅是显示效果没有了。
但是内存中还是存在的。当你append之后,又重新回到了文档流中,这就又显示出来了。

<input id="btn1" type="button" value="撤销">
<input id="btn2" type="button" value="重置">
<p>这就是测试嘛!</p>
<script>
    var p;
    $("#btn1").click(function(){
        if(!$("p").length) return;
        p = $("p").detach();
    });
    $("#btn2").click(function(){
        $("body").append(p);
    })
</script>

学习是需要总结的嘛,刚学了detach方法,那detach()和之前的remove()也是有些区别
remove()

  1. 无参数,移除自身整个节点及其内部所有节点,也包括节点上的事件和数据
  2. 有参数,移除筛选出来的节点以及该节点内部所有节点,也包括节点上的事件和数据

detach()

  1. 移除的处理与remove一致
  2. 与remove()不同的是,所有绑定的事件、附加的数据等都会保留下来

新增插入,删除的常见的操作就这些啦,其它呢,还有很多常见的操作

克隆操作

.clone()方法深度复制所有匹配的元素集合,包括所有匹配的元素、匹配元素的下级元素、文字节点。
但是,在需要操作的节点上有绑定的事件或数据时,clone()需要传递一个布尔值true用来指定,这样就可以将附带的事件一并克隆.使用clone()后,在将它插入到文档之前,是可以修改这个克隆的元素,譬如可增加一个颜色$("p").clone().css("color","red");

替换操作

.replaceWith(newContent),用新内容替换掉集合中所有匹配的元素并且返回被删除元素的集合
也就是说,用$()选择一个目标节点,调用replaceWith()方法,传入一个新的内容B用来替换掉A,这个B可以是HTML字符串,DOM元素,jQuery对象
譬如

<div>
    <p>这是一个测试</p>
    <p>这是一个测试</p>
    <p>这是一个测试</p>
</div>

我现在想要将第二个段落内容换掉.

$("p:eq(1)").replaceWith("<a style='color:red'>")这是一个替换测试</a>");

还有一个替换的同源操作
.replaceAll(target),用集合的匹配元素替换每个目标元素
譬如,还是上面的HTML结构,若要得到相同的结果,则需要这样写:

$("<a style='color:red'>")这是一个替换测试</a>"),replaceAll("p:eq(1)");

所以呢,关于替换操作的两个方法,功能是相似的,主要就是目标和源的位置不一样

  1. .replaceWith()与.replaceAll() 方法会删除与节点相关联的所有数据和事件处理程序
  2. .replaceWith()方法,和大部分其他jQuery方法一样,返回jQuery对象,所以可以和其他方法链接使用
  3. .replaceWith()方法返回的jQuery对象引用的是替换前的节点,而不是通过replaceWith/replaceAll方法替换后的节点

包裹操作

所谓包裹也就是增加一个父元素,假设有一堆p标签,我想要将它们放在一个div中,用包裹就可以增加一个div父元素
.wrap(wrappingElement),在集合中匹配的每个元素周围包裹一个HTML结构

<p>这是一个测试</p>
<!--给p元素增加一个div包裹: -->
<script>
$("p").wrap("<div></div>");
<script>

还有一个同效不同样的写法,
.wrap(function),一个回调函数,返回用于包裹匹配元素的HTML内容或jQuery对象
上面的例子的不同写法:

$("p").wrap(function(){
    return "<div></div>";
})

需要注意的是,.wrap()函数可以接受任何字符串或对象,可以传递给$()工厂函数来指定一个DOM结构。
这种结构可以嵌套了好几层深,但应该只包含一个核心的元素。每个匹配的元素都会被这种结构包裹。
该方法返回原始的元素集,以便之后使用链式方法。

反包裹操作

既然可以增加包裹,那就可以反包裹嘛,也就是说可以删除选中元素的父元素呀
unwrap(),将匹配元素集合的父级元素删除,保留自身(和存在的兄弟元素)在原来位置
譬如,

<div>
    <p>这是一个测试</p>
</div>

先要删除这个div,可以用之前学到的remove和empty直接删除,但是我想保留其中的p元素及内容,那两个方法就不行了

$("p").unwrap();

找到p元素,然后调用unwrap方法,这样只会删除父辈div元素了

无论是包裹还是反包裹,它们操作的都是单一元素,如果想要将集合中的元素用其他元素包裹起来,也就是给他们增加一个父元素,那该怎么办呢?
.wrapAll(wrappingElement),给集合中匹配的元素增加一个外面包裹HTML结构

<p>这是一个测试</p>
<p>这是一个测试</p>
<!--给这两个p元素增加一个div包裹: -->
<script>
$("p").wrapAll("<div></div>");
</script>

.wrapAll( function ),一个回调函数,返回用于包裹匹配元素的 HTML 内容或 jQuery 对象
这是和wrap()同效不同样的写法,
上面的例子的不同写法:

$("p").wrapAll(function(){
    return "<div></div>";
})

结果:给两个p元素分别增加一个父元素

这样嵌套的操作还是太简单了,如果将合集中元素的内部子元素给包裹起来,并当做制定元素的子元素,那么之前的方法又无法简单的实现了
.wrapInner(wrappingElement),给集中匹配的元素的内部,增加包裹的HTML结构

!!! 至此,对于.wrapInner我之前的理解应该是错了,通过自己测试证明原来想的就是错的 !!!

测试demo:

<div id="demo">
    <p>这是个测试</p>
    <p>这是个测试</p>
    <p>这是个测试</p>
    <div>这就是个测试嘛</div>
</div>
<script>
    $("p").wrapInner("<div></div>");
</script>

原本想法:通过.wrapInner会将三个P元素用div包裹起来作为demo元素的子元素呢
看了结果发现是每个p元素中的文本节点被div包裹起来了
原本想法的实现:用wrapAll()包裹三个p元素.

通常实际运用中所写的jQuery是个合集对象,如果想要快速查找其中的某元素,就需要遍历操作

childern()方法

.children(selector)方法是返回匹配元素集合中每个元素的所有子元素(仅儿子辈,这里可以理解为就是父亲-儿子的关系)
举个栗子,形象的展示children()有无参数的情况:

<div>
    <div class="demo">
        <p>这是个测试</p>
        <p>这是个测试</p>
    </div>
    <div class="demo">
        <p>这是个测试</p>
        <p>这是个测试</p>
    </div>
</div>
<input id="btn1" type="button" value="按钮1">
<input id="btn2" type="button" value="按钮2">

<script>
    $("#btn1").click(function(){
        $(".demo").children().css("border","1px solid red");
    });
    $("#btn2").click(function(){
        $(".demo").children(":last").css("border","2px solid blue");
    });
</script>

find()方法

快速查找DOM树中的目标元素的后代元素,这里要注意哦,后代元素意味着包含父子关系
需要注意的点:

  1. find是遍历当前元素集合中每个元素的后代。只要符合,不管是儿子辈,孙子辈都可以。
  2. 与其他的树遍历方法不同,选择器表达式对于.find()是必需的参数。如果我们需要实现对所有后代元素的取回,可以传递通配选择器 '*'。
  3. find只在后代中遍历,不包括自己。
  4. 选择器context是由.find()方法实现的。因此,$('.item-ii').find('li') 等价于 $('li', '.item-ii')(找到类名为item-ii的标签下的li标签)。
<div class="demo">
    <div>
        <p>这是个测试</p>
        <p>这是个测试</p>
    </div>
    <div>
        <p>这是个测试</p>
        <p>这是个测试</p>
    </div>
</div>
<input type="button" value="按钮1">

<script>
    $("input").click(function(){
        $(".demo").find("p:last").css("border","1px solid red");
    })
</script>

find()和children()区别:

  1. children只查找第一级的子节点
  2. find查找范围包括子节点的所有后代节点

parent()方法

快速查找合集里面的每一个元素的父元素,这里可以理解为就是父亲-儿子的关系,多一级的祖父的级别都不行

parents()方法

快速查找合集里面的每一个元素的所有祖辈元素

parent()和parents()区别:

  1. .parent()方法只是进行了一个单级的DOM树查找
  2. $( "html" ).parent()方法返回一个包含document的集合,而$( "html" ).parents()返回一个空集合。

以选定的元素为中心,往内查找可以通过find、children方法。如果往上查找,也就是查找当前元素的父辈祖辈元素,可以用parent()和parents()
在查找当前元素的父辈祖辈元素,还有一个方法,

closest()方法

从元素本身开始,在DOM 树上逐级向上级元素匹配,并返回最先匹配的祖先元素
它接受一个匹配元素的选择器字符串

.parents()和.closest()的区别:

  1. 起始位置不同:.closest开始于当前元素 .parents开始于父元素
  2. 遍历的目标不同:.closest要找到指定的目标,.parents遍历到文档根元素,closest向上查找,直到找到一个匹配的就停止查找,parents一直查找到根元素,并将匹配的元素加入集合
  3. 结果不同:.closest返回的是包含零个或一个元素的jquery对象,parents返回的是包含零个或一个或多个元素的jquery对象

next()方法

快速查找指定元素集合中每一个元素紧邻的后面同辈元素的元素集合

<div>
    <div><p>这是个测试</p></div>
    <div><p>这是个测试</p></div>
    <div class="demo"><p>这是个测试</p></div>
</div>
<input id="btn1" type="button" value="按钮1">
<input id="btn2" type="button" value="按钮2">

<script>
    $("#btn1").click(function(){
        $(".demo").prev().css("border","1px solid red");
    });
    $("#btn2").click(function(){
        $(".demo").next(":last").css("border","2px solid blue");
    });
</script>

prev()方法

快速查找指定元素集合中每一个元素紧邻的前面同辈元素的元素集合
其实吧,next()找它的下一个兄弟,prev()找它的上一个兄弟

siblings()方法

快速查找指定元素集合中每一个元素的同辈元素

add()方法

.add()用来创建一个新的jQuery对象,元素添加到匹配的元素集合中
.add()的参数可以几乎接受任何的$(),包括一个jQuery选择器表达式,DOM元素,或HTML片段引用。
举个栗子,将p元素也添加到li的合集中

<ul>
    <li>这就是个测试</li>
    <li>这就是个测试</li>
</ul>
<p>这还是个测试</p>
<input type="button" value="按钮">

<script>
    $("input").click(function(){
        $("li").add("p").css("color","red");
    })
</script>

each()方法

.each() 方法就是一个for循环的迭代器,它会迭代jQuery对象合集中的每一个DOM元素。
每次回调函数执行时,会传递当前循环次数作为参数(从0开始计数)
注意点:

  1. each是一个for循环的包装迭代器
  2. each通过回调的方式处理,并且会有2个固定的实参,索引与元素
  3. each回调方法中的this指向当前迭代的dom元素
<ul>
    <li>这就是个测试</li>
    <li>这就是个测试</li>
    <li>这就是个测试</li>
    <li>这就是个测试</li>
    <li>这就是个测试</li>
    <li>这就是个测试</li>
</ul>
<input type="button" value="按钮">

<script>
    $("input").click(function(){
        $("li").each(function(index,element){
            if(index % 2){
                $(this).css("color","red");
            }
        })
    })
</script>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值