1

I have a function that I would like to apply to different elements - or rather, different selectors creating different contexts. How can I modify the below function to use $('this'), instead of specifying the $('#themes') selector inside the getClass function?

The code:

$('#themes').change(function(e) {
  getClass(this, e); 
});

function getClass() {
  var classToAdd = $('#themes').find('option[value]:selected').map(function() {
    return this.value;
  }).get().join(' ');
  var allClassess = $('#themes').find('option[value]').map(function() {
    return this.value ? this.value : null;
  }).get().join(' ');
  $('#result').removeClass(allClassess).addClass(classToAdd);
}

See fiddle here.

1
  • In event listeners, this points to the current element the event is fired for, so you shouldn't re-select the element by a selector, use this instead. Commented Sep 6, 2016 at 20:02

4 Answers 4

1

The event has a currentTarget property that's exactly what you're looking for, and no need to pass this to it... in fact, just reconfigure the binding like this:

$('#themes').on('change', getClass);

function getClass (event) {
  var themes = $(event.currentTarget);
  var classToAdd = themes.find('option[value]:selected').map(function() {
    return this.value;
  }).get().join(' ');

  var allClassess = themes.find('option[value]').map(function() {
    return this.value ? this.value : null;
  }).get().join(' ');

  $('#result').removeClass(allClassess).addClass(classToAdd);
}
Sign up to request clarification or add additional context in comments.

2 Comments

So simple. Thanks a lot.
No problem. Just as a tip, jQuery's binding behavior is to always pass the event like this. Generally speaking, if you need more data than the event itself you probably have an opportunity to make the binding more generic somewhere.
1

the this operator has to do with scoping and what the current object is you are working on. If no object is currently selected then this will reference document, also known as the entire webpage. You could assign a new variable to the passed selector, that is a fairly easy way to accomplish what you are doing:

('#themes').change(function(event) {
  getClass(this, event);
});

function getClass(elem, e) { //if you pass args into a func, you need to declare them in the prototype
  //elem now represents whatever object you passed it (in this case 'this')
  var classToAdd = elem.find('option[value]:selected').map(function() {
    return this.value;
  }).get().join(' ');
  var allClassess = elem.find('option[value]').map(function() {
    return this.value ? this.value : null;
  }).get().join(' ');
  $('#result').removeClass(allClassess).addClass(classToAdd);
}

The other option is to use a method or jQuery plugin, but that syntax is a little bit more to grapple with than this function. Understand how this function is taking in the object as a variable before moving forward with methods and plugins.

I hope this helps!

1 Comment

Thanks for the explanation.
0

Use $(this) instead of this.
That way you don't have to define the same jQuery-selector.

Comments

0

It is important to understand the distinction between $(this) and this

$(this) - is a jQuery object containing this, so you would use $(this) whenever you want to run any jQuery functions

this - is a Javascript object, so any Javascript functions you want to use, you should use it on this.

Moreover, when using this, what it is, is dependent upon how the function is called. You shouldn't need to pass this and e to your getClass function. A simple $('#themes').change(getClass); will execute that function when #themes changes, and your this keyword in your getClass function will be the select object that is #themes while $(this) will be your jQuery object that contains this.

So instead, you can just use $(this).find(':selected') and you should be good. However, keep in mind, your this keyword inside of your map function refers to the object that you are running the map function on (aka the $(this).find(':selected'))

Comments

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.