javascript - 有没有办法使用 javascript 将样式应用于突出显示的文本?
问题描述
我正在努力创建一个功能丰富的文本编辑器,它可以模拟您在 MS word 和 google docs 等全尺寸文字处理器中找到的一些功能。我正在尝试将样式(粗体、斜体、突出显示等)应用于用户选择的文本。
我已经将完成这项工作的以下代码放在一起,但前提是突出显示的文本不跨越 html 元素。
const hightlightBtn = document.querySelector('.btn');
hightlightBtnS.addEventListener('click', () => {
const selected = window.getSelection().getRangeAt(0);
console.log(selected);
highlightElement(selected);
});
function highlightElement(range){
const newNode = document.createElement('div');
newNode.setAttribute(
'style',
'background-color: yellow; display: inline;'
)
range.surroundContents(newNode);
};
如果我尝试突出显示来自两个段落的文本(并分别包含在
标签)我得到了错误:
未捕获的 DOMException:无法在“范围”上执行“surroundContents”:范围已部分选择了非文本节点。
这似乎是surroundContents() 方法的问题。
在此方法的 MDN 参考资料中,我发现以下内容:
但是,如果 Range 仅使用其中一个边界点拆分非文本节点,则会引发异常。也就是说,与上面的替代方案不同,如果有部分选择的节点,它们将不会被克隆,而是操作将失败。
有什么办法可以在仍然使用环绕内容的同时解决这个问题?或者任何人都可以帮我找出另一种将样式应用于用户选择的文本的方法吗?
解决方案
为什么不简单地使用 CSS?
p::selection, p ::selection {
background-color: green;
color: #fff;
}
<p>Mark some text <i>here</i> in this paragraph.</p>
伪选择器::selection
具有非常广泛的浏览器支持,甚至可以追溯到 IE 9:
推荐阅读
- php - 搜索一个 json 文件
- mysql - 如何在 MySQL 8 中通过 int 而不是通过名称从嵌套 JSON 中获取
- perl - Perl 程序可以知道 __DATA__ 开始的行号吗?
- python - 递归比较两个列表
- ios - 在使用 ytplayer SDK 的应用程序中,某些 YouTube 视频无法播放
- c# - 有没有办法为 EF 模型自动创建 CRUD(目前是 DB First)
- python - TypeError:需要一个类似字节的对象,而不是 pd.read_csv 的“str”
- python - `droppdf[df.columnName != 'Value']` 不工作?
- javascript - 更改复选框上的变量值
- python - 如何将条形图的颜色链接到 yticks?