Как вызвать функцию с правильным аргументом в объекте jQuery-resizable, который создается в цикле?
У меня есть пара объектов с изменяемыми размерами, и я хотел бы вызвать функцию 'changeS()', когда я прекращаю изменять размер объекта.
Функция changeS () должна принимать в качестве первого аргумента имя объекта, для которого она вызывается.
Я имею в виду:
когда я прекращаю изменять размер объекта "#resizable0", тогда должен называться changeS(#resizable0,new_size - old_size),
когда я прекращаю изменять размер объекта "#resizable1", тогда должен вызываться changeS(#resizable1,new_size - old_size) и т. д.
Когда я просто устанавливаю в коде этот метод для каждого имеющегося у меня объекта, все в порядке, но я бы хотел сделать это в цикле for(), потому что объектов будет намного больше, и тогда у меня возникнет проблема:
var old_size=0;
var new_size=0;
var x,i;
for(i=0; i<5; i++){
x = "#resizable"+i;
var $res = $(x);
$res.resizable({
grid: 22, minHeight:22, handles: 's',
start: function(event,ui) {
old_size = ui.originalSize.height;
},
stop: function(event,ui) {
new_size = ui.size.height;
if(new_size!=old_size)
changeS($res,new_size - old_size);
}
});
}
Я не знаю, как правильно передать имя объекта в качестве аргумента функции.
Когда функция changeS () выполняется, она всегда вызывается с тем же именем - именем последнего созданного объекта (в данном случае "#resizable5").
Мой вопрос:
Как сделать так, чтобы для каждого объекта была вызвана функция changeS () с соответствующим аргументом (именем этого объекта)?
Спасибо, попКонр
1 ответ
Функции, которые вы создаете в цикле, являются замыканиями. Они сохраняют постоянную ссылку на переменные, которые они закрывают, а не копию значения на момент определения функции. И поэтому все они видят последнее значение, которое вы назначаете $res
, а не значение во время "их" цикла.
Обычный способ решить эту проблему - использовать фабричную функцию, что-то вроде этого:
var x,i;
for(i=0; i<5; i++){
x = "#resizable"+i;
var $res = $(x);
makeResizeable($res);
}
function makeResizeable($thisres) {
var old_size = 0,
new_size = 0;
$thisres.resizable({
grid: 22, minHeight:22, handles: 's',
start: function(event,ui) {
old_size = ui.originalSize.height;
},
stop: function(event,ui) {
new_size = ui.size.height;
if(new_size!=old_size)
changeS($thisres,new_size - old_size);
}
});
}
Обратите внимание, как мы сейчас используем $thisres
аргумент передается в фабричную функцию makeResizeable
, скорее, чем $res
, поскольку аргумент заполняется в функции, которые мы создаем в makeResizeable
не изменился Также обратите внимание, что я переехал new_size
а также old_size
в эту фабричную функцию, а также. Обработчики событий закроют эти данные, и каждая пара получит свои собственные копии этих переменных.
Замыкания не сложны, но есть несколько фундаментальных вещей, которые люди обычно неправильно понимают. Однако, как только вы их опустите, вы будете в хорошей форме.