如果你想实现这种效果
或这种 ...
又或是这种 ...
那么你就需要深入了解浏览器的
Range、Selection
特性
1. Range、Selection 是啥?
为了让开发人员更方便地控制页面,“DOM2 级遍历和范围”模块定义了“范围(Range)接口”。通过范围(Range)可以选择文档中的一个区域,而不必考虑节点的界限。
——《JavaScript 高级程序设计》
Selection 代表当前处于选中状态的区域,Selection 与 Range 之间可以互相转换。比如我们可以获取当前鼠标选中区域中的文字,或通过编程将指定区域中的文字选中;
2. 兼容性怎么样?
兼容性这方面,IE 从没让我们失望过...
W3C 的标准接口是:
IE 并没有鸟 W3C,自己整了一套:
3. W3C 标准接口怎么用?
W3C 标准接口涉及:Range、selectionRange;
3.1. Range
Range 代表文档中连续的一部分;
接口简介:
创建一个空 Range: var rangeObj = document.createRange(); 调整 Range 边界: rangeObj.setStart(node, offsetInsideNode); rangeObj.setEnd(node, offsetInsideNode); rangeObj.setStartBefore(node); rangeObj.setStartAfter(node); rangeObj.setEndBefore(node); rangeObj.setEndAfter(node); 折叠 Range 边界: rangeObj.collapse([toStart]); 获取 Range 内容: rangeObj.toString(); 删除 Range 内容: rangeObj.deleteContents();
示例1:deleteContents();
代码分析:
3.2. selectionRange
selectedRange 代表当前文档中选中的部分。
接口简介:
获取文档中当前选中的部分: var selRange = window.getSelection(); 获取当前选中部分的文本; selRange.toString(); 调整当前选中区的 Range: selRange.addRange(rangeToAdd); selRange.removeAllRanges();
示例2:selRange.toString();
代码分析:
示例3:selRange.addRange
代码分析:
示例4:示例2的微调版,从 div 换成 textarea;
4. IE 专有接口怎么用?
IE 从 9 开始,就实现了 W3C 的标准 Range 接口;但IE7、IE8这些老古董,就只能用 IE 自己的 TextRange 和 selection 接口;
4.1. TextRange
与 W3C 的Range 含义一样,代表文档中连续的一部分;
接口简介:
创建一个 TextRange: var range = document.body.createTextRange(); 调整 Range 边界: range.moveToElementText(element);range.moveStart(unitToMove [, numberOfUnits]); range.moveEnd(unitToMove [, numberOfUnits]); 折叠 Range 边界: range.collapse([toStart]); 高亮选中 Range 中的内容: range.select();
示例5:textRange.moveStart、moveEnd等;
代码分析:
4.2. selection
与 W3C 的 selectedRange 含义相同,代表当前文档中选中的部分;
接口简介:
获取文档中当前选中的部分: var selection = document.selection; 从文档中删除当前选中的部分; selection.clear(); 取消当前的选中状态; selection.empty(); 转换当前选中部分为 TextRange; selection.createRange();
示例6:document.selection.createRange().text;
代码分析:
今天的栗子有点多
5. 应用场景
Range 与 Selection 在类似下图这种 Mask Input(自动格式化录入)插件中有广泛应用;
下面这些开源插件
基本都与 Mask Input 有关
也基本都涉及 Range 与 Selection
大家可以参考参考
找找灵感
jquery.formance: 仓库:https://github.com/omarshammas/jquery.formance 状态:5年前停止维护 labelmask: 仓库:https://github.com/bradfrost/labelmask 状态:4年前停止维护 maskjs: 仓库:https://github.com/bguzmanrio/maskjs 状态:3年前停止维护 jquery.maskedinput: 仓库:https://github.com/digitalBush/jquery.maskedinput 状态:3年前停止维护 rangy: 仓库:https://github.com/timdown/rangy 状态:3年前停止维护 input-masking: 仓库:https://github.com/estelle/input-masking 状态:2年前停止维护 jquery.payment: 仓库:https://github.com/stripe/jquery.payment 状态:2年前停止维护 vanilla-masker: 仓库:https://github.com/vanilla-masker/vanilla-masker 状态:1年前停止维护
Inputmask: 仓库:https://github.com/RobinHerbots/Inputmask 状态:活跃; intl-tel-input: 仓库:https://github.com/jackocnr/intl-tel-input 状态:活跃 text-mask: 仓库:https://github.com/text-mask/text-mask 状态:活跃 cleave.js: 仓库:https://github.com/nosir/cleave.js 状态:活跃
参考:
https://jquery-plugins.net/ Dottoro Web Reference: http://help.dottoro.com/ljfjepre.php https://www.quirksmode.org/dom/range_intro.html https://www.quirksmode.org/dom/w3c_range.html