3

I have a textarea that I have a blur event attached to. I don't want the blur event to run if the user clicks on a specific span.dontClick on the page. However if the user clicks on anything other than the span.dontClick I do want the blur event to run. I have found a way to do this, but it looks awful, feels very hackey, and I'm guessing there is a better solution out there. Here's what I've come up with:

if (event.type === 'focusout') {
  if (
    typeof event.originalEvent !== 'undefined' &&
    typeof event.originalEvent.currentTarget !== 'undefined' &&
    typeof event.originalEvent.currentTarget.activeElement !== 'undefined' &&
    typeof event.originalEvent.currentTarget.activeElement.className !== 'undefined' &&
    event.originalEvent.currentTarget.activeElement.className === 'dontClick'
  ) {
    // abort the code for the blur event (in effect, do nothing)
  }
  else {
    // run code for when a user blurs by not clicking on span
  }

It should probably be noted that the event object is from a jQuery event handler. I'm not sure if it is different or the same as the native event objects.

It should also be noted that this fails silently for most browsers but I get a debug window in IE if I don't specify the 'undefined' state for each object all the way down the line...

If anyone has a more elegant solution I would really appreciate seeing it. Thanks!

1
  • This is one of the biggest reasons why I love CoffeeScript :) Commented Oct 31, 2012 at 21:20

1 Answer 1

7

You don't need comparisons to undefined. Just do a truthy test. Also the test for the className isn't needed. The === comparison will cover it.

 if (
    event.originalEvent &&
    event.originalEvent.currentTarget &&
    event.originalEvent.currentTarget.activeElement &&
    event.originalEvent.currentTarget.activeElement.className === 'dontClick'
  ) {

but then you're doing more work than needed anyway since jQuery gives you a reliable currentTarget.

 if (
    event.currentTarget.activeElement &&
    event.currentTarget.activeElement.className === 'dontClick'
  ) {

or if you're in a handler, just use this.

 if (this.activeElement && this.activeElement.className === 'dontClick') {
Sign up to request clarification or add additional context in comments.

4 Comments

I'm not seeing any activeElement object under event.currentTarget, plus, if I'm thinking clearly about this, the reason I'm checking event.originalEvent.currentTarget.activeElement.className is because I need to see if a user clicked on the span originally. If it existed, wouldn't event.currentTarget.activeElement refer to the textarea?
@jasonmerino: Yes, the correct property is document.activeElement, and it would refer to the textarea. I wasn't sure why you were checking it for the class of the span. You could put a handler on the span.dontClick, but by the time it fires, the blur will have already fired. Perhaps the only way would be to have the blur event code in a short setTimeout, then have a click event on the span.dontClick set some global variable that the blur event can check before it invokes its code.
Yeah, I could set a timer, but to me that feels even more hackey than my current solution... :S
@jasonmerino: Yeah, it's pretty hackey, but it's tough to get around the fact that events happen in a certain order.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.