React onSelect event not working

30,778

Solution 1

Check out https://github.com/ydeshayes/react-highlight

To get the effect you want with a regular DOM element involves a lot of delicate code handling mouse events.

You could cheat and use an <input> or <textarea> instead and style it to look like regular text. Then onSelect should just work.

Solution 2

React has this option. In my opinion You have to bind function to this key word:

onSelect={this.selectedText.bind(this)}

So, Your code will look like this:

import React, { Component } from 'react';

class ReadModule extends Component {
  selectedText() {
      console.log("You selected some text");
  }

  render() {
    return (
          <div id="read-module" className="row">
            <p>Reading:</p>
            <span onSelect={this.selectedText.bind(this)}>{this.props.reading}</span>
          </div>
    );
  }
}

export default ReadModule;
Share:
30,778
NewScientists
Author by

NewScientists

Updated on July 09, 2022

Comments

  • NewScientists
    NewScientists almost 2 years

    Does React have an event handler for the onSelect statement? i.e. if a user selects some text with their mouse within a paragraph (highlighted text) trigger an event that extracts the selected text.

    import React, { Component } from 'react';
    
    class ReadModule extends Component {
      selectedText() {
          console.log("You selected some text");
      }
    
      render() {
        return (
              <div id="read-module" className="row">
                <p>Reading:</p>
                <span onSelect={this.selectedText}>{this.props.reading}</span>
              </div>
        );
      }
    }
    
    export default ReadModule;
    

    The above doesn't work. If there is an approach that is better i.e. extracting a string please do let me know! Once i get a simple

    on highlight trigger function

    Concept working I can take it from there. Thanks in advance

    Solution:

    import React, { Component } from 'react';
    
    class ReadModule extends Component {
      selectedText() {
            var txt = "";
            if (window.getSelection) {
                    txt = window.getSelection();
            }
            else if (document.getSelection) {
                txt = document.getSelection();
            } else if (document.selection) {
                txt = document.selection.createRange().text;
            }
    
            alert("Selected text is " + txt);
      }
    
      render() {
        return (
              <div id="read-module" className="row">
                <p>Reading:</p>
                <span onMouseUp={this.selectedText}>{this.props.reading}</span>
              </div>
        );
      }
    }
    
    export default ReadModule;
    
  • NewScientists
    NewScientists about 7 years
    Thanks, this works. i did selectedText(e) { console.log(e) }. This returns a proxy. Now i'm not sure what this is, but is this right approach to extracting the selected value?
  • NewScientists
    NewScientists about 7 years
    Is cheating with an input or textarea acceptable for an application that will go into production, kind of hesitant if it exposes the application to vulnerabilities. Whats your take?
  • pscl
    pscl about 7 years
    Well you'd want to give the input a readonly attribute. As long as your input is not wired up to anything I don't see a cause for concern. Of course if you could make it work with the <span> then its even better.
  • NewScientists
    NewScientists about 7 years
    Uncaught Error: input is a void element tag and must neither have children nor use dangerouslySetInnerHTML
  • pscl
    pscl about 7 years
    <input> takes its body text like this <input value="abcdefg" />. <textarea> is probably an easier fit for you.
  • Rebecca
    Rebecca over 6 years
    hey! just so you know, you don't need to use bind if you declare the selectedText function like so: selectedText = () => { }
  • Anselmo Park
    Anselmo Park almost 3 years
    Does this really work? In my case, <span> or <div> tag doesn't fire onSelect event. It is fired such as <textarea> tag for me.