文章目录
- 一、参考
- 二、问题描述
- 三、快速入门
- 四、HTML5中选中Selection和光标Range对象
- 4.1 选中对象-selection
- 4.2 光标对象-range
- 4.3 ()
- 五、代码集合
- 5.1选中input表单的内容,展示位置
- 5.2 在文本控件的光标位置添加 字符串
- 5.3 自定义光标位置 或者 删除选中内容
- 5.4在contenteditable属性标签中光标位置添加文本
一、参考
- setSelectionRange()参考
- Selection MDN
- Range MDN
二、问题描述
业务需求:摄像头发现有违章停车,就需要短信通知到相关车主
开发任务:需要提前编辑好相关短信模板,比如时间、车牌号、车主名字等通用模板信息,需要使用特定字符代替,方便后台解析。而这些字符串是开发定的,对编写短信模板的人实际上没有实际意义
三、快速入门
<html>
<head> </head>
<script type="text/javascript">
function add(str) {
var tc = document.getElementById("mytextarea");
var tclen = tc.value.length;
tc.focus();
// 兼容性检查
if (typeof document.selection != "undefined") {
document.selection.createRange().text = str;
} else {
tc.value =
// 获取光标的开始位置
tc.value.substr(0, tc.selectionStart) +
str +
tc.value.substring(tc.selectionStart, tclen);
}
}
</script>
<body>
<textarea rows="5" name="s1" cols="27" id="mytextarea">
目的通过点击页面上的按钮button 在textarea中的光标停留处插上文字 </textarea
>
<ul>
<li>
<button onclick="add('huangbiao')">添加指定字符串</button>
</li>
</ul>
</body>
</html>
四、HTML5中选中Selection和光标Range对象
光标是一个对象,当你选中某个元素的时候才会出现光标对象
- 我们点击一个输入框,实际会产生一个
选中对象-selection
,这个对象我们可以通过()来获取; -
selection只存在1个
,所以当你切换到其他输入框额时候,selection同样会跟着变化的。 -
在选中的情况下有一个光标叫做range,和selection一样
。 - 当你点击一个输入框,或者你切换到别的输入框,selection是会跟着变化的。光标就是在selection里面,光标叫做range,
4.1 选中对象-selection
-
Selection MDN
-
MDN 解释说明
- Selection 对象表示用户选择的文本范围或插入符号的当前位置。它代表页面中的文本选区,可能横跨多个元素。
- 文本选区由用户拖拽鼠标经过文字而产生。
要获取用于检查或修改的 Selection 对象,请调用 ()
。- 一个 Selection 对象表示用户选择的 Range 的集合。通常,它只包含一个区域
var selObj = window.getSelection();
var range = selObj.getRangeAt(0);
-
个人理解
-
当我们去点击一个输入框的时候,实际上它会产生一个选中对象-selection(就是我们可以看到的文字变成蓝色的那个区域)
,selection在火狐浏览器可以直接用 ()获取,在HTML里面,selection只有一个的,并且selection是一个区域,你可以想象成一个长方形,它是有开始和结束的
-
-
selectionchange 事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div>
Enter and select text here:<br /><input id="mytext" rows="2" cols="20" />
</div>
<div>selectionStart: <span id="start"></span></div>
<div>selectionEnd: <span id="end"></span></div>
<div>selectionDirection: <span id="direction"></span></div>
</body>
<script>
const myinput = document.getElementById("mytext");
// ("selectionchange", () => { 这个无效
document.addEventListener("selectionchange", () => {
// 只有HTMLInputElement 节点才有 selectionStart selectionEnd selectionDirection 属性
document.getElementById("start").textContent = myinput.selectionStart;
document.getElementById("end").textContent = myinput.selectionEnd;
document.getElementById("direction").textContent =
myinput.selectionDirection;
});
</script>
</html>
4.2 光标对象-range
- Range MDN
- MDN 概念
- Range 接口表示一个包含节点与文本节点的一部分的文档片段。
- 范围指的是文档中连续的一部分。一个范围包括整个节点,也可以包含节点的一部分,例如文本节点的一部分。用户通常下只能选择一个范围,但是有的时候用户也有可能选择多个范围。
- 可以用 Document 对象的 方法创建 Range,也可以用 Selection 对象的 getRangeAt 方法获取 Range。另外,还可以通过 Document 对象的构造函数 Range() 来得到 Range。
- 个人理解
- 光标就是在selection里面,光标叫做range,是一个片段区域,
和selection一样,有开始点,和结束点,当我们对文字按下左键向右拉的时候,就看到了文字变成蓝色,那个就是光标的开始和结束
, 当我们直接点一下的时候,光标在闪,其实只是开始和结束点重叠了
- 光标就是在selection里面,光标叫做range,是一个片段区域,
4.3 ()
- setSelectionRange()参考
- 函数作用
- 于设定 或 元素中当前选中文本的起始和结束位置。
- 个人理解:
设置光标的位置
- 属性
- selectionStart
被选中的第一个字符的位置索引,从0开始
。如果这个值比元素的 value 长度还大,则会被看作 value 最后一个位置的索引。 - selectionEnd
被选中的最后一个字符的 下一个 位置索引
。如果这个值比元素的value长度还大,则会被看作value最后一个位置的索引。 - selectionDirection 可选
一个表示选择方向的字符串
,可能的值有: “forward” 、 “backward”、 “none” 默认值,表示方向未知或不相关。
- selectionStart
五、代码集合
5.1选中input表单的内容,展示位置
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div>
Enter and select text here:<br /><input id="mytext" rows="2" cols="20" />
</div>
<div>selectionStart: <span id="start"></span></div>
<div>selectionEnd: <span id="end"></span></div>
<div>selectionDirection: <span id="direction"></span></div>
</body>
<script>
const myinput = document.getElementById("mytext");
// ("selectionchange", () => { 这个无效
document.addEventListener("selectionchange", () => {
// 只有HTMLInputElement 节点才有 selectionStart selectionEnd selectionDirection 属性
document.getElementById("start").textContent = myinput.selectionStart;
document.getElementById("end").textContent = myinput.selectionEnd;
document.getElementById("direction").textContent =
myinput.selectionDirection;
});
</script>
</html>
5.2 在文本控件的光标位置添加 字符串
<html>
<head> </head>
<script type="text/javascript">
function add(str) {
var tc = document.getElementById("mytextarea");
var tclen = tc.value.length;
tc.focus();
if (typeof document.selection != "undefined") {
document.selection.createRange().text = str;
} else {
tc.value =
// 获取光标的开始位置
tc.value.substr(0, tc.selectionStart) +
str +
tc.value.substring(tc.selectionStart, tclen);
}
}
// 文本表单内容全部选中
function selectAll() {
var tc = document.getElementById("mytextarea");
// textarea 内容全部选中
tc.select();
// 聚焦选中
tc.focus();
}
function selectPos() {
var start = 5,
end = 10;
var tc = document.getElementById("mytextarea");
// 没有选中,默认全部是从 0 开始
console.log(tc.selectionStart);
// 没有选中区域,则和 selectionStart 在相同的位置
console.log(tc.selectionEnd);
// 设置选中的区域,不会在浏览器中高亮选中的内容
tc.setSelectionRange(start, end);
// 选中的开始位置
console.log(tc.selectionStart);
// 选中的结束位置
console.log(tc.selectionEnd);
var str = "huangbiao";
var tclen = tc.value.length;
tc.value =
tc.value.substr(0, tc.selectionStart) +
str +
tc.value.substring(tc.selectionStart, tclen);
}
function getSelectObj() {
// 获取用户页面选中的对象
var selObj = window.getSelection();
// 调用 () 方法会返回被选中区域中的纯文本。
window.alert(selObj);
}
function getRangeObj() {
var selObj = window.getSelection();
// 获取Range 对象
var range = selObj.getRangeAt(0);
console.log(range);
}
</script>
<body>
<textarea rows="5" name="s1" cols="27" id="mytextarea">
目的通过点击页面上的按钮button 在textarea中的光标停留处插上文字 </textarea
>
<ul>
<li>
<button onclick="selectAll()">
全部选中
</button>
</li>
<li>
<button onclick="add('huangbiao')">添加指定字符串</button>
</li>
<li>
<button onclick="selectPos()">
自定义选中的位置
</button>
</li>
<li>
<button onclick="getSelectObj()">
获取选中的值
</button>
</li>
<li>
<button onclick="getRangeObj()">
获取选中的Range对象
</button>
</li>
</ul>
</body>
</html>
5.3 自定义光标位置 或者 删除选中内容
<html>
<head> </head>
<script type="text/javascript">
// 要把元素清空
function clearContent() {
var p = document.getElementById("mytextarea"),
s = window.getSelection(),
r = document.createRange();
debugger
// 兼容 contenteditable="true" 属性 和 input 表单两种情况
p.innerHTML = "\u00a0";
// 光标选中节点
r.selectNodeContents(p);
// 选中对象 删除所有的光标
s.removeAllRanges();
// 选中对象 插入自定义的光标对象
s.addRange(r);
// 将光标选中的对象删除
// ("delete", false, null);
}
// 将光标放在第一个位置
function addFirst() {
var p = document.getElementById("mytextarea"),
s = window.getSelection(),
r = document.createRange();
// 设置光标在 p 控件的开始位置
r.setStart(p, 0);
// 设置光标在 p 控件的结束位置
r.setEnd(p, 0);
// 选中对象 删除所有的光标
s.removeAllRanges();
// 选中对象 插入自定义的光标对象
s.addRange(r);
// 聚焦到可编辑的文本控件中
p.focus();
}
</script>
<body>
<div contenteditable="true" id="mytextarea">
我是一句优美的语言
</div>
<ul>
<li>
<button onclick="addFirst()">将光标放在第一个位置</button>
</li>
<li>
<button onclick="clearContent()">要把元素清空</button>
</li>
</ul>
</body>
</html>
5.4在contenteditable属性标签中光标位置添加文本
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>#edit{height:500px;width:500px;border:1px solid red;}</style>
</head>
<body>
<div id="edit" contenteditable></div>
<input type="text" id="emojiInput">
<button id="sendEmoji">发送表情</button>
<script>
var sendEmoji = document.getElementById('sendEmoji')
// 定义最后光标对象
var lastEditRange;
// 编辑框点击事件
document.getElementById('edit').onclick = function() {
// 获取选定对象
var selection = getSelection()
// 设置最后光标对象
lastEditRange = selection.getRangeAt(0)
}
// 编辑框按键弹起事件
document.getElementById('edit').onkeyup = function() {
// 获取选定对象
var selection = getSelection()
// 设置最后光标对象
lastEditRange = selection.getRangeAt(0)
}
// 表情点击事件
document.getElementById('sendEmoji').onclick = function() {
// 获取编辑框对象
var edit = document.getElementById('edit')
// 获取输入框对象
var emojiInput = document.getElementById('emojiInput')
// 编辑框设置焦点
edit.focus()
// 获取选定对象
var selection = getSelection()
// 判断是否有最后光标对象存在
if (lastEditRange) {
// 存在最后光标对象,选定对象清除所有光标并添加最后光标还原之前的状态
selection.removeAllRanges()
selection.addRange(lastEditRange)
}
// 判断选定对象范围是编辑框还是文本节点
if (selection.anchorNode.nodeName != '#text') {
// 如果是编辑框范围。则创建表情文本节点进行插入
var emojiText = document.createTextNode(emojiInput.value)
if (edit.childNodes.length > 0) {
// 如果文本框的子元素大于0,则表示有其他元素,则按照位置插入表情节点
for (var i = 0; i < edit.childNodes.length; i++) {
if (i == selection.anchorOffset) {
edit.insertBefore(emojiText, edit.childNodes[i])
}
}
} else {
// 否则直接插入一个表情元素
edit.appendChild(emojiText)
}
// 创建新的光标对象
var range = document.createRange()
// 光标对象的范围界定为新建的表情节点
range.selectNodeContents(emojiText)
// 光标位置定位在表情节点的最大长度
range.setStart(emojiText, emojiText.length)
// 使光标开始和光标结束重叠
range.collapse(true)
// 清除选定对象的所有光标对象
selection.removeAllRanges()
// 插入新的光标对象
selection.addRange(range)
} else {
// 如果是文本节点则先获取光标对象
var range = selection.getRangeAt(0)
// 获取光标对象的范围界定对象,一般就是textNode对象
var textNode = range.startContainer;
// 获取光标位置
var rangeStartOffset = range.startOffset;
// 文本节点在光标位置处插入新的表情内容
textNode.insertData(rangeStartOffset, emojiInput.value)
// 光标移动到到原来的位置加上新内容的长度
range.setStart(textNode, rangeStartOffset + emojiInput.value.length)
// 光标开始和光标结束重叠
range.collapse(true)
// 清除选定对象的所有光标对象
selection.removeAllRanges()
// 插入新的光标对象
selection.addRange(range)
}
// 无论如何都要记录最后光标对象
lastEditRange = selection.getRangeAt(0)
}
</script>
</body>
</html>