-1

I am trying to make it so when you hover over a dog's photo, you can hear his bark. I figured out how to do it manually, but now I am trying to automate it in a loop so the code stays clean.

I am giving the image and sound corresponding ids so that I can create a loop that adds a number to the end of 'image' and 'sound'. That way I can say on #image1.mouseenter play #sound1, and on #image2.mouseenter play #sound2. If that makes sesne

here is the jsfiddle I created. and here is the script i wrote:

var i;
for (i = 1; i<=3; i++){
  var barking = $("#sound"+i)[0];
  $("#image"+i).mouseenter(function(){
    barking.play();});
  $("#image"+i).mouseleave(function(){
    barking.pause();});
}
Louys Patrice Bessette
  • 33,375
  • 6
  • 36
  • 64
KaZ
  • 11
  • 2

2 Answers2

1

A better way to do this would be to have data attributes on your tags, specifying what sound to play. Then, have a single simple handler.

In your HTML:

<div class="dogs">
  <img src="dog.jpg" data-hover-sound="dog.mp3" />
</div>

Then, in your JavaScript:

$('.dogs').on('mouseenter', '[data-hover-sound]', function () {
  var audio = new Audio($(this).attr('data-hover-sound'));
  audio.play();
});

Untested, but something like that should work. Basically, you add a single handler on the container of .dogs, and filter for only tags that have a hover sound.

Alternatively, you could just use $('[data-hover-sound]'), but if you have a lot of these, this will create a lot of events to watch for. It's a tradeoff either way, because having an event handler on the parent element means that it's going to fire needlessly if there are a lot of other elements that don't have sounds.

Also, when you have this working, look into throttle and/or debounce.

Brad
  • 159,648
  • 54
  • 349
  • 530
  • thank you! I will try this. I am new to this so I am not sure I understand it, but I'm assuming this will work with different sounds for different dogs? – KaZ Apr 23 '17 at 00:09
  • @KaZ The whole point is that you keep your dog sound reference in your markup (just like you do with your dog images). The JavaScript doesn't have to know or care what those URLs are. Yes, it will work with whatever sounds you want. The URL comes from the markup. – Brad Apr 23 '17 at 00:10
  • amazing! thank you for teaching a stranger, i hope to repay the favor once I get better. – KaZ Apr 23 '17 at 00:16
0

You need a closure so the i variable have the correct value when passed to the event handler

Below is one way, and here is a few more: JavaScript closure inside loops

for (var i = 1; i <= 3; i++) {
  (function(j) {
    $("#image" + j).mouseenter(function() {
      $("#sound" + j)[0].play();
    });
    $("#image" + j).mouseleave(function() {
      $("#sound" + j)[0].pause();
    });
  })(i);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id="image1" src="https://www.rocketdogrescue.org/wp-content/uploads/2013/09/DSC_0718.png" width="400px">
<img id="image2" src="https://www.rocketdogrescue.org/wp-content/uploads/2013/09/lightening.jpg" width="400px">
<img id="image3" src="https://www.rocketdogrescue.org/wp-content/uploads/2013/09/pet-food-express.jpg" width="400px">

<audio id="sound1" preload="auto" loop="loop">
  <source src="http://soundbible.com/mp3/Dogs Barking-SoundBible.com-625577590.mp3">
</audio>

<audio id="sound2" preload="auto" loop="loop">
  <source src="http://soundbible.com/mp3/Dog Woof-SoundBible.com-457935112.mp3">
</audio>

<audio id="sound3" preload="auto" loop="loop">
  <source src="http://soundbible.com/mp3/dog-howling-yapping-daniel_simon.mp3">
</audio>
Community
  • 1
  • 1
Asons
  • 84,923
  • 12
  • 110
  • 165
  • you did it!!!!! Thank you so much!! It's working here: [link](http://urbanmistletoe.com/test/index_test.html) – KaZ Apr 23 '17 at 00:12
  • @KaZ Thanks, though I still think [_Brad's answer_](http://stackoverflow.com/a/43565954/2827823) is worth consider, as it give you simpler and more maintainable code – Asons Apr 23 '17 at 00:14