jQuery使用(六):DOM操作之元素包裹、克隆DOM与data的综合应用

包裹

  • wrap()
  • wrapInner()
  • wrapAll()
  • unwrap()
  • clone()

数据缓存机制

  • data

文档处理(包裹)

1.1.wrap()--将所匹配的元素用其他元素结构化标签包裹起来(实际上就是给指定的元素添加父元素)。参数可以是HTML标记代码字符串;也可以是DOM元素对象;或者是传入一个方法,方法的返回值可以是前面两种情况。

//html
<div class="demo">b</div>
<div class="a">a</div>

//js
$(‘.demo‘).wrap(‘<div class="b">c</div>‘);

上面这个示例展示的结果可以得出一个结论就是通过wrap包裹元素,其实质就是将元素添加到指定的元素的末尾。同时我们又会思考另一个问题,就是通常我们选择的DOM不会只有一个,而是多个,如果执行了wrap()会发什么呢?

//html
<div class="demo">b</div>
<div class="demo">d</div>
<div class="a">a</div>

//js
$(‘.demo‘).wrap( $(‘.a‘) );

从上面的示例可以得到,当jQuery对象是DOM集合时,每个DOM节点上包裹一个指定元素。被指定的元素是DOM节点,相当于拷贝指定的DOM节点(节点的属性会被拷贝,但是内部节点内容不会被拷贝)。最后展示一下function作为参数的语法:

$(‘.demo‘).wrap( function(index){
    //index表示当前正在执行被包裹的元素的jQuery索引
    return ‘<div class="wrapper‘+ index +‘"></div>‘;
} );

既然前面我们讲到当调用wrap()方法的jQuery对象是DOM集合时,执行的是每个节点上包裹一个指定的元素。如果一个节点集合需要被一个指定的元素包裹怎么办呢?jQuery给我们提供了wrapInner()方法。

1.2.wrapAll()--将调用wrapAll方法的jQuery对象包含的所有的DOM节点包裹在一个指定的元素内,如果DOM集合的节点不是兄弟节点,会以第一个获取到的节点为基础,将其他节点剪切到第一个节点的下方,作为第一个节点的兄弟节点,再执行统一包裹。参数可以是HTML标记代码字符串,也可以是DOM节点。

//html
<div class="a">
    <div class="demo">
        <p>
            <span class="demo"></span>
        </p>
        <div class="demo"><a></a></div>
    </div>
</div>
<p class="demo"></p>

//js
$(‘.demo‘).wrapAll(‘<div class="wrapper"></div>‘);

1.3.wrapInner()--将每一个DOM节点的内容被指定的元素包裹起来。参数可以是HTML标记代码字符串,DOM节点对象,也可以是方法,语法类似wrap。

//html
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
</ul>

//js
var hrefArr = ["www.baidu.com","www.1688.com","www.qq.com","www.huawei.com.cn","www.136.com"];
$(‘ul li‘).wrapInner(function(index){
    return ‘<a href=" ‘+ hrefArr[index] + ‘ "></a>‘;
});//实例中的每个li内的数字会被包裹在a标签内,当然也可以包裹元素。

1.4.unwrap()--用来移除被选元素的父元素。

//html
<div class="aa">
    <p class="bb"><span class="cc"></span></p>
</div>

//js
$(‘.cc‘).unwrap();

方法内也可以添加参数(选择器),用来移除指定的元素,比如上面的示例可以添加‘p’实现的效果是一样的,如果添加‘div‘就不能删除父元素了。这个参数起到的筛选的作用。

1.5.clone()--生成备选元素的副本,包含子节点文本和属性(非特性属性也可以被克隆);元素上绑定的事件需要传入boolean值来指定是否被一并克隆。

//html
<div class="demo" style="width: 100px;height: 100px;background-color: red;" data-cst="duyi"></div>

//js
$(‘.demo‘).clone(true).appendTo(‘body‘);

关于克隆的一个小demo:

//html
<table class="stb">
    <tr>
        <th>名字</th>
        <th>年龄</th>
        <th>班级</th>
    </tr>
    <tr class="tpl">
        <td></td>
        <td></td>
        <td></td>
    </tr>
</table>

//css
.tpl{
    display: none;
}

