Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to make selected text (a range of a text block) with red background color?

19 views
Skip to first unread message

justaguy

unread,
May 19, 2013, 3:20:13 PM5/19/13
to
Hi,

Say, I have the following block of text:
"
Commuters are bracing for a difficult trip around southwest Connecticut and to New York City beginning Monday as workers repair the Metro-North commuter rail line crippled by a derailment and crash. Crews will spend days rebuilding 2,000 feet of track, overhead wires and signals following the collision...
"
And I want to have an ability to let a user to select, say, "rail" and "crash" with red background color, how?
With Firefox and Chrome.

Many thanks.

Michael Haufe (TNO)

unread,
May 19, 2013, 5:04:14 PM5/19/13
to
Here is a basic approach to get you started (some assembly required):

function highlight(node,text){
var html = node.innerHTML,
i = html.indexOf(text),
len = text.length;
if(i > -1){
node.innerHTML = html.substring(0,i) +
"<span class='hightlight'>" +
html.substring(i,i + len) +
"</span>" +
html.substring(i + len);
}
}

var node = document.getElementById("foo")
highlight(node,"rail")


On May 19, 2:20 pm, justaguy <lichunshe...@gmail.com> wrote:
> Hi,
>
> Say, I have the following block of text:
> "
> Commuters are bracing for a difficult trip around southwest Connecticut and to New York City beginning Monday as workers repair the Metro-North commuterrailline crippled by a derailment and crash.  Crews will spend days rebuilding 2,000 feet of track, overhead wires and signals following the collision...

Cezary Tomczyk

unread,
May 19, 2013, 5:22:23 PM5/19/13
to

justaguy

unread,
May 19, 2013, 5:47:43 PM5/19/13
to

>On Sunday, May 19, 2013 5:04:14 PM UTC-4, Michael Haufe (TNO) wrote:
> Here is a basic approach to get you started (some assembly required):
>
>
>
> function highlight(node,text){
>
> var html = node.innerHTML,
>
> i = html.indexOf(text),
>
> len = text.length;
>
> if(i > -1){
>
> node.innerHTML = html.substring(0,i) +
>
> "<span class='hightlight'>" +
>
> html.substring(i,i + len) +
>
> "</span>" +
>
> html.substring(i + len);
>
> }
>
> }
>
>
>
> var node = document.getElementById("foo")
>
> highlight(node,"rail")
>

If my understanding is correct, the problem with this solution is that,
we don't know that "rail" would be selected beforehand.

justaguy

unread,
May 19, 2013, 5:50:09 PM5/19/13
to
I should add (forgive me for top posting).

That the following code fails (does not do anything and no error), tested with Firefox 20.

<input type="button" onclick="var sel = document.getElementById("longtextstr").contentWindow.getSelection();sel.execCommand('foreColor',false, '#ff0000');sel.select();" style="background-color:Red;width:25;height:23" />

Michael Haufe (TNO)

unread,
May 19, 2013, 6:24:06 PM5/19/13
to
On May 19, 4:47 pm, justaguy <lichunshe...@gmail.com> wrote:
> >On Sunday, May 19, 2013 5:04:14 PM UTC-4, Michael Haufe (TNO) wrote:
> > Here is a basic approach to get you started (some assembly required):
[...]

> If my understanding is correct, the problem with this solution is that,
> we don't know that "rail" would be selected beforehand.

So you simply want a red highlight color on any selection and not to
actually do something like highlighting a search result? If so, then
this is a CSS issue. Cezary Tomczyk's solution would be more
appropriate

justaguy

unread,
May 19, 2013, 6:58:29 PM5/19/13
to
I've looked at this option as well, however, it seems to be able to deal with ONE selection only, that is, if I have multiple selections only the last selection would be affected. Am I wrong about this?

Thanks.

Michael Haufe (TNO)

