3

I have the following html file :

<div id="tour">
 <h2>Paris, France Tour</h2>
 <p>$2,499 for 7 Nights</p>
 <button>See photos from our last tour</button>
 <ul class="photos">
   <li>
   <img src="/assets/photos/paris1.jpg">
   <span>Arc de Triomphe</span>
   </li>
   <li>
  <img src="/assets/photos/paris2.jpg">
  <span>The Eiffel Tower</span>
  </li>
  <li>
  <img src="/assets/photos/paris3.jpg">
  <span>Notre Dame de Paris</span>
  </li>
 </ul>
</div>

This is my jQuery code :

function showPhotos()
{
    $(this).find("span").slideToggle();
}

$(document).ready(function() { 
    $("#tour").on("click", "button", function() { 
        $(".photos").slideToggle();
    });

    $(".photos").on("mouseenter", "li", showPhotos);
    $('.photos').on("mouseleave", "li", showPhotos);
});

This code works, it shows the span when mouse enters the img element . But when I try to do the same thing like so :

function showPhotos()
{
    $(this).find("span").slideToggle();
}

$(document).ready(function() { 
    $("#tour").on("click", "button", function() { 
        $(".photos").slideToggle();
    });
    $(".photos").on("mouseenter", "li", function() {
        showPhotos();
    });
    $('.photos').on("mouseleave", "li", function() {
        showPhotos();
    });
});

It doesn't work . With my limited knowledge, both codes seem to be doing the same thing. Please help me, How is the second code different from the first ?

1
  • 1
    try : $(".photos").on("mouseenter", "li", function() { showPhotos(this); }); and function showPhotos(sender) { $(sender).find("span").slideToggle(); } Commented Jun 13, 2013 at 7:08

4 Answers 4

10

The second example doesn't have the this context in the showPhotos() function, you can pass the element as an argument:

function showPhotos(that)
{
    $(that).find("span").slideToggle();
}

$(document).ready(function() { 
  $("#tour").on("click", "button", function() { 
    $(".photos").slideToggle();
  });
  $(".photos").on("mouseenter", "li", function() {
      showPhotos(this);
  });
  $('.photos').on("mouseleave", "li", function() {
      showPhotos(this);
  });
});

Unlrelated to the question but a minor improvement would be to chain the mouseleave event, instead of re-selecting .photos again.

  $(".photos").on("mouseenter", "li", function() {
      showPhotos(this);
  }).on("mouseleave", "li", function() {
      showPhotos(this);
  });
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks a lot . So , in the first example , 'this' context is available. I'm a little confused ,Can you explain how it is available for the 1st example ?
Yes, in the first example, when you directly assign showPhotos() as the click handler, the function's this will be set to the value of the element that was clicked. That's because the browser passes the element as this into the root click handler. In the second example, the root click handler is the anonymous function and so showPhotos() doesn't get the this context, unless you pass it in like in the example. In the first example, showPhotos() is root click handler and so it gets the context.
Ah,now I think I understand. Thank you for your patience.
2

When you call the function showPhotos from within the anonymous function, 'this' does not refer to the element handling the event. So you'll either have to use the solution that MrCode has given or you can also use something like this:

$('.photos').on("mouseleave", "li", function() {
    showPhotos.apply(this,arguments);
});

2 Comments

Just a note: for complete equality between both it should be return showPhotos.apply(this, arguments); (this way the event object is also passed as argument, and returning false from the callback would also work)
Thanks . I didn't know about the apply method before .
0
$(document).ready(function() { 
   $("#tour").on("click", "button", function() { 
        $(".photos").slideToggle();
   });
   $(".photos").on("mouseenter", "li", showPhotos);
   $('.photos').on("mouseleave", "li", showPhotos);
});

Try this.

1 Comment

That the first example of the question. The question is why the firstexample works and the second one not.
0

In the second case instead of calling the function showPhotos(); inside

  $(".photos").on("mouseenter", "li", function() {
  }); 

writing the actual code of the function i,e

  $(this).find("span").slideToggle(); 

will work.

2 Comments

Please use the available possibilities to formate your answers. e.g surrounding code with ` or write it in a new line with indenting. This will make it easier to read and understand your answer.
Ok, So you mean writing the actual code of function within strings as the third argument of "on" will work ?

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.