Finding the textarea selection
A desperate web developer emailed me asking how make a bookmarklet that does something with the selected text, where the selected text is usually in a textarea.
He had tried using window.getSelection.toString(), but that doesn't work, because window.getSelection() is implemented in terms of DOM Ranges and it doesn't make much sense to have a DOM Range inside a textarea.
Here are some of the methods I tried:
- Determine focus using by tracking with onfocus or onblur events. Works for web pages, but doesn't work for bookmarklets.
- Determine focus using window.getSelection().getRangeAt(...) and commonAncestorContainer. Doesn't work (bug 336936).
- Determine focus using a XUL document in an iframe and commandDispatcher.focusedElement. Ugly Firefox-only hack, but it works.
- Determine focus using WhatWG's document.currentFocus. Only a working draft, not implemented in Firefox yet (bug 337631).
- Use selectionStart / selectionEnd in all textareas. This can return nonempty selections from multiple textareas.
Am I missing a sane solution that works in current versions of Firefox?
May 6th, 2006 at 7:22 pm
Sound like you’d like https://bugzilla.mozilla.org/show_bug.cgi?id=296471 to be implemented, and/or the WHATWG focus work. Of course, these solutions would only work for future Firefox versions.
What does the developer use to make this stuff work on IE? The IE focus model stuff like in the bug linked above?
May 6th, 2006 at 7:42 pm
IE’s document.selection.createRange().text works for textareas as well as for web page text. Most search bookmarklets use it in their IE branches.
May 7th, 2006 at 1:15 am
Hmm, what was the name of the desperate web developer? Michael Palmer?
In that case, it was someone who was mass-mailing.
May 7th, 2006 at 2:52 am
Yes, it was Michael Palmer.
May 7th, 2006 at 2:55 am
Maybe he only mass-mailed people who had left useful comments on bug 85686, which wouldn’t be too many people. Still, it’s a bit deceptive to mail multiple people and make the mail look like it only has one recipient.
May 7th, 2006 at 5:51 am
Yes, I too think that’s a bit deceptive. I also went through quite some trouble to give him an answer.
I didn’t get a reply from him yet.
Instead of mailing, I think he should just comment in the bug or ask his question in the mozilla newsgroups or the mozillazine forums (which I replied in my e-mail to him).
May 7th, 2006 at 11:07 am
In case the brief answers given above aren’t enough, here’s what I’ve used in some web apps. It works, but it requires that you pass in the appropriate textarea as a parameter.
getSelection: function( el )
{
if ( el.selectionStart == undefined )
{
var r = document.selection.createRange();
return new Array( r.start, r.end );
}
else
{
return new Array( el.selectionStart, el.selectionEnd );
}
},
(That’s part of a class prototype, thus the slightly weird indenting and formatting.)
I don’t remember how to ask Firefox which element currently has the focus. If he needs this to work generically with whatever is the current textarea (rather than one in particular), he’ll have to use the focus/blur events to keep track of which item is ‘current’.
You probably figured all of this out anyway, but I happened to have this code handy when I saw your question.
May 7th, 2006 at 12:18 pm
Seth, bookmarklets can’t use focus/blur events to track focus without requiring extra clicks.
May 7th, 2006 at 8:26 pm
I suppose to track the focus you could add a rule to the stylesheet that says something like textarea:focus { elevation: 90; }. Then you just look at the computed style for all of the textareas and see which one has an elevation of 90. There are a couple of unused or rarely used css properties you could commandeer.
It’s a bit of a hack though.
May 8th, 2006 at 10:01 am
Yes, I think the :focus hack from db48x is the best hack of them all, thus far (until someone implements document.currentFocus in Firefox).
May 9th, 2006 at 8:12 am
Here’s one I wrote which has both FF and IE versions. Feel free to use any of the methods I employ. Cheers.
May 9th, 2006 at 8:13 am
A link helps… http://thlayli.detrave.net/tagblaster.html
May 10th, 2006 at 9:20 am
[…] How to detect the currently focused element via JS, without adding a ton of onFocus/onBlur handlers to everything […]
May 17th, 2006 at 8:22 am
How do they do it on the WSJ homepage? (www.wsj.com) If you select text and right-click, they search for it. pretty cool all around.
May 17th, 2006 at 8:46 pm
The WSJ feature doesn’t involve textareas.
May 19th, 2006 at 7:41 am
The code for Daniel’s suggestion for my future reference, if you don’t mind me putting it here.
//textarea:focus { z-index: 57; }
function getFocusedTextArea() {
var textareas = document.getElementsByTagName(“textarea”);
for(var i=0; i lessthan textareas.length; i++) {
var ta = textareas.item(i);
if (window.getComputedStyle(ta, null).zIndex == 57) {
return ta;
}
}
}
May 19th, 2006 at 8:02 am
Greetings,
I found your name as one of the mentors for Google Summer of code.
Could you tell me who would be the person most interested in improvements in Mozilla Download Manager? there is no mentor listed on the site. Your swift reply would be awsome. (I just got off from my final exams and apprently there isnt much time before acceptance are sent out by Google)
i wasn’t able to find an email address for you (easily) so i posted a comment on ur blog. hope it reaches in time
—
Shahzada Hatim
http://hatim.webhop.info
May 19th, 2006 at 1:59 pm
Depends on what aspect of download manager you’re hoping to improve. For the UI, I’m not sure who the best person is, but you could start by talking with beltzner or mconnor or Gavin Sharp. For backend stuff like making donwloads resumable across sessions, I’d start with Christian Biesinger, since he has made useful comments on the bug about resumable downloads.
Btw, it’s not that hard to find my contact information.