-1

Upon document.ready, I am defining several functions, then attempting to call them using window[variable], where the variable is the name of the function. I came upon this soution here: Calling a JavaScript function named in a variable. Here is my code:

jQuery(document).ready(function() {


function playSlide0(){
    player0.playVideo();
    console.log('slide0 fired');
}
function playSlide1(){
    player1.playVideo();
    console.log('slide1 fired');
}
function playSlide2(){
    player2.playVideo();
    console.log('slide2 fired');
}

swiper.on('slideChangeStart', function () {


    var currentSlide = swiper.activeIndex;
    var currentVid = document.getElementById('video'+currentSlide);
    var currentVidId = 'slide_'+currentSlide;
    var playSlideFunction = 'playSlide'+currentSlide;

    window[playSlideFunction]();

});

});

Instead of calling my function, I am getting the error 'window[playSlideFunction] is not a function'. Any thoughts? Thank you.

3
  • You've defined the functions in the scope of the anonymous function, they are not defined globally, i.e. they are not properties of window. Commented Sep 6, 2017 at 18:33
  • While this is possible in theory, you should unlearn everything about this immediately. Please add the relevant HTML and we can show you how to write this properly. Commented Sep 6, 2017 at 18:34
  • Possible duplicate of Javascript - Variable in function name, possible? Commented Sep 6, 2017 at 18:41

3 Answers 3

1

Inside document.ready the value of this is not the window, but the document

jQuery(document).ready(function() {
  console.log(document === this); // true
  console.log(window === this); // false
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Which is why window[playSlideFunction] is undefined.
The proper way to handle this, would be with an object you control, and not the document or window

jQuery(document).ready(function() {
  var funcs = {
    playSlide0: function() {
      player0.playVideo();
      console.log('slide0 fired');
    },
    playSlide1: function() {
      player1.playVideo();
      console.log('slide1 fired');
    },
    playSlide2: function() {
      player2.playVideo();
      console.log('slide2 fired');
    }
  }

  swiper.on('slideChangeStart', function() {
    var currentSlide = swiper.activeIndex;
    var currentVid = document.getElementById('video' + currentSlide);
    var currentVidId = 'slide_' + currentSlide;
    var playSlideFunction = 'playSlide' + currentSlide;

    funcs[playSlideFunction]();
  });
});
Sign up to request clarification or add additional context in comments.

7 Comments

What has this to do with this?
@Teemu - If you define a function inside document.ready it's not attached to window, but document, and can't be called with window[function_name]
?? They are defined in the scope of that anonymous function, that's why they are not properties of window.
When something is defined inside document.ready it's not global, and can't be accessed on the window, and that is the problem the OP is having, and thus the answer to the question.
Yes, I know that, but I can't see how this is involved in the case, since we're talking about scopes ..? And functions defined in document.ready's argument are not assigned to the document, assigning variables as properties is a feature of the globally declared variables/functions only. Not my downvote, though.
|
0

You could wrap the function in an object

var fn = {
    playSlide0: function () {
        player0.playVideo();
        console.log('slide0 fired');
    },
    playSlide1: function () {
        player1.playVideo();
        console.log('slide1 fired');
    },
    playSlide2: function () {
        player2.playVideo();
        console.log('slide2 fired');
    }
}

and call it with the name

fn['playSlide' + currentSlide]();

Comments

0

Generally speaking, this is not a good way to go about this. It's hard to give a really specific answer because we don't have the rest of your page, but in general you are better off with a single function that takes a parameter telling it which thing to operate on. This is basic principle called DRY - Do Not Repeat Yourself.

You might do something like this:

Say you have a bunch of video elements - you can grab them all with:

var players = document.querySelectorAll('video');

Now players is a list of players -- you can reference each player in order with:

players[0] //etc

Now you only need one function regardless of how many players you have:

function playSlide(index){
  players[index].playVideo();
  console.log('player ' + index  + 'fired');
}

And you can use it with something like this:

var currentSlide = swiper.activeIndex
playSlide(currentSlide)

Now if you add more players, you don't need to change your code and if you want to change something in the code, you only need to change it in one place.

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.