Reputation: 10254
I'm struggling with closure scope in a JavaScrit function. The function below should create three swatches with different images (which works), then when these are clicked, should switch the stylesheet.
The problem is that the same object is passed to the switchTheme
function even though stepping through shows the theme
variable in the first function does change.
var switcherConfig = {
themes:
{
'Orangeness': {
folder: 'ui-lightness'
},
'Red Matter': {
folder: 'blitzer'
},
'Flubber': {
folder: 'south-street'
}
}
}
function createThemeSwitcher(placeholderSelector) {
for (var themeName in switcherConfig.themes) {
var theme = switcherConfig.themes[themeName];
var anchor = $('<a/>')
//.text(theme.title)
.attr('title', theme.title)
.attr('href', '#')
.on('click', function () { switchTheme(theme); })
// append to DOM etc
}
}
function switchTheme(theme) {
var themeDirectory = switcherConfig.baseDirectory + '/' + theme.folder + '/';
// 'theme' variable is always the last in my 'themes' config object
}
Upvotes: 0
Views: 93
Reputation: 12815
Instead of making closure you can use .data
like below (just an alternative):
var switcherConfig = {
themes:
{
'Orangeness': {
title:"Orangeness",
folder: 'ui-lightness'
},
'Red Matter': {
title:'Red Matter',
folder: 'blitzer'
},
'Flubber': {
title:'Flubber',
folder: 'south-street'
}
}
}
function createThemeSwitcher(placeholderSelector) {
for (var themeName in switcherConfig.themes) {
var theme = switcherConfig.themes[themeName];
var anchor = $('<a/>')
.data("theme",theme)
.attr('title', theme.title)
.attr('href', '#')
.html(theme.title)
.on('click', function () { switchTheme($(this).data("theme")); })
$("body").append(anchor);
}
}
function switchTheme(theme) {
alert(theme.title)
}
Upvotes: 0
Reputation: 885
Move
var theme = switcherConfig.themes[themeName];
to click function
function createThemeSwitcher(placeholderSelector) {
for (var themeName in switcherConfig.themes) {
var anchor = $('<a/>')
//.text(theme.title)
.attr('title', theme.title)
.attr('href', '#')
.on('click', function () {
var theme = switcherConfig.themes[themeName];
switchTheme(theme);
})
// append to DOM etc
}
}
Upvotes: 0
Reputation: 522250
The value used by switchTheme(theme)
will be the state that theme
is in when the function is called, the value is not bound at the moment you create that anonymous callback. Use a closure to bind that particular value:
.on('click', (function (t) {
return function () { switchTheme(t); };
})(theme))
Upvotes: 3