//js
var studentArr = [
    {
        name: ‘小明‘,
        age : 18,
        class: 3
    },
    {
        name: ‘小红‘,
        age: 19,
        class: 2
    },
    {
        name: ‘小李‘,
        age: 50,
        class: 1
    }
];
var oWrapper = $(‘.stb‘);
studentArr.forEach(function(ele,index){
    var oCloneDom = $(‘.tpl‘).clone().removeClass(‘tpl‘);
    oCloneDom
        .find(‘td‘)
            .eq(0)
                .text(ele.name)
                    .next()
                        .text(ele.age)
                            .next()
                                .text(ele.class);
    oWrapper.append(oCloneDom);
});

文档处理与数据缓存机制

在关于clone()方法的解析中,说克隆一个元素时可以复制其子节点内容、属性、特性、甚至绑定的事件都可以复制,这好像是说元素上的所有内容都可以被复制。但是真的是这样的吗?请看下列代码:

<div class="demo"  data-cst="duyi"></div>

$(‘.demo‘).prop(‘data-log‘,‘1111‘);
console.log( $(‘.demo‘).prop(‘data-log‘) );//1111
console.log( $(‘.demo‘).data(‘log‘) );//undefined
console.log( $(‘.demo‘).data(‘cst‘) );//duyi
console.log( $(‘.demo‘).clone().prop(‘data-log‘) );//undefined
console.log( $(‘.demo‘).clone().data(‘log‘) );//undefined
console.log( $(‘.demo‘).clone().data(‘cst‘) );//duyi

其实这时候你打开控制台可以看到元素通过prop()方法添加的属性并没有出现在元素上,其prop()是用来添加特性使用,但是它在一定程度上可以用来存储数据,这种数据的缓存方式不能被clone()方法复制到,但是通过prop()方法添加的特性是可以被复制的,并且通过查看控制台可以看到添加的特性会出现在标签上。

$(‘.demo‘).prop(‘id‘,‘12‘);
console.log( $(‘.demo‘).clone().prop(‘id‘) );//12

既然prop()实现的数据缓存机制不能被拷贝,那通过data()方法实现的数据缓存能否被拷贝呢?

$(‘.demo‘).data({
    name:"小明",
    age:18,
    class:3
});
console.log( $(‘.demo‘).data(‘name‘) );//‘小明‘
console.log( $(‘.demo‘).clone().data(‘name‘) );//undefined

还是不能!

那为什么还需要data来缓存数据呢?相信细心的朋友已经发现了前面代码埋下的伏笔,在第一个示例中的元素上通过字面量的方式添加了data-cst="duyi"这个属性,可以被jQuery的data()数据存储机制解析成为键值对的数据;在第三个示例中展示了直接通过data()方法传入对象的方式添加缓存数据,这些操作相比prop()方便的多了,并且功能上更加语义化。然后还有一个更重要的因素就是通过prop()获取的值都是字符串类型,而通过data()获取的值和存储的值是一致的。

然而这些还并不是最关键的原因,下面我们通过一个示例来实际应用data()方法处理一个业务模型:

//html
<!-- 模拟购物车勾选结算商品 -->
<div class="wrapperData">
    <div class="tplData">
        <p></p>
        <span></span>
        <button>add</button>
    </div>

    <p class="showData">
        <span>sum</span>
        <span class="sum">0</span>
    </p>
</div>

//css
.tplData{
    display: none;
}

//js
//模拟购物车勾选结算商品
var shopArr = [
    {
        name: ‘james solider‘,
        shopName: ‘nike‘,
        price: 110,
        id: ‘1001‘
    },
    {
        name: ‘Rose crazyLight‘,
        shopName: ‘adidas‘,
        price: 90,
        id: ‘2002‘
    },
    {
        name: ‘curry one‘,
        shopName: ‘Under Armour‘,
        price: 120,
        id: ‘3003‘
    }
];

shopArr.forEach(function(ele,index){
    var oCloneDom = $(‘.tplData‘).clone().removeClass(‘tplData‘);
    oCloneDom.data({
        id:ele.id,
        name:ele.name,
        shopName:ele.shopName,
        price:ele.price
    }).find(‘p‘)
            .text(ele.name)
                .next()
                    .text(ele.price);

    oCloneDom.insertBefore(‘.showData‘);
});
//勾选结算商品
$(‘.wrapperData button‘).click(function(){
    $(‘.sum‘).text( +$(‘.sum‘).text() + $(this).parent().data(‘price‘) );
});

