Добавление в эвент значение переменной
Суть вопроса в следующем: можно ли как-то, при добавлении элементу эвента (через джс), передать в функцию непосредственно значение переменной, а не её название.
То есть у нас имеется следующее: 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, время: 09:06. |