马黑黑《初识 Selection 对象》
<style>.artBox { margin: 20px auto; font: normal 18px/28px sans-serif; max-width: 1200px; }
.artBox mark { padding: 2px 6px; background: lightblue; }
.artBox blockquote { padding: 14px; border: solid lightblue; border-width: 0 4px; border-radius: 10px; background: beige; }
.artBox p { margin: 10px 0; }
.mama { margin: 30px; width: 600px; border: 1px solid gray; border-radius: 10px; padding: 10px; }
</style>
<div class="artBox">
<blockquote id="bq1" onclick="getSelectedText();">Selection 对象表示用户选择的文本范围或插入符号的当前位置。它代表页面中的文本选区,可能横跨多个元素。文本选区由用户按下鼠标左键不放并拖拽鼠标经过文字而产生。调用 window.getSelection() 方法可以获取 Selection 对象。</blockquote>
<p><button onclick="showSelection();">演示:点击此按钮将会在上面的文本段落中随机创建选区</button></p>
<p>正如文本开头引用框所介绍的,你也可以在上面的文本段落中自行选择任意文本。上面介绍 Selection 对象的引用框集成有一个功能:用鼠标手动选择任意文本,都会弹出一个 alert 窗口,窗口上展现被选择文本的相关信息。功能的实现仅使用了一个方法:<mark>selection.toString()</mark>,该方法返回选区内的完整文本,toString 是<b>转换为字符串</b>的意思。</p>
<p><mark>window.getSelection()</mark> 方法返回的是一个 Selection(选区)对象,该对象拥有如下主要<b>属性</b>:</p>
<ul>
<li><b>anchorNode</b> :只读,返回选区<b>起点</b>所在的节点(Node)。anchor是“锚”之意,指选区开始时的定位点(鼠标按下时的那个点)</li>
<li><b>anchorOffset</b> :只读,返回选区起点在 anchorNode 中的位置偏移量。需要注意两种情形:
<ol>
<li>如果 anchorNode 是文本节点、注释节点,返回锚点(anchor)到该节点中第一个字的字符个数</l>
<li>如果 anchorNode 是元素节点,返回锚点(anchor)之前的同级节点总数</li>
</ol>
</li>
<li><b>focusNode</b> :只读,返回选区终点所在的节点。focus意味“焦点”,这里指选区起点到终点的高亮区域</li>
<li><b>focusOffset</b> :只读,返回选区终点在 focusNode 中的位置偏移量。需要注意两种情形:
<ol>
<li>如果 focusNode 是文本节点、注释节点,返回焦点(focus)到该节点中的第一个字的字符个数</li>
<li>如果 focusNode 是元素节点,返回焦点(focus)之前的同级节点总数</li>
</ol>
</li>
<li><b>isCollapsed</b> :只读,返回布尔值,表示选区的起始点和终点是否在同一个位置</li>
<li><b></b> :只读,选区方向,返回forward(自左向右)或 backward(自右向左)</li>
<li><b>rangeCount</b> :只读,返回选区所包含的连续范围(range)的数量</li>
</ul>
<p>【注意】选区有方向(direction),可以自左向右或自右向左,取决于用户按下左键后往左或往右拖曳。选区的方向直接影响锚和焦点的位置,自左向右时锚前、焦点后,自右向左锚后、焦点前。</p>
<p>下面是获取选区对象属性值的简单演示:</p>
<div class="mama" onmouseup="getSelectionAttributes();">
<h3>请选择任意文本</h3>
<p>这行是 <mark>id="mama"</mark> div 的p标签文本,里面有两个<mark>mark</mark>元素节点</p>
<div>这行是 div 标签,里面的内容是纯文本</div>
</div>
<p>选区(Selection)对象的主要<b>方法</b>则有:</p>
<ul>
<li>getRangeAt :返回选区包含的指定区域(Range)的引用,即获取指定选区的范围</li>
<li>collapse :将当前的选区折叠为一个点</li>
<li>extend :将选区的焦点移动到一个特定的位置</li>
<li>modify :修改当前的选区</li>
<li>collapseToStart :将当前的选区折叠到起始点</li>
<li>collapseToEnd :将当前的选区折叠到最末尾的一个点</li>
<li>selectAllChildren :将某一指定节点的子节点框入选区</li>
<li>addRange :一个区域(Range)对象将被加入选区</li>
<li>removeRange :从选区中移除一个区域</li>
<li>removeAllRanges :将所有的区域都从选区中移除</li>
<li>deleteFromDocument :从页面中删除选区中的内容</li>
<li>toString :返回当前选区的纯文本内容</li>
<li>containsNode :判断某一个 Node 是否为当前选区的一部分</li>
</ul>
<p>选区(Selection)对象的方法很多需要配合 range 对象使用,如开头随机选择选区就用上了 range 对象。下例仅演示 toStrong 和 delecteFromDocument 方法:</p>
<div id="mama" class="mama" onmouseup="getTextAndDelete(this);">选择本此方框内的任意文本会获取所选择的文本然后删除掉,直至删完为止(选择后如果没有弹出alert窗口,请再单击一下此方框)。全部删除文本内容后可单击下方按钮重置。</div>
<p><button id="btnResetText">重置方框文本</button></p>
<p><br></p>
<p>【附】本文基于选区的核心JS代码(自动获取)</p>
<div class="hEdiv"><pre id="pre1" class="hEpre"></pre></div>
</div>
<script id="js_1">
// 创建随机选区
function showSelection() {
const sel = window.getSelection();
const range = new Range();
const len = bq1.textContent.length; // blockquote的文本长度
let begin = Math.floor(Math.random() * len / 2);
let end = Math.floor(Math.random() * len);
if (begin === end) end += 2;
if (begin > end) = ;
range.setStart(bq1.firstChild, begin);
range.setEnd(bq1.firstChild, end);
sel.removeAllRanges();
sel.addRange(range);
}
// 获取选区文本
function getSelectedText() {
const sel = window.getSelection();
const msg = sel.isCollapsed ? '你没有选择任何文字' : `你选择的文字是:${sel.toString()}`;
alert(msg);
}
// 获取选区属性信息
function getSelectionAttributes() {
const sel = window.getSelection();
let res = '未选择任何文本';
// 若有选择文本
if (sel.rangeCount) {
const dir = {forward: '自左向右', backward: '自右向左'}
res = `选区相关属性信息 :
anchorNode(起始节点):${sel.anchorNode}
anchorOffset(选区起点在起始节点中的偏移量):${sel.anchorOffset}
focusNode(终点节点):${sel.focusNode}
focusOffset(选区终点在结束节点中的偏移量):${sel.focusOffset}
direction(选区方向):${sel.direction}(${dir})
isCollapsed(起始和结束节点是否同一个):${sel.anchorNode === sel.focusNode ? '同' : '不同'}
rangeCount(选区范围):${sel.rangeCount}`;
}
alert(res);
}
// 获取选区文本并删除
function getTextAndDelete() {
const sel = window.getSelection();
let str = '没有选择任何内容';
if (sel.isCollapsed) return;
alert(`选择的文本“${sel.toString()}”将被删除!`);
sel.deleteFromDocument();
}
</script>
<script type="module">
import hl from 'https://638183.freep.cn/638183/web/js/hl.js';
pre1.innerHTML = js_1.outerHTML.replaceAll('<', '<').replaceAll('>', '>');
const divs = document.querySelectorAll('.hEdiv');
const pres = document.querySelectorAll('.hEpre');
divs.forEach((div,idx) => hl.hl(div, pres));
const rawtext = mama.innerText;
btnResetText.onclick = () => mama.innerText = rawtext;
</script>
长知识了,谢谢分享
页:
[1]