Got selected text, but can I get surrounding context?

Discussion in 'Javascript' started by Dekortage, Feb 22, 2007.

  1. Dekortage

    Dekortage Guest

    Hi all...

    I am able to grab the text that a user has selected on a web page,
    using this code:

    function moreInfo() {
    if (!isIE) {
    var t = window.getSelection();
    // act on variable "t";

    } else if (document.selection && document.selection.createRange) {
    var t = document.selection.createRange();
    if (document.selection.type == 'Text' && t.text>'') {
    document.selection.empty();
    // act on variable "t";

    }
    }
    }

    (the boolean "isIE" is established earlier in the code)

    This works. However, I'm wondering how to get the words *around* the
    selected word. Take these sentences for example: "If you need to
    framglubble the zartbox, then you should buy the red widget.
    Otherwise you can buy the blue widget and save some money."

    My code will tell me if the person has selected the word "widget".
    But I'd like to know if the selection is after "red" or "blue". Is
    this possible? I've been scouring the Internet for some advice, and
    I'm having trouble finding an answer.

    Many thanks in advance for your time.
     
    Dekortage, Feb 22, 2007
    #1
    1. Advertising

  2. Dekortage

    VK Guest

    On Feb 22, 7:39 pm, "Dekortage" <> wrote:
    > My code will tell me if the person has selected the word "widget".
    > But I'd like to know if the selection is after "red" or "blue". Is
    > this possible?


    Not in any straightforward way AFAIK.

    You may extend/shift range left or right to see what words will be
    added. In any case it presumes some fixed content you know in advance
    so able to recognize by fragments. In this case wouldn't it be much
    more easy to mark all needed segments in advance? Just a suggestion:

    <p>If you need to framglubble the zartbox, then you should buy the
    <span onclick="f(this)">red widget</span>.
    Otherwise you can buy the <span click="f(this)">blue widget</span> and
    save some money.</p>
     
    VK, Feb 22, 2007
    #2
    1. Advertising

  3. Dekortage

    Dekortage Guest

    On Feb 22, 3:36 pm, "VK" <> wrote:

    > You may extend/shift range left or right to see what words will be
    > added. In any case it presumes some fixed content you know in advance
    > so able to recognize by fragments. In this case wouldn't it be much
    > more easy to mark all needed segments in advance? Just a suggestion:
    >
    > <p>If you need to framglubble the zartbox, then you should buy the
    > <span onclick="f(this)">red widget</span>.
    > Otherwise you can buy the <span click="f(this)">blue widget</span> and
    > save some money.</p>


    Thanks for your response, VK.

    I hear ya. I have specific reasons for doing it the other way. I'm
    trying to develop a definition system so someone can select text on a
    page and hit button to get a definition. Using the example above,
    they could select "widget" or "framglubble" or "money". But there are
    many words which have different meanings depending on context, so the
    definition system could be more accurate/useful if I could
    intelligently scan context.

    I'm intrigued about shifting the range to the left. I expect to be
    working with fairly fixed content (or at least indexable content that
    would be intelligently tied to the definition system). How would I do
    that?
     
    Dekortage, Feb 22, 2007
    #3
  4. Dekortage

    Dekortage Guest

    Okay. I have a really rough, unoptimized version of what I want. The
    IE part is pretty simple, since it can move the selection boundary
    range around. The Mozilla part is a bit more of a hack: I get the
    full text of the node that the selection resides in, then based on the
    selection offset within the node, I chop up the text around it to
    determine the words just before and after the selected word. It
    doesn't work quite perfectly, but it's close. It doesn't work with
    Safari but I've tested it succesfully with Firefox (Mac) and IE 6
    (Windows). (Safari has some weird text range issues...?!?)

    Below is the code for an entire HTML page. Hopefully the word wrap
    won't kill it. I freely admit it is an ugly, unoptimized hack thrown
    together as a proof of concept, so you're welcome to clean it up, fix
    bugs, add features, etc.




    <html>
    <head>
    <title>Framglubble the Zartbox: getting selection context via
    JavaScript</title>
    <script language="javascript">

    // Original author: Dekortage @ a server called Gmail.com
    // You're free to copy this but leave the "Original author" line
    intact.
    //
    // This deliberately returns a "null" value if it determines that the
    previous
    // or next word is separated from the selected word by a comma or
    period.

    // determine browsers
    var isIE = document.all;
    var isN6 = document.getElementById && !document.all;
    var isN4 = document.layers;
    var detect = navigator.userAgent.toLowerCase();
    var isSafari = ( detect.indexOf("safari") > 0 );

    function trim(x) { return x.replace(/^\s*|\s*$/g,''); }

    function moreInfo() {
    if (!isIE) {
    var t = window.getSelection(); // selected text
    tx = t+"";
    preWord = null;
    postWord = null;

    if (!isSafari) { // Safari does not work with this

    origNode = t.anchorNode;
    orig = origNode.textContent + "";

    // get previous word
    preTxt = orig.slice(0,t.anchorOffset);
    preArray = preTxt.split(" ");
    preCount = preArray.length;
    while ((preWord == null) && (preCount >= 0)) {
    preCount -= 1;
    if ((preArray[preCount] != null) && (preArray[preCount] != "") &&
    (preArray[preCount] != " ")) {
    preWord = preArray[preCount];
    if ((preWord.charAt(preWord.length-1) == ",")) preWord = null;
    }
    }

    // get next word
    postTxt = orig.slice((t.anchorOffset + tx.length + 1));
    postArray = postTxt.split(" ");
    if ((postArray[0] != ".") && (postArray[0] != ",") &&
    (postArray[0] != "--") && (postArray[0] != "") &&
    (postArray[0] != " ")) { // if not end of sentence
    postWord = postArray[0];
    }

    }

    showWords(tx,preWord,postWord);

    } else if (document.selection && document.selection.createRange) {
    var t = document.selection.createRange(); // selected text
    if ((document.selection.type == 'Text') && (t.text > '')) {

    tx = trim(t.text);

    t.moveStart("word",-1); // not sure why t.move() alone wouldn't work
    t.moveEnd("word",-1);
    preWord = trim(t.text);
    if ((preWord == ",") || (preWord == ".")) {
    preWord = null;
    }

    t.moveEnd("word",2);
    t.moveStart("word",2);
    postWord = trim(t.text);
    if ((postWord == ",") || (postWord == ".")) {
    postWord = null;
    }

    // need to fix this to work with hyphenated words

    document.selection.empty();
    showWords(tx,preWord,postWord);
    }
    }
    }

    function showWords(t,a,z) { window.alert("Sequence: "+a+","+t
    +","+z); }

    if (isIE) document.ondblclick=moreInfo;

    </script>
    </head>
    <body ondblclick="if (!isIE) moreInfo()" style="font-size: 24px;
    margin: 24px;">
    <p>If you need to framglubble the zartbox, then you should buy the red
    widget. Otherwise you can buy the blue widget and save some money.</p>
    <p>(double-click on a word to see its context)</p>
    </body>
    </html>
     
    Dekortage, Feb 23, 2007
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Simon Harvey
    Replies:
    4
    Views:
    571
    Jon A. Cruz
    Jul 22, 2003
  2. Doug Estep
    Replies:
    4
    Views:
    751
    Oliver Bonten
    Feb 2, 2004
  3. Piet
    Replies:
    1
    Views:
    604
  4. gf
    Replies:
    0
    Views:
    92
  5. Antonio Gulli

    Extracting all img tag and surrounding text

    Antonio Gulli, Aug 7, 2004, in forum: Perl Misc
    Replies:
    0
    Views:
    127
    Antonio Gulli
    Aug 7, 2004
Loading...

Share This Page