我已经知道如何使用document.selection进行突出显示。对于example
/* http://jsfiddle.net/4J2dy/ */
$("#content").on('mouseup', function() {
highlighting();
});
var highlighting = function () {
var seleted_str = (document.all) ? document.selection.createRange().text : document.getSelection();
if(seleted_str != "") {
var stringToBeHighlighted = seleted_str.getRangeAt(0);
var span = document.createElement("span");
span.style.cssText = "background-color: #80deea";
span.className = "MT";
stringToBeHighlighted.surroundContents(span);
}
};
但有些事情我不知道如何实现。
让我们说我有四个同时使用相同内容创建的图层。
我想在控制层上选择一个句子,同时也会选择其他三个层中的所有相同句子。(见下图)
选择之后,我想弹出一个菜单(我可以做),并根据按下的按钮获取DOM元素。(见下图)
有人能告诉我如何实现这个目标吗?或者它无法完成?如果有人能为我回答,我将不胜感激。
答案 0 :(得分:1)
这种可能性,我很感激SO用户Tim Down的输入,因为他对JS Range / Selections有很多了解,但我已经提出了我的部分解决方案。
您可以只存储startOffset
&而不是选择4个图层。在endOffset
上更新的外部对象中的mouseup
。唯一的副作用是,用户的选择只会在点击图层按钮时获得span
的颜色。
优点是你现在可以简单地使用DOM文本节点而不是范围/选择(无论如何,对我来说更复杂)。
我已经选择在按钮上找到data-layer
属性的图层,并在图层上找到相应的id
图层。我处理了'追加'选择的跨度'通过切片图层中文本节点的文本内容,如下所示:
layer.innerHTML = txt.slice(0, selText.start)
+ '<span class="MT" style="background-color: #80deea">'
+ txt.slice(selText.start, selText.end) + '</span>'
+ txt.slice(selText.end, txt.length);
查看 in action here 。我添加了cleanSelection
功能,因此一次只能进行一次选择(开始和结束计数器失败,因为选择范围不考虑HTML标记,所以你必须摆脱的跨度)。
最后的说明:
getElementsByClassName
整个JS代码作为参考(也在fiddle中):
// this object will hold the start & end offsets of selection value
var selText = false;
// selText will be updated on mouseup
document.body.onmouseup = getSelText;
// on button click, selText will be highlighted
document.body.onclick = function(e) {
var target = e.target || e.srcElement, range, layer, txt;
// only do if it's a layer button & the selection is non-empty
if (target.getAttribute('data-layer') && selText !== false) {
// first remove previous spans, they break the startOffset & endOffset of the selection range
cleanSelection();
// get the clicked layer
layer = document.getElementById(target.getAttribute('data-layer'));
// this assumes that the first node in the layer is a textNode
txt = layer.firstChild.nodeValue;
// let's append the selection container now
layer.innerHTML = txt.slice(0, selText.start)
+ '<span class="MT" style="background-color: #80deea">'
+ txt.slice(selText.start, selText.end) + '</span>'
+ txt.slice(selText.end, txt.length);
// ...and empty the 'real selection'
window.getSelection().collapse();
// log results to console
console.log('From char ' + selText.start + ' to char ' + selText.end + ', in ' + layer.id);
}
};
function getSelText () {
var seleted_str = (document.all) ? document.selection.createRange().text : document.getSelection(), stringToBeHighlighted;
if(seleted_str !== "") {
stringToBeHighlighted = seleted_str.getRangeAt(0);
selText = {
start: stringToBeHighlighted.startOffset,
end: stringToBeHighlighted.endOffset
};
} else {
selText = false;
}
}
function cleanSelection() {
var getText, mtSpan = document.getElementsByClassName('MT');
for ( var i = 0; i < mtSpan.length; i++) {
getText = mtSpan[i].innerHTML;
mtSpan[i].previousSibling.nodeValue = mtSpan[i].previousSibling.nodeValue + getText + mtSpan[i].nextSibling.nodeValue;
mtSpan[i].parentNode.removeChild(mtSpan[i].nextSibling);
mtSpan[i].parentNode.removeChild(mtSpan[i]);
}
}