unread,
May 19, 2013, 7:05:46 PM5/19/13
to
On May 19, 5:58 pm, justaguy <lichunshe...@gmail.com> wrote:
> On Sunday, May 19, 2013 5:22:23 PM UTC-4, Cezary Tomczyk wrote:
> > W dniu niedziela, 19 maja 2013 21:20:13 UTC+2 użytkownik justaguy napisał:
>
> > > Hi,
>
> > > Say, I have the following block of text:
>
> > > "
>
> > > Commuters are bracing for a difficult trip around southwest Connecticut and to New York City beginning Monday as workers repair the Metro-North commuter rail line crippled by a derailment and crash.  Crews will spend days rebuilding 2,000 feet of track, overhead wires and signals following the collision...
>
> > > "
>
> > > And I want to have an ability to let a user to select, say, "rail" and "crash" with red background color, how?
>
> > > With Firefox and Chrome.
>
> > Do you think about that solution?
>
> >http://css-tricks.com/overriding-the-default-text-selection-color-wit...
>
> > --
>
> > Cezary Tomczyk
>
> >http://www.ctomczyk.pl/
>
> I've looked at this option as well, however, it seems to be able to deal with ONE selection only, that is, if I have multiple selections only the last selection would be affected.  Am I wrong about this?
>
> Thanks.

In Firefox, at least, you can highlight multiple text blocks by
holding the CTRL when selecting (windows). The CSS solution works fine
for this. I don't know if chrome has the equivalent. I think I would
need to know a little more context to understand better what the goal
is.

justaguy

unread,
May 19, 2013, 8:59:48 PM5/19/13
to
No, no, misunderstanding here. Not how to select multiple text but once they are selected, the code won't be able to make all of them to have red background color.

Michael Haufe (TNO)

unread,
May 19, 2013, 9:45:59 PM5/19/13
to
On May 19, 7:59 pm, justaguy <lichunshe...@gmail.com> wrote:

> No, no, misunderstanding here.  Not how to select multiple text but once they are selected, the code won't be able to make all of them to have red background color.

Here is a slight improvement over the first solution I gave, though
still not a robust solution:

function selected(){
var sel = window.getSelection(),
cnt = sel.rangeCount,
ranges=[];
for(var i = 0; i < sel.rangeCount; i++)
ranges[i] = sel.getRangeAt(i);
return ranges
}