从我们常见的购物车结算示例来看,当点击行为触发选中商品时,我们需要调取对应商品的数据进行结算操作,在示例中,将商品对应的数据通过data()绑定在DOM节点对应的jQuery对象上,就有了后面结算时直接通过jQuery对象的data()方法进行获取。如果通过prop()和attr()方法来存储数据,每一次存储和每一次获取都要操作DOM,相信大家都知道通过浏览器的js引擎调用浏览器的DOM引擎的接口来进行数据交互,比纯粹的js引擎内部数据运算,消耗的资源要大很多,对性能和体验会造成很大的影响。

原文地址:https://www.cnblogs.com/ZheOneAndOnly/p/10343135.html

时间: 2024-11-06 07:10:21

jQuery使用(六):DOM操作之元素包裹、克隆DOM与data的综合应用的相关文章

jQuery碎语(1) 基础、选择要操作的元素、处理DOM元素

1.基础 jquery对象集: $():jquery对象集合 获取jquery对象集中的元素: 使用索引获取包装器中的javascript元素:var temp = $('img[alt]')[0] 使用jquery的get方法获取jquery对象集中的javascript元素:var temp = $('img[alt]').get(0) 使用jquery的eq方法获取jquery对象集中的jquery对象元素: $('img[alt]').eq(0) $('img[alt]').first(

DOM操作HTML元素属性

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>DOM操作HTML元素属性</title> </head> <body> <ul> <li></li> <li></li> <li></li> <

jQuery遍历和过滤操作所有元素

1 遍历祖先  方法 parent()返回一个直接父元素 parents()返回所有祖先直到根元素<html>  可以添加参数过滤 parentsuntil()不添加参数同上 添加参数 返回与参数之间的父元素不包括参数自身 2 遍历子孙  方法 children() childrens() childrensuntil() contents()没有参数 ,不仅查找子元素,同时获得文本节点,解释节点等类似于childNodes 不过他返回的是jQuery对象 3 水平遍历 siblings()方

jQuery中的DOM操作------复制及包裹节点

1.复制节点: 如果单击<li>元素后需要再复制一个<li>元素,可以用clone()方法来完成: $(this).clone().appendTo("ul"); 复制节点后,被复制的新元素不具有任何行为,如果需要新元素也具有复制功能,可以这么写: $(this).clone(true).appendTo("ul"); 2.包裹节点:wrap()&warpAll()&wrapInner() 如下代码: <strong t

javascript基础dom操作html元素

语法:document.getElementById("id"); 举例:<script> window.onload = funtion () { var oDiv = document.getElementById("div1");// js选择html元素id元素 oDiv.style.color = "red";//js控制html元素css样式color颜色: } <script> <body> &l

jQuery08源码 (5140 , 6057) DOM操作 : 添加 删除 获取 包装 DOM筛选

jQuery.fn.extend({ //$('ul').find('li').css('background','red'); //$('ul').find( $('li') ).css('background','red'); find: function( selector ) { var i, ret = [], self = this, len = self.length; if ( typeof selector !== "string" ) {//$('li') //jQ

jquery16 DOM操作 : 添加 删除 获取 包装 DOM筛选

<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>无标题文档</title> <script src="jquery-2.0.3.js"></script> <script> 一些变

jquery17 DOM操作 : 添加 删除 获取 包装 DOM筛选

<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>无标题文档</title> <script src="jquery-2.0.3.js"></script> <script> $(f

Jquery基础之DOM操作

 一.jQuery对象与Dom对象的区别 一直以来对于通过jQuery方式获取的对象使不能直接使用JavaScript的一些方法的,开始的时候不理解,现在此案知道,原来jQuery获得的对象并不和我们平时使用getElementById获得的对象是一样的对象.所以一些新手就很迷惑,为什么${”#Element”}不能直接innerHTML,这就是原因所在,解决方式请看下文. jQuery对象与dom对象的转换只有jquery对象才能使用jquery定义的方法.注意dom对象和jquery对象是有