Добавление в эвент значение переменной
Суть вопроса в следующем: можно ли как-то, при добавлении элементу эвента (через джс), передать в функцию непосредственно значение переменной, а не её название.
То есть у нас имеется следующее:
g.addEventListener("click", function () { faunaAdd(scale); });
g.onclick = function () { faunaAdd(scale); };
Вызов функции faunaAdd в которую надо передать значение scale, но проблема в том, что таким способом передаётся непосредственно само название переменной и в итоге при срабатывании эвента в функцию будет передано, по сути, ничего, ведь scale в эвенте не определён. Я долго пытался найти решение этой проблемы гугле, но то ли плохо искал, то ли ещё что, но не нашёл вообще ничего. Единственное до чего допёр сам, это сделать объявление так:
g.setAttribute("onclick", "faunaAdd(" + scale + ");");
Тогда да, передаётся именно значение и всё работает как надо, но выглядит это... Ужасно и неудобно. Собственно поэтому и возник вопрос, может кто знает как сделать подобное, но с нормальным объявлением. |
в корне неправильный подход.
во первых хорошим тоном считается не встраивать в html теги обработчики, а так чтобы вешать через setAttribute вижу впервые. напишите что хотите сделать, подскажем как будет правильно. |
Цитата:
А что надо... В целом, я уже выше всё описал, да и не важно куда эвент вешать, проблема актуальна на любом элементе будет. В общем, всё, что мне надо, это при добавлении эвента элементу, передать в него значение переменной, а не название переменной, дабы при срабатывании эвента в функцию (в моём случае) передавалось сразу готовое значение, а не пустое значение необъявленной переменной (в пределах эвента). Короче, если мы используем этот способ:
g.onclick = function () { faunaAdd(scale); };
то получаем следующий эвент:
function () { faunaAdd(scale); };
А если используем тот костыль, до которого я дошёл:
g.setAttribute("onclick", "faunaAdd(" + scale + ");");
то получаем на выходе следующее: ( scale = 0.3; )
function () { faunaAdd(0.3); };
И вот мне надо получить последнее, но нормальными путями, если это возможно, конечно же. П.с.: ещё уточню, что это новый элемент:
var g = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
"Хуяк-хуяк" решения:
g.scale = scale;
g.addEventListener("click", faunaAdd); //внутри faunaAdd использовать this.scale
g.addEventListener("click", faunaAdd.bind(this, scale)); //заодно и перепривяжем this
g.addEventListener("click", function(scale){
return function(){
faunaAdd(scale);
}
}(scale) ); //хардкор classic
...А как делать нормально - зависит от конкретной ситуации.) И да, в вашем случае не "передаётся имя, которого нет", а происходит где-то после изменение переменной. |
Цитата:
|
Магия.)
function(scale){...}(scale)
создаём анонимную функцию и тут же на месте её вызываем с параметром scale. Теперь есть отдельный внешний scale и есть отдельный scale как параметр функции.
return function(){ faunaAdd(scale);}
Создаём ещё одну анонимную функцию и возвращаем её как результат предыдущей. Это новосоданная функция замыкает на себя внутренний scale, к которому больше никто не имеет доступа кроме неё, после самовыполнения вышестоящей функции.Т.о. в addEventListener попадет тот же самый
function(){ faunaAdd(scale); }
только scale в нём теперь отдельный.Чтоб понятнее, можно записать так
function getFaunaAddWithScale(innerScale){
return function(){
faunaAdd(innerScale);
}
}
var faunaAddWithScale = getFaunaAddWithScale(scale);
g.addEventListener("click", faunaAddWithScale );
Собсно тут работает тот же самый механизм замыканий, что и мешал вам. Только у вас замыкалась внешняя переменная, которая со временем менялась, а тут замыкается, так сказать, персональная, неизменная.) |
Aetae,
Спасибо, я понял, правда это объяснение было не очень понятно из-за одинакового названия переменной, вот так, имхо, понятнее:
g.addEventListener("click", function(a){
return function(){
faunaAdd(a);
}
}(scale) ); //хардкор classic
То есть таким образом в функцию передаётся само значение скейла в переменную "а". Правда зачем ретурн я всё равно не понял.) Впрочем, без него не работает, так что нужен.) Впрочем, вместо этого можно использовать этот вариант:
g.scale = scale;
g.addEventListener("click", faunaAdd.bind(this, scale));
Но я так понял лучше всё же тот что выше использовать? |
| Часовой пояс GMT +3, время: 14:36. |