提问人:Mr. Polywhirl 提问时间:8/2/2023 最后编辑:Mr. Polywhirl 更新时间:8/2/2023 访问量:23
选择 API containsNode 似乎与可见选择不一致
Selection API containsNode seems inconsistent with visible selection
问:
Selection: containsNode()
方法采用可选的第二个参数,即 .partialContainment
当我将其设置为 时,它似乎工作正常,但有时会拾取不属于可见选择的相邻元素。我将其设置为更严格,但它缺少元素。true
false
页面上可见的“突出显示”与 API 解释“选择”内容的方式之间是否有区别?
在下面的示例中,如果选择部分文本,则某些字母不会变为活动状态,即使它们被明显突出显示。我需要更改哪些内容才能使文本变为红色,以显示为选中的任何内容?
const sequences = ['CRABAPPLE', 'ORANGES', 'SQUASH'];
const handleTextSelection = (e) => {
const selection = window.getSelection();
const $container = $(e.currentTarget);
const $sequence = $(e.target).closest('.sequence');
$sequence.find('.letter').each((i, el) => {
$(el).toggleClass('letter-active', selection.containsNode(el, false));
});
selection.empty();
};
$('#container').append(sequences.map(sequence =>
$('<div>', { class: 'sequence' }).append(sequence.split('').map(letter =>
$('<div>', { class: 'letter', text: letter })))));
$('#container').on('mouseup', handleTextSelection);
html, body, #container { width: 100%; height: 100%; margin: 0; padding: 0; }
#container { display: flex; flex-direction: row; gap: 0.25rem; align-items: center; justify-content: center; }
.sequence { display: flex; flex-direction: row; }
.sequence:after { content: ','; }
.sequence:last-child:after { content: none; }
.letter-active { color: red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container"><div>
更新
以下似乎效果更好一些,但它仍然将部分(未实际选择)字母视为已选择。
const sequences = ['CRABAPPLE', 'ORANGES', 'SQUASH'];
const getLetter = (node) => {
let letter = node;
if (node.nodeName === '#text') { node = node.parentElement; }
return node.classList.contains('letter') ? node : null;
};
const handleTextSelection = (e) => {
const selection = window.getSelection();
const range = selection.getRangeAt(0);
const { startContainer, endContainer } = range
const $container = $(e.currentTarget);
const $sequence = $(range.commonAncestorContainer);
const letterStart = getLetter(startContainer);
const letterEnd = getLetter(endContainer);
if (!letterStart || !letterEnd) { return; }
let active = false;
$sequence.find('.letter').each((i, el) => {
if (el === letterStart) { active = true; }
$(el).toggleClass('letter-active', active);
if (el === letterEnd) { active = false; }
});
selection.empty();
};
$('#container').append(sequences.map(sequence =>
$('<div>', { class: 'sequence' }).append(sequence.split('').map(letter =>
$('<div>', { class: 'letter', text: letter })))));
$('#container').on('mouseup', handleTextSelection);
html, body, #container { width: 100%; height: 100%; margin: 0; padding: 0; }
#container { display: flex; flex-direction: row; gap: 0.25rem; align-items: center; justify-content: center; }
.sequence { display: flex; flex-direction: row; }
.sequence:after { content: ','; }
.sequence:last-child:after { content: none; }
.letter-active { color: red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container"><div>
答: 暂无答案
评论