文章目录
- getBoundingClientRect
- 实例应用
- contenteditable
- contenteditable 属性介绍
- 内部文本选中高亮实例,3秒后高亮消失
- 父元素定位特定子元素内容定位效果
- 方式一:使用JavaScript,在页面加载完成后设置滚动位置(适用于大多数现代浏览器环境)
- 方式二:使用`scrollIntoView`方法(兼容性也较好,更简洁直观)
- 方式三:如果使用一些JavaScript框架(如jQuery,在有相关项目依赖的情况下)
- 高亮选中补充
- ::selection 伪元素
- 应用场景
- 实例
- rangeAt 方法(通常配合 `getSelection` 等一起使用)
- 应用场景
- 实例
- surroundContents
- 综合应用如下
getBoundingClientRect
- 基本概念
getBoundingClientRect
是一个DOM元素的方法,它返回一个DOMRect
对象。这个对象包含了元素相对于视口(viewport)的位置和大小信息。视口是浏览器中网页可见部分,不包括浏览器的工具栏、标签栏等。DOMRect
对象包含的属性主要有:left
:元素左边界相对于视口左边界的距离,包括元素的左边框宽度。right
:元素右边界相对于视口左边界的距离,包括元素的右边框宽度。right - left
的值等于元素的宽度(包括边框)。top
:元素上边界相对于视口上边界的距离,包括元素的上边框宽度。bottom
:元素下边界相对于视口上边界的距离,包括元素的下边框宽度。bottom - top
的值等于元素的高度(包括边框)。width
:元素的宽度,不包括外边距(margin),计算方式为right - left
(考虑边框)。height
:元素的高度,不包括外边距(margin),计算方式为bottom - top
(考虑边框)。x
和y
:x
属性等同于left
,y
属性等同于top
。在某些场景下,使用x
和y
可以让代码更具语义性。
- 应用场景
- 元素定位和碰撞检测
- 在游戏开发中,例如制作一个简单的2D游戏,当需要检测游戏角色(一个DOM元素表示)是否与障碍物(另一个DOM元素)发生碰撞时,可以使用
getBoundingClientRect
。通过获取两个元素的边界信息,比较它们的位置和大小来判断是否碰撞。- 假设游戏中有一个小球(
ball
元素)和一个方块(block
元素),可以这样检测碰撞:
javascript">const ballRect = ball.getBoundingClientRect(); const blockRect = block.getBoundingClientRect(); if (ballRect.right > blockRect.left && ballRect.left < blockRect.right &&ballRect.bottom > blockRect.top && ballRect.top < blockRect.bottom) {// 发生碰撞的逻辑处理,比如改变小球的运动方向等 }
- 假设游戏中有一个小球(
- 在页面布局中,当需要精确控制元素的位置,比如实现一个自定义的弹出框(
popup
),需要让弹出框显示在某个触发元素(trigger
)的下方或旁边。可以先获取触发元素的边界信息,然后根据这些信息来设置弹出框的位置。- 例如,要让弹出框显示在触发元素的下方:
javascript">const triggerRect = trigger.getBoundingClientRect(); popup.style.top = triggerRect.bottom + 'px'; popup.style.left = triggerRect.left + 'px';
- 在游戏开发中,例如制作一个简单的2D游戏,当需要检测游戏角色(一个DOM元素表示)是否与障碍物(另一个DOM元素)发生碰撞时,可以使用
- 响应式布局和元素大小变化检测
- 在响应式网页设计中,当窗口大小改变时,可能需要根据元素的新位置和大小来调整其他元素的样式。
getBoundingClientRect
可以用于获取元素在不同窗口尺寸下的实际位置和大小。- 例如,有一个侧边栏(
sidebar
)和一个主要内容区域(mainContent
),当窗口变窄时,需要调整侧边栏的宽度。可以在窗口resize
事件中这样做:
javascript">window.addEventListener('resize', () => {const sidebarRect = sidebar.getBoundingClientRect();if (sidebarRect.width < 200) {// 调整侧边栏样式,比如减小字体大小等} });
- 例如,有一个侧边栏(
- 在响应式网页设计中,当窗口大小改变时,可能需要根据元素的新位置和大小来调整其他元素的样式。
- 元素滚动和视口位置关联
- 当页面滚动时,元素相对于视口的位置会发生变化。
getBoundingClientRect
可以用于跟踪元素在滚动过程中的位置变化。- 例如,要实现一个“返回顶部”按钮,当页面内容滚动到一定程度后显示该按钮。可以通过获取页面主体内容(
document.body
)的顶部位置来判断:
javascript">window.addEventListener('scroll', () => {const bodyRect = document.body.getBoundingClientRect();if (bodyRect.top < -100) {// 显示返回顶部按钮} else {// 隐藏返回顶部按钮} });
- 例如,要实现一个“返回顶部”按钮,当页面内容滚动到一定程度后显示该按钮。可以通过获取页面主体内容(
- 当页面滚动时,元素相对于视口的位置会发生变化。
- 元素定位和碰撞检测
- 注意事项
- 浏览器兼容性方面,
getBoundingClientRect
在现代浏览器中得到了很好的支持,包括Chrome、Firefox、Safari和IE9及以上版本。但是在一些旧版本浏览器中可能会有一些细微的差异或者不支持某些属性。 - 当元素的样式发生动态变化(如通过JavaScript修改了元素的
width
、height
、margin
、padding
、position
等属性)后,获取的边界信息也会相应变化。因此,在需要精确获取元素边界信息的场景下,要注意元素样式的动态更新可能带来的影响。同时,元素的隐藏(display: none
)会导致getBoundingClientRect
返回的尺寸为0,因为隐藏元素不占据可视空间。如果要获取隐藏元素的实际大小,可能需要先将其显示出来(如设置为display: block
或display: inline - block
),获取边界信息后再恢复其原始的隐藏状态。
- 浏览器兼容性方面,
实例应用
- 基本语法
- 在JavaScript中,
getBoundingClientRect
方法是应用于DOM元素的。其基本语法是element.getBoundingClientRect()
,其中element
是一个DOM节点,比如通过document.getElementById('myElement')
获取到的元素。这个方法会返回一个DOMRect
对象,该对象包含了元素的位置和大小相关的属性。
- 在JavaScript中,
- 获取位置属性
left
和top
属性left
属性表示元素的左边界距离视口(viewport)左边界的像素值,这个值包含了元素的左边框宽度。top
属性表示元素的上边界距离视口上边界的像素值,包含元素的上边框宽度。- 例如,有一个
<div id="box"></div>
元素,其样式如下:
在JavaScript中,可以这样获取它的css">#box {width: 100px;height: 100px;border: 5px solid black;position: absolute;left: 50px;top: 50px; }
left
和top
属性:javascript">const box = document.getElementById('box'); const rect = box.getBoundingClientRect(); console.log('left:', rect.left); console.log('top:', rect.top);
- 当浏览器窗口的左上角为坐标原点(0,0)时,上述代码中
rect.left
的值会是50(因为元素的left
样式值是50px,加上边框宽度),rect.top
的值会是50(同理,元素的top
样式值是50px,加上边框宽度)。
right
和bottom
属性right
属性表示元素的右边界距离视口左边界的像素值,bottom
属性表示元素的下边界距离视口上边界的像素值。它们也包含了元素边框的宽度。right - left
的值等于元素的宽度(包括边框),bottom - top
的值等于元素的高度(包括边框)。- 对于上面的
#box
元素,获取right
和bottom
属性的代码如下:
javascript">const box = document.getElementById('box'); const rect = box.getBoundingClientRect(); console.log('right:', rect.right); console.log('bottom:', rect.bottom);
- 计算可得,
rect.right
的值会是50 + 100+ 5
(元素的left
值加上宽度再加上右边框宽度)即155,rect.bottom
的值会是50 + 100 + 5
(元素的top
值加上高度再加上下边框宽度)即155。
x
和y
属性x
属性等同于left
,y
属性等同于top
。在某些情况下,使用x
和y
可以让代码更具语义性。- 对于
#box
元素,获取x
和y
属性的代码如下:
javascript">const box = document.getElementById('box'); const rect = box.getBoundingClientRect(); console.log('x:', rect.x); console.log('y:', rect.y);
- 这里
rect.x
的值和rect.left
一样是50,rect.y
的值和rect.top
一样是50。
- 获取大小属性
width
和height
属性width
属性返回元素的宽度,不包括外边距(margin),计算方式是right - left
(考虑边框)。height
属性返回元素的高度,不包括外边距,计算方式是bottom - top
(考虑边框)。- 对于
#box
元素,获取宽度和高度的代码如下:
javascript">const box = document.getElementById('box'); const rect = box.getBoundingClientRect(); console.log('width:', rect.width); console.log('height:', rect.height);
- 因为元素宽度是100px,边框左右各5px,所以
rect.width
的值是110。同理,元素高度是100px,边框上下各5px,rect.height
的值是110。
- 在不同场景下的应用示例
- 页面滚动后的位置获取
- 当页面滚动时,元素相对于视口的位置会发生变化。
getBoundingClientRect
可以用于获取滚动后元素的位置。 - 例如,有一个
<h1 id="title">My Title</h1>
元素,想要在页面滚动后获取它的位置,可以这样做:
javascript">window.addEventListener('scroll', () => {const title = document.getElementById('title');const rect = title.getBoundingClientRect();console.log('滚动后标题的top位置:', rect.top); });
- 当页面滚动时,元素相对于视口的位置会发生变化。
- 元素碰撞检测
- 假设在一个简单的游戏场景中有两个元素,一个小球(
#ball
)和一个方块(#block
),要检测它们是否碰撞,可以使用getBoundingClientRect
。 - 样式如下:
css">#ball {width: 20px;height: 20px;border - radius: 10px;background - color: red;position: absolute;left: 0;top: 0; } #block {width: 50px;height: 50px;background - color: blue;position: absolute;left: 30px;top: 30px; }
- 检测碰撞的JavaScript代码如下:
javascript">const ball = document.getElementById('ball'); const block = document.getElementById('block'); function checkCollision() {const ballRect = ball.getBoundingClientRect();const blockRect = block.getBoundingClientRect();if (ballRect.right > blockRect.left && ballRect.left < blockRect.right &&ballRect.bottom > blockRect.top && ballRect.top < blockRect.bottom) {console.log('发生碰撞');} } checkCollision();
- 假设在一个简单的游戏场景中有两个元素,一个小球(
- 页面滚动后的位置获取
contenteditable
contenteditable 属性介绍
-
基本概念
contenteditable
是一个HTML全局属性,它允许用户直接在网页上编辑元素内的文本内容。当把这个属性应用到HTML元素(比如div
、p
等元素)上时,该元素就变得像一个可编辑的文本输入框一样,用户可以通过鼠标点击进入编辑状态,然后进行文本的输入、修改、删除等操作,非常方便用于创建一些富文本编辑场景或者让用户能够动态地更改页面上某些文本内容。 -
属性值
它有以下几个常用的属性值:true
:表示元素是可编辑的,用户能够对其内部文本进行编辑操作,这是最常用的设置方式,例如:<div contenteditable="true">这里的文本可以编辑哦</div>
。false
:明确指定元素不可编辑,即便该元素可能继承了来自父元素的可编辑特性等情况,设置为false
后就禁止编辑了,比如:<p contenteditable="false">这段文本不能编辑</p>
。inherit
:元素会继承其父元素的contenteditable
属性值,如果父元素是可编辑的,那它也可编辑,反之则不可编辑,像<span contenteditable="inherit">文本内容,编辑状态取决于父元素哦</span>
。
内部文本选中高亮实例,3秒后高亮消失
以下是使用HTML、CSS和JavaScript来实现的示例,当在设置了contenteditable
属性的div
中选中文本时,文本会高亮显示,然后3秒后高亮效果自动消失:
- HTML结构
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>ContentEditable Highlight Example</title><link rel="stylesheet" type="text/css" href="styles.css">
</head><body><div id="editableDiv" contenteditable="true">这是一段可以编辑的文本内容,试试选中其中一部分文字,看看它会高亮显示,然后很快就会恢复原样哦。</div><script src="script.js"></script>
</body></html>
- CSS样式(styles.css文件)
这里定义了高亮显示的样式,通过添加一个类名来实现文本背景颜色改变等高亮效果:
css">.highlight {background-color: yellow; /* 设置高亮背景色为黄色,可根据喜好更改 */
}
- JavaScript代码(script.js文件)
javascript">const editableDiv = document.getElementById('editableDiv');editableDiv.addEventListener('mouseup', function () {// 获取当前选中的文本范围对象const selection = window.getSelection();if (selection.rangeCount > 0) {const range = selection.getRangeAt(0);const selectedText = range.cloneContents();const span = document.createElement('span');span.className = 'highlight';span.appendChild(selectedText);range.deleteContents();range.insertNode(span);setTimeout(() => {const highlightedSpans = editableDiv.querySelectorAll('.highlight');highlightedSpans.forEach(span => {const textNode = document.createTextNode(span.textContent);span.parentNode.replaceChild(textNode, span);});}, 3000);}
});
在上述JavaScript代码中:
- 首先通过
getElementById
获取到了设置了contenteditable
属性的div
元素。 - 接着给这个
div
添加了mouseup
事件监听器,因为当用户松开鼠标时,基本完成了文本选中操作,此时触发事件。 - 在事件处理函数中,使用
window.getSelection()
获取到用户的文本选择范围,判断如果有选中的文本(rangeCount > 0
),则进行以下操作:- 克隆选中的文本内容,创建一个
<span>
元素并添加highlight
类名来赋予高亮样式,然后把克隆的文本内容放入<span>
元素中。 - 先删除原来选中的文本内容,再把带有高亮样式的
<span>
元素插入到原来文本的位置,实现高亮显示效果。
- 克隆选中的文本内容,创建一个
- 最后使用
setTimeout
函数,设置在3000毫秒(即3秒)后,查询这个div
中所有带有highlight
类名的<span>
元素,并把它们替换回原来的普通文本节点,使得高亮效果消失,恢复文本原本的样子。
你可以将上述代码分别保存到对应的.html
、.css
和.js
文件中(文件名可自行确定,但要保证HTML文件中引入的文件名正确),然后在浏览器中打开HTML文件查看效果。
父元素定位特定子元素内容定位效果
以下是几种常见的实现方式,使得在父级元素出现滚动条的情况下,默认滚动条滚动到最后一个子元素内容进行展示,分别基于HTML、CSS和JavaScript来实现,示例代码如下:
方式一:使用JavaScript,在页面加载完成后设置滚动位置(适用于大多数现代浏览器环境)
- HTML结构示例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Scroll to Last Child</title><style>css">/* 父元素样式,设置高度并出现滚动条 */.parent {height: 200px;overflow-y: scroll;border: 1px solid black;}/* 子元素样式,设置高度使其总和大于父元素高度 */.child {height: 80px;background-color: lightgray;margin-bottom: 10px;}</style>
</head><body><div class="parent"><div class="child">子元素1</div><div class="child">子元素2</div><div class="child">子元素3</div><div class="child">子元素4</div></div><script>javascript">window.addEventListener('load', function () {const parent = document.querySelector('.parent');const lastChild = parent.lastElementChild;parent.scrollTop = lastChild.offsetTop + lastChild.offsetHeight - parent.offsetHeight;});</script>
</body></html>
在上述代码中:
- 首先通过
window.addEventListener('load',...)
监听页面的load
事件,确保页面上所有元素都加载完成后再执行后续操作。 - 然后使用
document.querySelector('.parent')
获取到父元素,再通过parent.lastElementChild
找到父元素内的最后一个子元素。 - 最后计算需要滚动的距离,通过设置
parent.scrollTop
属性来让父元素的滚动条滚动到相应位置。滚动距离的计算原理是让滚动条滚动到最后一个子元素的底部与父元素底部对齐的位置,即lastChild.offsetTop + lastChild.offsetHeight - parent.offsetHeight
,其中offsetTop
是元素相对于其偏移父元素(包含它的最近的定位元素,如果没有就是文档根元素)顶部的距离,offsetHeight
是元素自身的高度,通过这样的计算实现滚动到最后一个子元素内容进行展示的效果。
方式二:使用scrollIntoView
方法(兼容性也较好,更简洁直观)
- HTML结构可以沿用上面的示例,主要更改JavaScript部分代码如下
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Scroll to Last Child</title><style>css">/* 父元素样式,设置高度并出现滚动条 */.parent {height: 200px;overflow-y: scroll;border: 1px solid black;}/* 子元素样式,设置高度使其总和大于父元素高度 */.child {height: 80px;background-color: lightgray;margin-bottom: 10px;}</style>
</head><body><div class="parent"><div class="child">子元素1</div><div class="child">子元素2</div><div class="child">子元素3</div><div class="child">子元素4</div></div><script>javascript">window.addEventListener('load', function () {const lastChild = document.querySelector('.parent').lastElementChild;lastChild.scrollIntoView({ behavior: 'smooth', block: 'end' });});</script>
</body></html>
这里的核心是scrollIntoView
方法,它用于将指定元素滚动到浏览器窗口或其容器元素(在这里就是父元素)的可视区域内。传入的参数对象中:
behavior
属性设置滚动的行为方式,'smooth'
表示平滑滚动,如果设置为'auto'
则是瞬间滚动到相应位置。block
属性指定在垂直方向上的对齐方式,'end'
表示将元素的底部与滚动容器(父元素)的底部对齐,从而实现滚动到最后一个子元素底部的效果,确保最后一个子元素内容完整展示在父元素可视区域内。
方式三:如果使用一些JavaScript框架(如jQuery,在有相关项目依赖的情况下)
- HTML结构类似上述示例,同时引入jQuery库(假设通过CDN引入),JavaScript代码如下
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Scroll to Last Child</title><style>css">/* 父元素样式,设置高度并出现滚动条 */.parent {height: 200px;overflow-y: scroll;border: 1px solid black;}/* 子元素样式,设置高度使其总和大于父元素高度 */.child {height: 80px;background-color: lightgray;margin-bottom: 10px;}</style><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
</head><body><div class="parent"><div class="child">子元素1</div><div class="child">子元素2</div><div class="child">子元素3</div><div class="child">子元素4</div></div><script>javascript">$(window).on('load', function () {$('.parent').scrollTop($('.parent').find('.child').last().position().top + $('.parent').find('.child').last().outerHeight()- $('.parent').height());});</script>
</body></html>
在这段基于jQuery的代码中:
- 首先通过
$(window).on('load',...)
监听页面加载完成事件,和原生JavaScript的window.addEventListener('load',...)
类似功能。 - 然后使用
$('.parent')
获取父元素对应的jQuery对象,通过find('.child').last()
找到最后一个子元素的jQuery对象。 - 接着使用
position().top
获取子元素相对于其偏移父元素(这里基本就是父元素本身)的顶部距离,outerHeight()
获取子元素包含边框和内边距等的总高度,再结合父元素的height
属性,计算出需要设置的滚动条的scrollTop
值,实现滚动到最后一个子元素内容展示的效果,原理和原生JavaScript方式中的滚动距离计算类似,只是调用的是jQuery提供的相关DOM操作和属性获取方法。
以上几种方式都可以根据具体的项目需求和环境选择使用,实现让父元素滚动条默认滚动到最后一个子元素内容进行展示的目的。
高亮选中补充
以下是关于 ::selection
伪元素以及 rangeAt
相关方法在文本选中高亮方面的应用场景及实例介绍:
::selection 伪元素
应用场景
- 个性化文本选中效果:在网页设计中,当用户选中文本时,默认情况下浏览器会以系统自带的样式(通常是反色显示,比如白底黑字页面选中文字就是黑底白字)来呈现选中状态。使用
::selection
伪元素可以打破这种默认样式,按照网页整体的设计风格,自定义文本选中后的背景颜色、文字颜色等,增强页面的视觉效果和用户体验的独特性。 - 突出重要内容:对于一些需要引导用户重点关注的文本区域,比如文章中的关键段落、提示信息、操作按钮上的文字等,通过设置独特的选中样式,当用户偶然或有意选中这些文字时,能更加醒目地展示,强化内容传达效果。
实例
以下是一个简单的 CSS 代码示例,展示如何使用 ::selection
伪元素来改变文本选中时的样式:
css">/* 改变所有元素选中文本的背景色为黄色,文字颜色为红色 */
::selection {background-color: yellow;color: red;
}/* 仅改变段落元素内选中文本的背景色为浅蓝色,文字颜色为深蓝色 */
p::selection {background-color: lightblue;color: darkblue;
}
在上述代码中:
- 第一个规则会应用于页面内所有可选中并能应用样式的元素,当用户选中文本时,文本的背景会变为黄色,文字颜色变为红色。
- 第二个规则更具针对性,只针对段落(
p
)元素内的选中文本生效,将其选中背景设置为浅蓝色,文字颜色设置为深蓝色。这样就可以实现不同元素选中时有不同的高亮效果,使页面呈现更丰富的视觉感受。
rangeAt 方法(通常配合 getSelection
等一起使用)
应用场景
- 自定义文本操作功能:在富文本编辑器、文档编辑类网页应用等场景中,开发者往往需要精确地知道用户具体选中了哪些文本内容,以便进行进一步的操作,比如对选中文字添加特定格式(加粗、下划线等)、复制选中内容到其他地方、实现文本的删除、替换等复杂编辑功能。
rangeAt
方法能帮助获取文本选中范围的详细信息,进而实现这些自定义的文本处理逻辑。 - 实现交互性文本高亮:不仅仅是简单的统一选中样式,有时需要针对用户选中的特定文本片段,动态地添加独特的高亮效果(比如添加彩色背景框、动画闪烁等),区别于普通的
::selection
样式,而且这种高亮可以根据业务逻辑随时取消或更改,通过rangeAt
方法结合 JavaScript 操作就能达成这样灵活的交互性文本高亮效果。
实例
以下是一个 JavaScript 示例,实现当用户在一个可编辑的 div
元素中选中文本时,为选中的文本添加一个带有动画效果的高亮背景(这里使用 CSS 类添加动画,仅为示例,可按需完善动画效果):
- HTML 结构
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Text Highlight with rangeAt</title><style>css">/* 定义高亮的样式,这里简单设置背景色为黄色,可按需完善动画等效果 */.highlight {background-color: yellow;animation: blink 1s infinite; /* 添加一个闪烁动画,仅示例 */}/* 闪烁动画的定义,这里只是简单让背景色透明度在一定范围变化 */@keyframes blink {0%, 100% {background-color: yellow;opacity: 1;}50% {background-color: yellow;opacity: 0.5;}}/* 可编辑的 div 元素样式 */.editable-div {width: 300px;height: 200px;border: 1px solid black;padding: 10px;contenteditable: true;}</style>
</head><body><div class="editable-div">这是一段可以编辑的文本内容,你可以在这里选中文本,看看选中的部分会被高亮显示哦。</div><script src="script.js"></script>
</body></html>
- JavaScript 代码(script.js 文件)
javascript">const editableDiv = document.querySelector('.editable-div');editableDiv.addEventListener('mouseup', function () {const selection = window.getSelection();if (selection.rangeCount > 0) {const range = selection.getRangeAt(0);const selectedText = range.cloneContents();const span = document.createElement('span');span.className = 'highlight';span.appendChild(selectedText);range.deleteContents();range.insertNode(span);}
});
在上述示例中:
- 首先通过
document.querySelector
获取到页面上设置为可编辑的div
元素。 - 接着给这个
div
元素添加了mouseup
事件监听器,因为用户选中文本后松开鼠标时基本完成了选择操作,此时触发事件比较合适。 - 在事件处理函数内:
- 通过
window.getSelection
获取到用户的文本选择情况,如果存在选中的文本范围(rangeCount > 0
),则使用rangeAt(0)
方法获取第一个(通常也是唯一的)文本范围对象。 - 克隆选中的文本内容,创建一个
<span>
元素并添加highlight
类名(对应之前定义的带有动画效果的高亮样式),将克隆的文本放入<span>
元素中。 - 先删除原来选中的文本内容,再把带有高亮样式的
<span>
元素插入到原来文本的位置,从而实现当用户选中文本时,选中部分会呈现出带有动画效果的高亮背景,达到了更具交互性的文本选中高亮展示效果。
- 通过
需要注意的是,实际应用中可根据具体需求进一步扩展和优化这些示例代码,比如完善动画效果、处理更复杂的文本编辑和取消高亮等逻辑。
surroundContents
surroundContents
相关内容- 基本概念和应用场景
surroundContents
是Range
对象的一个方法,在JavaScript的DOM操作中用于将指定范围内的节点用一个新的节点包裹起来。这在处理富文本编辑、文档结构修改等场景中非常有用。- 例如,在一个富文本编辑器中,当用户选择一段文本并点击一个“加粗”按钮时,可以使用
surroundContents
方法将选中的文本用一个<strong>
标签包裹起来,从而实现加粗效果。或者当需要将选中的多个元素组合成一个新的结构单元时,也可以使用这个方法。
- 实例
- 假设在一个HTML页面中有一个可编辑的
div
元素,里面包含一些文本,当用户选中文本后,使用surroundContents
方法将其用一个<span>
标签包裹起来,并添加一个自定义的类名。 - HTML结构
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Surround Contents Example</title><style>css">.custom-span {background-color: yellow;}.editable-div {width: 300px;height: 200px;border: 1px solid black;padding: 10px;contenteditable: true;}</style> </head> <body><div class="editable-div">这是一段可以编辑的文本内容。</div><script src="script.js"></script> </body> </html>
- JavaScript代码(script.js)
javascript">const editableDiv = document.querySelector('.editable-div'); editableDiv.addEventListener('mouseup', function () {const selection = window.getSelection();if (selection.rangeCount > 0) {const range = selection.getRangeAt(0);const span = document.createElement('span');span.className = 'custom-span';try {range.surroundContents(span);} catch (error) {console.error('操作失败:', error);}} });
- 在上述代码中,当用户在
editableDiv
元素中选中文本并松开鼠标(mouseup
事件)时,首先获取选择对象selection
,然后得到选中的范围range
。接着创建一个<span>
元素并设置类名。最后尝试使用range.surroundContents(span)
将选中的内容用这个<span>
元素包裹起来。如果操作失败(例如,范围包含部分但不是全部的DocumentFragment
等情况),会捕获并打印错误信息。
- 假设在一个HTML页面中有一个可编辑的
- 基本概念和应用场景
- 删除相关操作(以刚才包裹的内容为例)
-
删除包裹元素及其内容
- 如果要删除刚才用
<span>
包裹的内容,可以通过获取包裹元素(span
)并使用remove
方法来实现。 - 例如,添加一个按钮,点击这个按钮就删除所有带有
custom - span
类的元素。 - HTML结构(在刚才的基础上添加按钮)
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Delete Surrounded Contents</title><style>css">.custom - span {background - color: yellow;}.editable - div {width: 300px;height: 200px;border: 1px solid black;padding: 10px;contenteditable: true;}</style> </head> <body><div class="editable - div">这是一段可以编辑的文本内容。</div><button id="delete - button">删除包裹的内容</button><script src="script.js"></script> </body> </html>
- JavaScript代码(script.js - 新增部分)
javascript">const deleteButton = document.getElementById('delete - button'); deleteButton.addEventListener('click', function () {const customSpans = document.querySelectorAll('.custom - span');customSpans.forEach(function (span) {span.remove();}); });
- 在上述代码中,首先获取
delete - button
按钮元素,然后为其添加click
事件监听器。在事件处理函数中,通过querySelectorAll
方法找到所有带有custom - span
类的元素,再使用remove
方法逐个删除这些元素,从而实现删除之前包裹的内容的操作。
- 如果要删除刚才用
-
仅删除包裹元素,保留内容
- 如果只想删除包裹元素(
span
),但保留其内部的内容,可以通过获取包裹元素的子节点,并将这些子节点插入到包裹元素的父节点中,然后再删除包裹元素。 - JavaScript代码(script.js - 另一种删除方式)
javascript">const deleteButton = document.getElementById('delete - button'); deleteButton.addEventListener('click', function () {const customSpans = document.querySelectorAll('.custom - span');customSpans.forEach(function (span) {while (span.firstChild) {span.parentNode.insertBefore(span.firstChild, span);}span.remove();}); });
- 在这种方式中,对于每个
custom - span
元素,通过一个while
循环,只要span
元素有第一个子节点,就将这个子节点插入到span
元素的父节点中(即包裹元素的父节点),位置在span
元素之前。这样就将包裹元素内部的内容逐个移出,最后再删除包裹元素,达到仅删除包裹元素,保留内容的目的。
综合应用如下
javascript"><!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><title>Surround Contents Example</title><style>.custom-span {background-color: yellow;}.editable-div {width: 300px;height: 200px;border: 1px solid black;padding: 10px;}</style> </head><body><div class="editable-div" contenteditable="true">这是一段可以编辑的文本内容。</div><button id="delete-button">删除包裹的内容</button><script>const editableDiv = document.querySelector('.editable-div');editableDiv.addEventListener('mouseup', function () {const selection = window.getSelection();if (selection.rangeCount > 0) {const range = selection.getRangeAt(0);const span = document.createElement('span');span.className = 'custom-span';try {range.surroundContents(span);} catch (error) {console.error('操作失败:', error);}}});const deleteButton = document.getElementById('delete-button');deleteButton.addEventListener('click', function () {// const customSpans = document.querySelectorAll('.custom-span');// customSpans.forEach(function (span) {// span.remove();// });const customSpans = document.querySelectorAll('.custom-span');customSpans.forEach(function (span) {while (span.firstChild) {span.parentNode.insertBefore(span.firstChild, span);}span.remove();});});</script> </body></html>```
- 如果只想删除包裹元素(
-