上一篇讲了 wrap(),它是在选中元素的外面套一层容器。而 wrapInner() 正好相反——它是在选中元素的里面,把原有的内容用新元素包起来。这个区别很关键,两个方法名字只差一个 Inner,但操作的位置不同。
举个例子可能更好理解。假设有一段 HTML:
<p>学习 jQuery 编程</p>
执行 $("p").wrap("<div class='outer'></div>") 后变成:
<div class="outer"><p>学习 jQuery 编程</p></div>
而执行 $("p").wrapInner("<span class='inner'></span>") 后变成:
<p><span class="inner">学习 jQuery 编程</span></p>
看出来了吧——wrap() 是给元素加个“爹”,wrapInner() 是给元素的内容加个“壳”。两者操作的是 DOM 树的不同层级。
语法形式
$(selector).wrapInner(wrappingElement, function(index))
参数和 wrap() 一致:
wrappingElement(必填):指定用来包裹内容的 HTML 元素。可以是字符串、jQuery 对象或 DOM 元素。
function(index)(可选):回调函数,index 是元素在中的位置索引,函数返回的 HTML 会作为该元素内容的包裹容器。
基础示例:用 em 标签包裹段落内容
下面这个示例点击按钮后,把每个 p 元素里的文字用 <em> 标签包裹起来,文字会变成斜体。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>wrapInner 基础示例</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
</head>
<body>
<p>欢迎学习 jQuery 编程</p>
<p>这是一段示例文字</p>
<button id="wrapInnerBtn">给段落内容包裹 em 标签</button>
<script>
$(document).ready(function(){
$("#wrapInnerBtn").click(function(){
$("p").wrapInner("<em></em>");
});
});
</script>
</body>
</html>
点击按钮后,第一个 p 的内容从纯文本变成了 <em>欢迎学习 jQuery 编程</em>,文字自动变为斜体。p 标签本身还在,只是它的内部被加了一层 em。
多层标签嵌套包裹
wrapInner() 支持一次性包裹多层嵌套标签,只要传的 HTML 字符串里包含了嵌套结构就行。下面这个例子用了 <em>、<b> 和 <marquee> 三层嵌套。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>wrapInner 多层嵌套示例</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
</head>
<body>
<p>学习 jQuery 很有趣</p>
<p>前端开发必备技能</p>
<button id="multiWrapBtn">多层标签包裹内容</button>
<script>
$(document).ready(function(){
$("#multiWrapBtn").click(function(){
$("p").wrapInner("<em><b><marquee></marquee></b></em>");
});
});
</script>
</body>
</html>
点击按钮后,段落内容最内层是 <marquee> 实现滚动效果,外面包了 <b> 加粗,最外层是 <em> 斜体。用开发者工具查看 DOM,能看到清晰的嵌套层级。<marquee> 这个标签虽然已经废弃,但在演示多层包裹的效果上倒是很直观——一眼就能看出内容被成功包裹了。实际项目里可以换成 <span>,语义更规范。
进阶示例:点击方块包裹内容
下面演示一个更互动的例子。页面上有几个方块,每个方块里已经有文字内容。点击任意方块,给它的文字内容包上滚动效果标签。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>wrapInner 进阶示例</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
.card {
margin: 8px;
padding: 12px;
border: 2px solid #555;
width: 140px;
cursor: pointer;
display: inline-block;
text-align: center;
font-weight: bold;
}
</style>
</head>
<body>
<p>点击任意方块给内容加滚动效果:</p>
<div class="card" style="background-color:#f5b7b1;">jQuery 教程</div>
<div class="card" style="background-color:#a9dfbf;">JavaScript 基础</div>
<div class="card" style="background-color:#f9e79f;">HTML 入门</div>
<div class="card" style="background-color:#aed6f1;">CSS 样式</div>
<script>
$(document).ready(function(){
$("div.card").click(function(){
var content = "<marquee><b></b></marquee>";
$(this).wrapInner(content);
});
});
</script>
</body>
</html>
每次点击方块,它的文字内容就会被 <marquee><b> 包裹,文字开始滚动并加粗。注意这里用的是 $(this).wrapInner(),只作用于被点击的那个方块,其他方块不受影响。这与之前用选择器 $("div.card") 批量操作不同,体现了事件处理中 this 的作用域。
wrapInner 的实用场景
说实话,wrapInner() 在日常开发中的出场率不如 wrap() 高,但在特定场景下它确实比其他方式更直接:
-
高亮搜索关键词:用
wrapInner()把匹配到的文字包上<mark>或<span class="highlight">标签。 -
给纯文本内容快速加样式标签:比如原本的
p标签内容没有加粗,现在想统一加一层<b>,不需要改 HTML 模板。 -
动态生成链接:如果某个元素的内容是纯文本 URL,想把它变成可点击的链接,用
wrapInner("<a href='...'>")很顺手。
不过有个地方需要留心:wrapInner() 操作的是元素的所有内容,包括子元素。如果元素内部已经有其他 HTML 标签,这些标签会和文本节点一起被包进新容器。这可能会导致嵌套结构变复杂,用之前先想清楚选中的元素里到底有什么。
本节课程知识要点
-
wrapInner()包裹的是元素内部的内容,跟wrap()包裹元素本身是相反的操作方向。 -
包裹参数支持 HTML 字符串、jQuery 对象和 DOM 元素,HTML 字符串最为常用。
-
多层嵌套包裹只需要在 HTML 字符串中按外层到内层的顺序写好标签结构,jQuery 会自动构建对应的 DOM 层级。
-
回调函数参数让批量操作中可以按元素索引提供不同的包裹内容。
-
使用前确认元素内部的内容结构,如果已有复杂子元素,包裹后可能产生预期之外的嵌套。
wrapInner() 和 wrap() 是一对互补的方法。一个在外层加容器,一个在内层包内容,解决了 DOM 结构动态调整中两个不同方向的需求。把这两个方法放在一起对比着学,会对 jQuery 操作 DOM 元素包裹的机制理解得更透彻。配合之前讲过的尺寸方法,现在可以灵活地获取元素尺寸、创建包裹容器、调整内外结构,前端的 DOM 操作能力已经形成了比较完整的技能闭环。