[英]Change CSS of selected text using Javascript
I'm trying to make a javascript bookmarklet that will act as a highlighter, changing the background of selected text on a webpage to yellow when the bookmarklet is pressed. 我正在尝试制作一个将用作荧光笔的javascript小书签,当按小书签时,将网页上所选文本的背景更改为黄色。
I'm using the following code to get the selected text, and it works fine, returning the correct string 我正在使用以下代码来获取选定的文本,并且工作正常,返回正确的字符串
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;
} }
However, when I created a similar function to change the CSS of the selected text using jQuery, it isn't working: 但是,当我创建了一个类似的函数来使用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'});
} }
Any ideas? 有任何想法吗?
The easiest way to do this is to use execCommand()
, which has a command to change the background colour in all modern browsers. 最简单的方法是使用
execCommand()
,该命令具有在所有现代浏览器中更改背景颜色的命令。
The following should do what you want on any selection, including ones spanning multiple elements. 以下应该在任何选择上做您想要的,包括跨越多个元素的选择。 In non-IE browsers it turns on
designMode
, applies a background colour and then switches designMode
off again. 在非IE浏览器中,它将打开
designMode
,应用背景色,然后再次关闭designMode
。
UPDATE 更新
Fixed in IE 9. 在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);
}
}
Here is a crude example of how it could work. 这是它如何工作的粗略示例。 As Zack points out you'll need to be aware of cases where the selection spans multiple elements.
正如Zack指出的那样,您需要注意选择跨越多个元素的情况。 This isn't intended to be used as-is, just something to help get ideas flowing.
这并不是按原样使用的,只是可以帮助使想法流传的东西。 Tested in Chrome.
在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 );
In Firefox, you can use the ::-moz-selection
psuedo-class. 在Firefox中,您可以使用
::-moz-selection
psuedo-class。
In Webkit, you can use the ::selection
pseudo-class. 在Webkit中,可以使用
::selection
伪类。
Have a look at a little example i made at http://www.jsfiddle.net/hbwEE/3/ 看看我在http://www.jsfiddle.net/hbwEE/3/上做的一个小例子
It does not take into account selections that span multiple elements.. ( IE will do but will mess the html a bit .. ) 它没有考虑跨多个元素的选择。( IE会这样做,但会使HTML有点混乱.. )
To make the highlight stick permanently, I believe you are going to have to wrap the selection in a new DOM element ( span
should do), to which you can then attach style properties. 为了使高光棒永久保持不变,我相信您将不得不将选择内容包装在新的DOM元素中(
span
应该这样做),然后可以将样式属性附加到该元素。 I don't know if jQuery can do that for you. 我不知道jQuery是否可以为您做到这一点。 Keep in mind that selections can span element boundaries, so in the general case you're going to have to inject a whole bunch of new elements
请记住,选择可能会跨越元素边界,因此在一般情况下,您将不得不注入一堆新元素
I like Tim's answer, it's clean and fast. 我喜欢蒂姆的答案,它干净快捷。 But it also shuts down the doors to doing any interactions with the highlights.
但这也关闭了与高光进行任何交互的大门。
Inserting inline elements directly around the texts is a bad choice, as they broke the text flow and mess things up in complex situations, 直接在文本周围插入内联元素是一个不好的选择,因为它们会破坏文本流并使混乱的情况变得混乱,
So I suggest a dirty hack that 因此,我建议一个肮脏的黑客是
This chrome extension is an example of how this can be done. 此chrome扩展程序是如何完成此操作的示例。
It uses API from this library to get the absolute layout of each selected line. 它使用此库中的 API来获取每个选定行的绝对布局。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.