Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 14.02.2018, 00:58
Новичок на форуме
Отправить личное сообщение для BOCbMOU Посмотреть профиль Найти все сообщения от BOCbMOU
 
Регистрация: 14.02.2018
Сообщений: 4

Добавление в эвент значение переменной
Суть вопроса в следующем: можно ли как-то, при добавлении элементу эвента (через джс), передать в функцию непосредственно значение переменной, а не её название.

То есть у нас имеется следующее:
g.addEventListener("click", function () { faunaAdd(scale); });
g.onclick = function () { faunaAdd(scale); };

Вызов функции faunaAdd в которую надо передать значение scale, но проблема в том, что таким способом передаётся непосредственно само название переменной и в итоге при срабатывании эвента в функцию будет передано, по сути, ничего, ведь scale в эвенте не определён.

Я долго пытался найти решение этой проблемы гугле, но то ли плохо искал, то ли ещё что, но не нашёл вообще ничего. Единственное до чего допёр сам, это сделать объявление так:
g.setAttribute("onclick", "faunaAdd(" + scale + ");");

Тогда да, передаётся именно значение и всё работает как надо, но выглядит это... Ужасно и неудобно.
Собственно поэтому и возник вопрос, может кто знает как сделать подобное, но с нормальным объявлением.
Ответить с цитированием
  #2 (permalink)  
Старый 14.02.2018, 01:03
Аватар для j0hnik
Профессор
Отправить личное сообщение для j0hnik Посмотреть профиль Найти все сообщения от j0hnik
 
Регистрация: 01.12.2016
Сообщений: 3,650

в корне неправильный подход.
во первых хорошим тоном считается не встраивать в html теги обработчики, а так чтобы вешать через setAttribute вижу впервые.

напишите что хотите сделать, подскажем как будет правильно.
Ответить с цитированием
  #3 (permalink)  
Старый 14.02.2018, 01:19
Новичок на форуме
Отправить личное сообщение для BOCbMOU Посмотреть профиль Найти все сообщения от BOCbMOU
 
Регистрация: 14.02.2018
Сообщений: 4

Сообщение от j0hnik Посмотреть сообщение
в корне неправильный подход.
во первых хорошим тоном считается не встраивать в html теги обработчики, а так чтобы вешать через setAttribute вижу впервые.

напишите что хотите сделать, подскажем как будет правильно.
В данном случае эвенты могу вешать только на g элементы, поскольку у меня svg поле с g элементами, в которых polygon и text.

А что надо... В целом, я уже выше всё описал, да и не важно куда эвент вешать, проблема актуальна на любом элементе будет.
В общем, всё, что мне надо, это при добавлении эвента элементу, передать в него значение переменной, а не название переменной, дабы при срабатывании эвента в функцию (в моём случае) передавалось сразу готовое значение, а не пустое значение необъявленной переменной (в пределах эвента).

Короче, если мы используем этот способ:
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");

Последний раз редактировалось BOCbMOU, 14.02.2018 в 01:22.
Ответить с цитированием
  #4 (permalink)  
Старый 14.02.2018, 01:20
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,491

"Хуяк-хуяк" решения:
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
...
А как делать нормально - зависит от конкретной ситуации.)

И да, в вашем случае не "передаётся имя, которого нет", а происходит где-то после изменение переменной.
__________________
29375, 35

Последний раз редактировалось Aetae, 14.02.2018 в 01:25.
Ответить с цитированием
  #5 (permalink)  
Старый 14.02.2018, 01:30
Новичок на форуме
Отправить личное сообщение для BOCbMOU Посмотреть профиль Найти все сообщения от BOCbMOU
 
Регистрация: 14.02.2018
Сообщений: 4

Сообщение от Aetae Посмотреть сообщение
g.addEventListener("click", function(scale){
  return function(){
    faunaAdd(scale);
  }
}(scale) ); //хардкор classic
Благодарствую, но можно уточнить для чего 2 и 5 строки? Я их смысл тут не улавливаю.
Ответить с цитированием
  #6 (permalink)  
Старый 14.02.2018, 01:44
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,491

Магия.)

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 );


Собсно тут работает тот же самый механизм замыканий, что и мешал вам. Только у вас замыкалась внешняя переменная, которая со временем менялась, а тут замыкается, так сказать, персональная, неизменная.)
__________________
29375, 35

Последний раз редактировалось Aetae, 14.02.2018 в 01:51.
Ответить с цитированием
  #7 (permalink)  
Старый 14.02.2018, 02:08
Новичок на форуме
Отправить личное сообщение для BOCbMOU Посмотреть профиль Найти все сообщения от BOCbMOU
 
Регистрация: 14.02.2018
Сообщений: 4

Aetae,
Спасибо, я понял, правда это объяснение было не очень понятно из-за одинакового названия переменной, вот так, имхо, понятнее:
g.addEventListener("click", function(a){
  return function(){
    faunaAdd(a);
  }
}(scale) ); //хардкор classic

То есть таким образом в функцию передаётся само значение скейла в переменную "а". Правда зачем ретурн я всё равно не понял.) Впрочем, без него не работает, так что нужен.)

Впрочем, вместо этого можно использовать этот вариант:
g.scale = scale;
g.addEventListener("click", faunaAdd.bind(this, scale));

Но я так понял лучше всё же тот что выше использовать?
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Значение переменной присваивается только со второй попытки thesun Общие вопросы Javascript 9 29.01.2016 20:52
Проблемы с выпадающим списком JavaScript ursus102 Общие вопросы Javascript 0 16.01.2016 19:30
Выводить значение раньше переменных Гробовщик Общие вопросы Javascript 11 10.09.2013 08:42
В contains() не подставляется значение переменной Heger jQuery 2 11.12.2011 20:26
Значение переменной salex009 jQuery 1 05.12.2011 16:55