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 Answers 3
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]();
});
});
7 Comments
this?document.ready it's not attached to window, but document, and can't be called with window[function_name]window.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.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.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
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.
window.