Loading sounds asynch how to refer to loaded file with "this"

Hi, I am creating a website with a lot of sounds that are played on different events. I load the asynch which works so far when I use the following code. But since I have a lot more sounds I would like to generalize this to avoid redundant code . I tried to create a function which refers to the sound like shown in the third. The Problem is that "this" does not seem to work. Also what would be best practices to do something like this. Any help appreciated!

sndLinkOver = loadSound("/assets/audio/blipOver.mp3", function(){
    for (var i = 0; i < sonicLinks.length; i++){
      sonicLinks[i].mouseOver(function(){
        sndLinkOver.setVolume(0.1);
        sndLinkOver.play();
      });
    }
  });

  sndLinkClick = loadSound("/assets/audio/blipClick.mp3", function(){
    for (var i = 0; i < sonicLinks.length; i++){
      sonicLinks[i].mouseClicked(function(){
        sndLinkClick.setVolume(0.1);
        sndLinkClick.play();
      });
    }
  });

generalized

function soundready(){
   // call bind sound to dom element event
 }

function bindsound( domelement ){
    // bind this to dom element
}

Answers

  • edited December 2017

    I'm confused, if you're loading 1 p5.SoundFile, why does its callback iterate over some mysterious sonicLinks[] array? What is its datatype btW? :-/

    In general, when posting an excerpt of a code, also include all the parts where variables are declared & initialized. (:|

    sonicLinks[] is much probably an array of p5.Element objects.
    However, a p5.Element instance can be a wrapper to all kinds of DOM elements. :-@

  • Thanks for your reply. The mysterious array is the array of DOM Elements I attach the sound to. In this case a to play sound on "clicked" and on "mouseover",which I selected with selectAll('a'). Then iterate through them and attach the function to each to play the sound. This is highly inefficient, I guess, so I want to generalize it, but I don´t know which is the correct way to achieve this. Also in the soundready() callback I can not usethis to refer to the loaded sound, e.g. this.play(); throws an error. I thought this would refer to the object that creates the callback. A rough high level idea how this is usually solved would be great.

  • edited December 2017

    The mysterious array is the array of DOM Elements I attach the sound to.

    Yea, I already know that, as I had stated at the end of my 1st answer! [-(

    The matter is that there are lotsa diff. DOM elements:
    https://Developer.Mozilla.org/en-US/docs/Web/API

    Notice that a p5.Element is merely a wrapper for a HTMLElement. L-)

    Then iterate through them and attach the function to each to play the sound.

    That's why I'm puzzled! Why would you need to link the same 1 sound for the whole array? :-/

    Also in the soundready() callback...

    Both posted callbacks are empty w/ just comments inside them! ~:>
    BtW, regular functions & variables should follow the lowerCaseNamingConvention.
    So they should be named respectively as: soundReady() & bindSound(). O:-)

    I thought this would refer to the object that creates the callback.

    Unless forced otherwise, current this inside a function body refers to the object which had invoked it. :-B

  • edited December 2017

    Some tips: place a console.log(this); inside your callbacks for debugging, so you can find out which object datatype had invoked it. *-:)

    Moreover, the callback itself may receive an event argument. L-)
    So it's a good idea to check that out as well: B-)

    someP5ElementObject.mouseOver(function (evt) { // callback
      console.log(this); // invoker object
      console.log(evt);  // passed event object
    });
    
  • edited December 2017

    Many thanks.

    That's why I'm puzzled! Why would you need to link the same 1 sound for the whole array?

    All links should trigger the same sound. I guess there is a more efficient way which I didn´t figure out yet. One reason for my question ;-)

    Both posted callbacks are empty w/ just comments inside them!

    I just wanted describe the basic idea of what I want to achieve and where I want to figure out, how to fill these callbacks.

    Unless forced otherwise, current this inside a function body refers to the object which had invoked it.

    I hoped that it works a little like in Daniel Shiffmans Video at 7:30 But I guess I misunderstand it. I´ll try your advice for debugging and I guess I need to rethink my idea comletely

  • edited December 2017 Answer ✓

    There are 2 ways to permanently bind a function's this to always be the same object reference: :ar!

    Classical way is via Function::bind() method, which returns a cloned bound function:
    https://Developer.Mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

    But the modern 1 is to use a fat arrow function (lambda) in place of a regular function: B-)
    https://Developer.Mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

    In this modality, its permanent bound this is determined at the moment of its creation.
    And that final this is the current 1 being used by its most immediate enclosing function. :-B

    So instead of function (evt) {}, go w/ evt => {}. :-bd

  • Many thanks!

Sign In or Register to comment.