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') );//
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') );//
既然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引擎内部数据运算,消耗的资源要大很多,对性能和体验会造成很大的影响。
jQuery使用(六):DOM操作之元素包裹、克隆DOM与data的综合应用的更多相关文章
- jQuery碎语(1) 基础、选择要操作的元素、处理DOM元素
1.基础 jquery对象集: $():jquery对象集合 获取jquery对象集中的元素: 使用索引获取包装器中的javascript元素:var temp = $('img[alt]')[0] ...
- jQuery 第二章 实例方法 DOM操作选择元素相关方法
进一步选择元素相关方法: .get() .eq() .find() .filter() .not() .is() .has() .add()集中操作 .end()回退操作 .get() $(&qu ...
- AJAX-URL-HTTP协议-缓存-DOM操作-HTML元素事件
1.URL 1.URL的作用 用于来表示任意一个资源的位置(互联网上). 协议+主机名+文件目录结构+文件名称 2.详解 格式: <scheme>://<user>:<p ...
- 前端性能优化--为什么DOM操作慢? 浅谈DOM的操作以及性能优化问题-重绘重排 为什么要减少DOM操作 为什么要减少操作DOM
前端性能优化--为什么DOM操作慢? 作为一个前端,不能不考虑性能问题.对于大多数前端来说,性能优化的方法可能包括以下这些: 减少HTTP请求(合并css.js,雪碧图/base64图片) 压缩( ...
- JQuery DOM操作:设置内容&属性&添加元素&插入元素&包裹&克隆&移除&替换
JQuery text().html().val() $(elem).text(str):添加文本内容str到elem类型元素,返回jQuery对象 $(elem).text():返回第一个elem标 ...
- jQuery中的DOM操作------复制及包裹节点
1.复制节点: 如果单击<li>元素后需要再复制一个<li>元素,可以用clone()方法来完成: $(this).clone().appendTo("ul" ...
- JQuery能够高效地操作页面元素
关于DOM和CSS的页面元素选择: $("span"); //全部span元素 $("#elem"); //id为elem的元素 $(".c ...
- javascript的DOM操作获取元素
一.document.getElementById() 根据Id获取元素节点 <div id="div1"> <p id="p1"> ...
- dom操作------获取元素的若干方法
// 1,getElementById:返回元素节点document.getElementById(); // 2,getElementsByClassName:返回HTMLCollection对象( ...
随机推荐
- 【BZOJ3771】Triple 生成函数 FFT 容斥原理
题目大意 有\(n\)把斧头,不同斧头的价值都不同且都是\([0,m]\)的整数.你可以选\(1\)~\(3\)把斧头,总价值为这三把斧头的价值之和.请你对于每种可能的总价值,求出有多少种选择方案. ...
- 前后端分离之vue2.0+webpack2 实战项目 -- html模板拼接
对于前后端分离,如何把一个页面的公共部分比如head, header, footer, content等组合成一个完整的html 是一个值得考虑的地方. 对于php,我们可以利用include加载其他 ...
- 【CodeForces 717C】Potions Homework
BUPT 2017 summer training (for 16) #1G 题意 每个人有一个懒惰值,每个任务有个难度,一开始每个人的任务和懒惰值都为\(a_i\),完成任务时间是懒惰值乘以难度,现 ...
- [国家集训队]排队 [cdq分治]
题面 洛谷 和动态逆序对那道题没有什么区别 把一个交换换成两个删除和两个插入 #include <cstdio> #include <cstdlib> #include < ...
- 洛谷CF809C Find a car(数位DP)
洛谷题目传送门 通过瞪眼法发现,\(a_{i,j}=(i-1)\text{ xor }(j-1)+1\). 二维差分一下,我们只要能求\(\sum\limits_{i=0}^x\sum\limits_ ...
- HihoCoder 1511: 树的方差(prufer序)
题意 对于一棵 \(n\) 个点的带标号无根树,设 \(d[i]\) 为点 \(i\) 的度数,定义一棵树的方差为数组 \(d[1..n]\) 的方差. 给定 \(n\) ,求所有带标号的 \(n\) ...
- Write less code
If you find yourself writing a lot of code to do something simple, you're probably doing it wrong. A ...
- 【CF891C】Envy(最小生成树)
[CF891C]Envy(最小生成树) 题面 Codeforces 洛谷 题解 考虑\(MST\)的构建过程,对于所有权值相同的边一起考虑. 显然最终他们连出来的结果是固定的. 把连边改为把联通块联通 ...
- 使用matplotlib.pylab绘制分段函数
1.安装matplotlib pip3 install matplotlib sudo apt install python3-tk 2.分段函数 from pylab import * x = li ...
- cf351B Jeff and Furik (树状数组)
逆序对数=0的时候,这个数列是有序的 然后交换相邻的,看哪个比较大,逆序对数会加1或减1 Jeff用的是最优策略所以他肯定让逆序对数-1 设f[i]表示Jeff操作前,逆序对数为i,最终的期望次数 那 ...