0

Here is an example that works fine

$(".multi-select").change(function() {
  $(this).parent().parent().addClass("glow");
} );
.glow {
    box-shadow: inset 0px 10px 10px 3px rgba(255, 0, 0, 1) !important;
    box-sizing: border-box;
    display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<div class="slides-containter">
  <div class="slide-container" id="slide_34">
    <div class="zoom-container">
      <span class="zoom-caption">
        <h3>
          <input class="multi-select" id="slide_select_34" name="ids[]" type="checkbox" value="34" />
        </h3>
      </span>
      <img alt="4c730521b21310758a4809d7b56feec5" src="http://foobar.tuxpartei.ch/foobar.png" />
    </div>
  </div>

But for some reason it doesn't work if I try to split it to some callback function like

function glow_it() {
 $(this).parent().parent().addClass("glow");
};


$(".multi-select").change(function() {
 glow_it();   
}
.glow {
    box-shadow: inset 0px 10px 10px 3px rgba(255, 0, 0, 1) !important;
    box-sizing: border-box;
    display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<div class="slides-containter">
  <div class="slide-container" id="slide_34">
    <div class="zoom-container">
      <span class="zoom-caption">
        <h3>
          <input class="multi-select" id="slide_select_34" name="ids[]" type="checkbox" value="34" />
        </h3>
      </span>
      <img alt="4c730521b21310758a4809d7b56feec5" src="http://foobar.tuxpartei.ch/foobar.png" />
    </div>
  </div>

I suppose I should pass this somehow to it. How it should be done ?

Thank you in advance.

2
  • 3
    Include code in question please. Commented Jan 10, 2015 at 2:11
  • 1
    $(".multi-select").on('change', glow_it);
    – adeneo
    Commented Jan 10, 2015 at 2:14

5 Answers 5

4

That is because when you're calling the glow_it() function, the context of the selector is lost, i.e. $(this) is no longer referring to the element where the change event is fired, but it is referring to the window object instead, i.e. $(window). To resolve this, pass $(this) as a variable to the function:

function glow_it(t) {
    $(t).parent().parent().addClass("oxo");
};

$(".multi-select").change(function() {
    glow_it(this);   
});

p/s: You also have a syntax error, because you left out the closing parenthesis ) on the last line in your .change() event.

See proof-of-concept fiddle here: http://jsfiddle.net/teddyrised/h0euqvf0/7/


Update: Alternatively you can call the glow_it() function as a second parameter in .on('change', [handler]) so as to preserve the context, as suggested by @adeneo in his comment:

$(".multi-select").on('change', glow_it);

The explanation to why this works is quite well explained in the jQuery .on() documentation:

When jQuery calls a handler, the this keyword is a reference to the element where the event is being delivered; for directly bound events this is the element where the event was attached and for delegated events this is an element matching selector. (Note that this may not be equal to event.target if the event has bubbled from a descendant element.) To create a jQuery object from the element so that it can be used with jQuery methods, use $( this ).

See demo: http://jsfiddle.net/h0euqvf0/5/

1
  • Nice. And alternately, there's .apply.
    – SpYk3HH
    Commented Jan 10, 2015 at 7:09
1

Declare your $(this) in var and pass as parameter.

function glow_it(multiSelect ) {
     multiSelect.parent().parent().addClass("oxo");
    };


    $(".multi-select").change(function() {
    var multiSelect = $(this);
     glow_it(multiSelect );   
    )};
1

In addition to Terry's answer, you can also use .call() to define the value of this when calling a function.

function glow_it() {
    $(this).parent().parent().addClass("glow");
}

$(".multi-select").on('change', function () {
    glow_it.call($(this));   
});

Updated Example

Also, instead of using .parent().parent(), i'd suggest using .closest('h3'):

function glow_it() {
    $(this).closest('h3').addClass("glow");
}
1

Another option is to use jquery proxy method. It allows you to define a call context. In this particular case is a little useless since you may use glow_it as change handler but it may worth to present this option for some other scenario where this firs better

$(".multi-select").change(function() {
    $.proxy(glow_it, this)();
});
0
1

You can do either of the following :

Specify glow_it as a named handler (preferred)

$(".multi-select").change(glow_it);

Here, the event object is automatically passed to the named handler in the same way it would be passed to an anonymous handler.

Call glow_it from an anonymous handler in such a way that it is informed of this.

$(".multi-select").change(function(e) {
    glow_it.call(this, e);   
}

It's good to get into the habit of passing the event object e even if it's not used. One day you will be glad of it.

Not the answer you're looking for? Browse other questions tagged or ask your own question.