获取网页上用户选择的文本中包含的元素列表
Getting a list of elements contained in user-selected text on a webpage
给定这样一个页面:
<p>
<span class="1">Here's some text</span>
<span class="2">that the user</span>
<span class="3">could select.</span>
</p>
如果用户选择了整个句子(从"Here's"到"select."),我想return“1”和“3”。
如果用户选择了句子的一部分(从跨度 1 中的 "some" 到跨度 2 中的 "the"),我想 return“1”和“2”。
最好的方法是什么?
*Edit - 我正在寻找一种允许同时突出显示多段(非重叠)文本的解决方案。
例如:
"Here's some text that" 和 "user could select."
- 在这种情况下,[[1,2],[2,3]] 将被 returned.
编辑:我刚刚发现实际上有一个 selection.containsNode 方法,听起来很适合您,但显然它仍然是一项实验性技术。
javascript 中没有广泛的突出显示事件,因此解决方案不会简单明了,而且文本被拆分成多个元素这一事实使解决方案变得更加困难。您 可以 将 document.selection
用作 the top answer to this similar question suggests,但是您仍然需要根据 span
元素的 innerHTML 解析返回的文本,这看起来像会很麻烦。
我认为在这种情况下,您最好的选择是基本上使用现有的 JS 事件重新创建突出显示功能。这是一个天真的实现,缺少一些功能,如双击 select 和键盘 selection,但你明白了。
const hLights = Array.from(document.querySelectorAll('.hlight'));
let active = false;
let hoveredEls = [];
window.addEventListener('mousedown', function() {
active = true;
});
window.addEventListener('mouseup', function() {
active = false;
console.log(hoveredEls);
hoveredEls = [];
});
hLights.forEach(el => {
el.addEventListener('mousemove', function() {
if (active && !hoveredEls.includes(el.id)) hoveredEls.push(el.id);
});
el.addEventListener('mouseenter', function() {
if (active) {
if(hoveredEls.includes(el.id)) {
const idx = hoveredEls.findIndex(el => el === el.id);
hoveredEls.splice(idx, 1);
} else {
hoveredEls.push(el.id);
}
}
});
});
<p>
<span id="1" class="hlight">Here's some text</span>
<span id="2" class="hlight">that the user</span>
<span id="3" class="hlight">could select.</span>
</p>
so here is the html
<span class="class-1"
onmousedown="getElementBegin('1')" onmouseup="getElementEnd('1')" >
algum texto 1
</span> <br>
<span class="class-2"
onmousedown="getElementBegin('2')" onmouseup="getElementEnd('2')">
algum texto 2
</span> <br>
<span class="class-3"
onmousedown="getElementBegin('3')" onmouseup="getElementEnd('3')">
algum texto 3
</span> <br>
<p id="selected"> nada!</p>
And here is the js:
let begin
let end
let selection
document.onmouseup = function () {
selection = window.getSelection().toString()
console.log(selection);
selected = document.getElementById('selected')
selected.innerHTML = `selection goes to: ${begin} until ${end} <br> selection: ${selection}`
}
function getElementBegin(beginElement) {
begin = beginElement
console.log(begin)
}
function getElementEnd(endElement) {
end = endElement
console.log(end)
}
给定这样一个页面:
<p>
<span class="1">Here's some text</span>
<span class="2">that the user</span>
<span class="3">could select.</span>
</p>
如果用户选择了整个句子(从"Here's"到"select."),我想return“1”和“3”。
如果用户选择了句子的一部分(从跨度 1 中的 "some" 到跨度 2 中的 "the"),我想 return“1”和“2”。
最好的方法是什么?
*Edit - 我正在寻找一种允许同时突出显示多段(非重叠)文本的解决方案。
例如: "Here's some text that" 和 "user could select." - 在这种情况下,[[1,2],[2,3]] 将被 returned.
编辑:我刚刚发现实际上有一个 selection.containsNode 方法,听起来很适合您,但显然它仍然是一项实验性技术。
javascript 中没有广泛的突出显示事件,因此解决方案不会简单明了,而且文本被拆分成多个元素这一事实使解决方案变得更加困难。您 可以 将 document.selection
用作 the top answer to this similar question suggests,但是您仍然需要根据 span
元素的 innerHTML 解析返回的文本,这看起来像会很麻烦。
我认为在这种情况下,您最好的选择是基本上使用现有的 JS 事件重新创建突出显示功能。这是一个天真的实现,缺少一些功能,如双击 select 和键盘 selection,但你明白了。
const hLights = Array.from(document.querySelectorAll('.hlight'));
let active = false;
let hoveredEls = [];
window.addEventListener('mousedown', function() {
active = true;
});
window.addEventListener('mouseup', function() {
active = false;
console.log(hoveredEls);
hoveredEls = [];
});
hLights.forEach(el => {
el.addEventListener('mousemove', function() {
if (active && !hoveredEls.includes(el.id)) hoveredEls.push(el.id);
});
el.addEventListener('mouseenter', function() {
if (active) {
if(hoveredEls.includes(el.id)) {
const idx = hoveredEls.findIndex(el => el === el.id);
hoveredEls.splice(idx, 1);
} else {
hoveredEls.push(el.id);
}
}
});
});
<p>
<span id="1" class="hlight">Here's some text</span>
<span id="2" class="hlight">that the user</span>
<span id="3" class="hlight">could select.</span>
</p>
so here is the html
<span class="class-1"
onmousedown="getElementBegin('1')" onmouseup="getElementEnd('1')" >
algum texto 1
</span> <br>
<span class="class-2"
onmousedown="getElementBegin('2')" onmouseup="getElementEnd('2')">
algum texto 2
</span> <br>
<span class="class-3"
onmousedown="getElementBegin('3')" onmouseup="getElementEnd('3')">
algum texto 3
</span> <br>
<p id="selected"> nada!</p>
And here is the js:
let begin
let end
let selection
document.onmouseup = function () {
selection = window.getSelection().toString()
console.log(selection);
selected = document.getElementById('selected')
selected.innerHTML = `selection goes to: ${begin} until ${end} <br> selection: ${selection}`
}
function getElementBegin(beginElement) {
begin = beginElement
console.log(begin)
}
function getElementEnd(endElement) {
end = endElement
console.log(end)
}