我正在尝试制作一个 JavaScript 小书签,它将充当荧光笔,当按下小书签时,将网页上选定文本的背景更改为黄色。
我使用以下代码来获取所选文本,它工作正常,返回正确的字符串
function getSelText() {
var SelText = '';
if (window.getSelection) {
SelText = window.getSelection();
} else if (document.getSelection) {
SelText = document.getSelection();
} else if (document.selection) {
SelText = document.selection.createRange().text;
}
return SelText;
}
但是,当我创建一个类似的函数来使用 jQuery 更改所选文本的 CSS 时,它不起作用:
function highlightSelText() {
var SelText;
if (window.getSelection) {
SelText = window.getSelection();
} else if (document.getSelection) {
SelText = document.getSelection();
} else if (document.selection) {
SelText = document.selection.createRange().text;
}
$(SelText).css({'background-color' : 'yellow', 'font-weight' : 'bolder'});
}
有什么想法吗?
最简单的方法是使用
execCommand()
,它有一个命令可以更改所有现代浏览器中的背景颜色。
以下内容应该对任何选择执行您想要的操作,包括跨越多个元素的选择。在非 IE 浏览器中,它会打开
designMode
,应用背景颜色,然后再次关闭 designMode
。
更新
已在 IE 9 中修复。
function makeEditableAndHighlight(colour) {
var range, sel = window.getSelection();
if (sel.rangeCount && sel.getRangeAt) {
range = sel.getRangeAt(0);
}
document.designMode = "on";
if (range) {
sel.removeAllRanges();
sel.addRange(range);
}
// Use HiliteColor since some browsers apply BackColor to the whole block
if (!document.execCommand("HiliteColor", false, colour)) {
document.execCommand("BackColor", false, colour);
}
document.designMode = "off";
}
function highlight(colour) {
var range, sel;
if (window.getSelection) {
// IE9 and non-IE
try {
if (!document.execCommand("BackColor", false, colour)) {
makeEditableAndHighlight(colour);
}
} catch (ex) {
makeEditableAndHighlight(colour)
}
} else if (document.selection && document.selection.createRange) {
// IE <= 8 case
range = document.selection.createRange();
range.execCommand("BackColor", false, colour);
}
}
这是一个简单的例子来说明它是如何工作的。正如扎克指出的那样,您需要注意选择跨越多个元素的情况。这并不是要按原样使用,只是为了帮助想法流动。在 Chrome 中测试。
var selection = window.getSelection();
var text = selection.toString();
var parent = $(selection.focusNode.parentElement);
var oldHtml = parent.html();
var newHtml = oldHtml.replace(text, "<span class='highlight'>"+text+"</span>");
parent.html( newHtml );
为了使突出显示永久保留,我相信您必须将选择内容包装在一个新的 DOM 元素中(
span
应该这样做),然后您可以附加样式属性。我不知道 jQuery 是否可以为你做到这一点。请记住,选择可以跨越元素边界,因此在一般情况下,您将不得不注入一大堆新元素
看看我在 http://www.jsfiddle.net/hbwEE/3/
制作的一个小例子它没有考虑跨越多个元素的选择。 (IE 也可以,但会弄乱 html ..)
在 Firefox 中,您可以使用
::-moz-selection
伪类。::selection
伪类。
CSS 高亮 API,https://developer.mozilla.org/en-US/docs/Web/API/CSS_Custom_Highlight_API,旨在实现您想要的功能。在 JS 中,您可以将范围标记为具有命名的突出显示样式,而在 CSS 中,您可以定义突出显示的内容。浏览器应该做一些看起来像选择但持久的事情。