GetRangeAt Throws An Error When Using EventListener

I have a script that gets the user’s text selection using windows.getSelection() and the range can be had using windows.getSelection().getRangeAt(0). When I use the onclick attribute of a button element to call the function just described, I had no issue. However, if I use the following code to ensure the page had loaded

document.addEventListener("DOMContentLoaded", function(event){}

and then define the click evenlistener inside of it, getRangeAt(0) throws an error.
Please see my script here.

Having a look, and one thing for starters

document.addEventListener("DOMContentLoaded", function(event){ 
    let btn = document.getElementById("test"); 
    let selection; 
    let range;

    if(window.getSelection){
          selection = window.getSelection(); 
          range = selection.getRangeAt(0);
    }

    btn.addEventListener("click", Test(range));
        
});
 
function Test (rangegObj){
   console.log(rangeObj);          
}

This is going to invoke Test, regardless of clicking

btn.addEventListener("click", Test(range));

One fix is to wrap the callback in a function

btn.addEventListener('click', function(event) { test(range) })

Or partial application with bind is another possibility

btn.addEventListener('click', test.bind(null, range))

Note have also changed ‘Test’ to lowercase. A capital first letter tends to be used to indicate that is is a constructor function.

I know it doesn’t answer your main question.

Oh and a typo 'rangegObj’

function Test (rangegObj){
   console.log(rangeObj);          
}

Looking at MDN
The zero-based index of the range to return. A negative number or a number greater than or equal to Selection.rangeCount will result in an error.

So if rangeCount is zero, it is equal to selection.getRangeAt(0)

1 Like

Ok a bit of a re-write. Edit: I have just realised with ‘rangeObj’, you wanted to output the object.

This is heading in the right direction though

function test (range) {
  console.log(range)
}

document.addEventListener('DOMContentLoaded', function (event) {
  function getSelection () {
    if (window.getSelection) {
      const selection = window.getSelection()

      if (selection.rangeCount > 0) {
        const range = selection.getRangeAt(0) // Object
        return range.endOffset - range.startOffset // number of chars selected
      }
      return 0
    }
  }

  const btn = document.getElementById('test')
  btn.addEventListener('click', function (e) { test(getSelection()) })
})
1 Like

I’ve wrapped the callback function in an anonymous function and I’m still getting an error. This time around the however, the exception is a null exception on the eventListener. Please see my modified script here

This is your null error, ‘test’? or ‘showSelection’?

<button id="showSelection">Get Selection</button>
let btn = document.getElementById("test");

Your script just isn’t going to work properly though.

document.addEventListener("DOMContentLoaded", function(event){ 
    let btn = document.getElementById("test");      
    let range;

    // needs to be wrapped in a function
    if(window.getSelection){
       const selection = window.getSelection(); 
       if(selection.rangeCount > 0){
          // needs to be returned
          range = selection.getRangeAt(0);
       }
    }
    // needs to call function and pass the returned value to test
    btn.addEventListener("click", function(){test(range);});
        
});

Your script will run once and pass the same range value ‘undefined’ to test on every successive click.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.