function highlight(node,sels){
var html = node.innerHTML;
sels.forEach(function(sel){
html = html.replace(new RegExp(sel,"g"),"<span
style='background-color:red'>$&</span>")
})
node.innerHTML = html
}

highlight(document.getElementById("foo"),selected())

--

Work to be done:
- obtaining selections relative to a particular node instead of the
entire document.
- not replacing the innerHTML of the node to highlight (references
attached directly to node contents can be lost)
- ... probably more I didn't think about in the handful of minutes I
spent on this

JJ

unread,
May 20, 2013, 7:06:33 PM5/20/13
to
On Sun, 19 May 2013 14:50:09 -0700 (PDT), justaguy wrote:
> I should add (forgive me for top posting).
>
> That the following code fails (does not do anything and no error), tested
> with Firefox 20.
>
> <input type="button" onclick="var sel =
> document.getElementById("longtextstr").contentWindow.getSelection();sel.execCommand('foreColor',false,
> '#ff0000');sel.select();" style="background-color:Red;width:25;height:23"
> />

contentWindow property is for IFrame and Object elements only, and
execCommand is a method of the document object only.

The document.designMode should be set to "on" before using execCommand that
modifies the document content, and set it back to "off" after all
modifications are done.

Assuming the "longtextstr" is not an Iframe, the code should be like this.

document.designMode = "on";
document.execCommand('foreColor', false, '#ff0000');
document.designMode = "off";

justaguy

unread,
May 21, 2013, 1:05:00 PM5/21/13
to
Sorry for insufficient information previously.
Yes, the longtextstr object/element is an iframe, and upon loading, it sets document.designMode = "on";

Also, I had a typo (with quotes),
<input type="button" onclick="var sel =document.getElementById("longtextstr").contentWindow.getSelection();sel.execCommand('foreColor',false,'#ff0000');sel.select();" style="background-color:Red;width:25;height:23">

should have been
<input type="button" onclick="var sel =document.getElementById('longtextstr').contentWindow.getSelection();sel.execCommand('foreColor',false,'#ff0000');sel.select();" style="background-color:Red;width:25;height:23">

Thanks.

JJ

unread,
May 21, 2013, 1:54:06 PM5/21/13
to
On Tue, 21 May 2013 10:05:00 -0700 (PDT), justaguy wrote:
>> contentWindow property is for IFrame and Object elements only, and
>> execCommand is a method of the document object only.
>>
>> The document.designMode should be set to "on" before using execCommand that
>> modifies the document content, and set it back to "off" after all
>> modifications are done.
>>
>> Assuming the "longtextstr" is not an Iframe, the code should be like this.
>>
>> document.designMode = "on";
>> document.execCommand('foreColor', false, '#ff0000');
>> document.designMode = "off";
>
> Sorry for insufficient information previously. Yes, the longtextstr
> object/element is an iframe, and upon loading, it sets
> document.designMode = "on";
>
> Also, I had a typo (with quotes), <input type="button" onclick="var sel
> =document.getElementById("longtextstr").contentWindow.getSelection();sel.execCommand('foreColor',false,'#ff0000');sel.select();"
> style="background-color:Red;width:25;height:23">
>
> should have been <input type="button" onclick="var sel
> =document.getElementById('longtextstr').contentWindow.getSelection();sel.execCommand('foreColor',false,'#ff0000');sel.select();"
> style="background-color:Red;width:25;height:23">

Then, the code should be like this.

var wnd = document.getElementById('longtextstr').contentWindow;
wnd.document.execCommand('foreColor', false, '#ff0000');

Assuming that:
- The IFrame element is present
- The IFrame content has finished loading
- The code/script is not violating cross-scripting policy (when accessing
the IFrame content).

Thomas 'PointedEars' Lahn

unread,
May 21, 2013, 4:38:36 PM5/21/13
to
justaguy wrote:

> On Monday, May 20, 2013 7:06:33 PM UTC-4, JJ wrote:
>> Assuming the "longtextstr" is not an Iframe, the code should be like
>> this.
>>
>> document.designMode = "on";
>>
>> document.execCommand('foreColor', false, '#ff0000');
^^^^^^^^
>> document.designMode = "off";
>
> Sorry for insufficient information previously.
> Yes, the longtextstr object/element is an iframe, and upon loading, it
> sets document.designMode = "on";
>
> Also, I had a typo (with quotes),

[word-wrapped at column 80]
> <input type="button" onclick="var sel
> =document.getElementById("longtextstr").contentWindow.getSelection();
> sel.execCommand('foreColor',false,'#ff0000');sel.select();"
> style="background-color:Red;width:25;height:23">
>
> should have been
> <input type="button" onclick="var sel
> =document.getElementById('longtextstr').contentWindow.getSelection();
> sel.execCommand('foreColor',false,'#ff0000');sel.select();"
> style="background-color:Red;width:25;height:23">

(Please learn to post properly. Do not use Google Groups for posting, it is
borken. See also <http://jibbering.com/faq/#posting> and
<http://PointedEars.de/faq#posting>.)

A “Selection” instance as returned by the getSelection() method and referred
here by “sel” still has not nor inherits an execCommand() or a select()
method, as the error console would have told you. The former is a method of
“(HTML)Document” instances, inherited from the Document prototype object.
The latter method I do not see existing at all in that context.

ISTM that the proprietary execCommand() API is generally incompatible with
the standards-compliant (W3C) Selection API. If you are using the Selection
API, you would have to use the properties of the returned object
(“baseNode”, “baseOffset”, “extentNode”, “extendOffset”, aso.), and DOM
Level 3 Core methods to split the text node in two and insert a
corresponding (“span”) element in-between.

Text formatting of selections is infinitely easier, but OTOH limited to the
commands that execCommand() supports, if you use the execCommand() API, as
e. g. the “foreColor” command will simply set the foreground color of the
selected portion of the document, provided designMode == "on". Another
important disadvantage of the execCommand() API is that at least in Chromium
26 it do text formatting by inserting a deprecated/invalid “font” element
instead of with a (“span”) element formatted by CSS.

Your Subject says “background color”, but you are using “foreColor” in the
code. Make up your mind.

--
PointedEars

Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

justaguy

unread,
May 22, 2013, 12:25:43 AM5/22/13
to
Beautiful, it works, tested with Firefox 20 and Chrome 26, thank you.

0 new messages