Показать полную графическую версию : [решено] переменные для events
VeshchiyOleg
15-09-2006, 13:14
как передать функции javascript, которая цепляется на событие, переменные???
да еще, чтоб работало и под IE и под FF???
например мне надо на некий созданный мною объект повесить onmouseover
я делаю так:
document.getElementById('element_id').onmouseower = function(e) {
//здесь e для того, чтоб в FF работало
...
statement
...
return false;
};
а что делать, если мне event в принципе не нужен, но нужно нечто другое???
я попробовал так:
document.getElementById('element_id').onmouseower = function(v) {
alert(v); // здесь v = myvar и, по сути я создаю функцию alert(myvar);
...
statement
...
return false;
}(myvar);
однако эта функция выполняется почему-то при создании функции, т.е. я ее пишу, что надо делать на mouseover, а она выполняется сразу
и на onmouseover ничего не происходит
что делать???
Prisoner
16-09-2006, 10:11
При обработке события в функцию-обработчик передается объект события, во втором примере Вашего кода он будет под переменной v. Т.е. Ваше предположение v=myvar неверно. А выполняется функция потому, что идет по сути ее вызов ввиду соблюдения синтаксиса "funcName(params)". То, что JS позволяет вам использовать определение тела функции и тут же ее вызов это его особенность, вот Вы ею и пользуйтесь. Правда это Вам вовсе не нужно, верно? Тогда помогут внешние переменные относительно контекста функции обработчика (частный случай - глобальные). Еще, на любителя, вариант - это обертка какой-то конечной функциональности в некий класс и назначение обработчиками методы этого класса, тогда приватные свойства класса могут решать поставленную Вами задачу - быть видимыми обработчику и невидимыми извне.
VeshchiyOleg
18-09-2006, 17:45
немного не въехал в написанное... это что же мне надо вызывать функцию примерно так??? (с глобальными переменными):
<tagname onmouseover="javascript:a='myval';domymouseover();"> а как присваивать такой обработчик посредством javascript`a???myobj.onmouseover = 'a=\'myval\';domymouseover();' или туда eval надо делать??? а с eval`ом оно не выполнится???
использование классов мне также ничего не даст... ну создам я класс с нужными мне переменными... и что??? туда ведь тоже надо значения передавать где-то...
зы
использовать конструкцию в описанном примере я подсмотрел в набле куроводства
там она работает - сам проверял
Prisoner
19-09-2006, 10:08
В какой именно набле? Можно ссылку?
1) Да, используйте глобальные переменные.
2) Код myobj.onmouseover = 'a=\'myval\';domymouseover();' эквивалентен myobj.onmouseover = 'domymouseover();' если в domymouseover будет выражение a='myval', за исключением области видимости переменной а. По сути этот код выполняет присваивание a='myval' каждый раз когда происходит событие и затем выполняет вызов функции domymouseover, т.о. если переменная нужна только для работы функции, то зачем засорять простраство глобальных переменных - выполняйте присваивание внутри domymouseover.
3) Присваивать обработчики событий можно (имхо, лучше) с помощью следующей функции (взятой там же, где и наблы):
function addEvent(elt, name, handler, atEnd) {
name = name.replace(/^(on)?/, 'on');
var prev = elt[name];
var tmp = '__tmp';
elt[name] = function(e) {
if (!e) e = window.event;
var result;
if (!atEnd) {
elt[tmp] = handler; result = elt[tmp](e); elt[tmp] = null; // delete() does not work in IE 5.0 (???!!!)
if (result === false) return result;
}
if (prev) {
elt[tmp] = prev; result = elt[tmp](e); elt[tmp] = null;
}
if (atEnd && result !== false) {
elt[tmp] = handler; result = elt[tmp](e); elt[tmp] = null;
}
return result;
}
return handler;
}
Использовать ее можно следующим образом:
addEvent(fields.login, 'onkeydown', function(e) {
var keyStatus = th.keyFilter(e, loginFilter);
if (keyStatus == ST_NOT_KEY) return false;
if (keyStatus == ST_SYSTEM_KEY) return true;
document.getElementById(loginImgId).src = imgDir+loginImgFocusedSrc;
th.prevT = new Date();
th.onchangeControl(this, delay);
return true;
})
Т.е. код {...} будет выполняться каждый раз при событии keydown. Как видите в анонимной функции (замыкании по терминологии 39ой наблы) используются и внешние переменные (imgDir, loginImgFocusedSrc), в этом нет ничего страшного.
VeshchiyOleg
19-09-2006, 11:40
все решилось гораздо проще, правда, как-то некрасиво:
eval('document.getElementById(\'element_id\').onmouseower = function(e) {'+
'alert(\''+myvar+'\');'+ // здесь myvar из переменной становится константой для ЭТОЙ функции!!!
...
statement
...
'return false;'+
'};');
Оказывается, можно обойтись и без создания функции createFunc(), однако это потребует от нас написания двух замыканий на каждом обороте цикла:
function create(n) {
var arr = [];
for (var i=1; i<n; i++) {
// Создаем функцию...
arr[i] = function(x) {
// создание замыкания с лексической x
return function() { alert(x*x) }
}(i); // и тут же ее вызываем с параметром i!
}
return arr;
}
Это работает по той же самой причине, что и код выше — за счет копирования i во вновь создаваемую при каждом вызове переменную x.
Prisoner
19-09-2006, 14:23
// здесь myvar из переменной становится константой для ЭТОЙ функции!!!
Верно, становится. Но именно поэтому теряется смысл нагромождения eval. Вы определяете обработчик, определить его можно однажды (потом - лишь переопределить) и целиком. Поэтому ваша переменная, ставшая константой ничем не отличается от внешней переменной, видимой из обработчика - глобальной. Если предполагать, что myvar внешняя относительно контекста обработчика, то отпадает надобность в eval, который, Вы верно выразились, добавляет "некрасивость" решению.
Так ведь проще:
var myvar = 'myvar_value';
document.getElementById('element_id').onmouseover = function(e) {
alert(myvar);
return;
};
VeshchiyOleg
19-09-2006, 17:02
может быть это я некорректно поставил задачу...
но этих myvar - множество
что-то вроде:
for (i = 0; i < myvar.length; i++) {
if (document.getElementById('element_' + i))
eval('document.getElementById(\'element_' + i + '\').onmouseower = function(e) {'+
'alert(\''+myvar[i]+'\');'+ // здесь myvar из переменной становится константой для ЭТОЙ функции!!!
...
statement
...
'return false;'+
'};');
} и мне нужно именно переменную, которая есть сейчас, передать в функцию, которая будет вызываться потом.
тут другая проблема возникает:
когда я создаю объект и прописываю ему event (не важно какой), то всё ок
если же я создаю этот объект внутри другого объекта, то event не отвечает...
в какую сторону копать???
Prisoner
19-09-2006, 19:12
1) function createHandler(myvar_i) {
return function(e) { alert('myvar_i=\''+myvar_i+'\' and e.type='+e.type); };
}
var myvar = ['the 0', 'the 1', 'the 2', 'the 3'];
for (i = 0; i < myvar.length; i++)
addEvent(document.getElementById('link'+i), 'onmouseover', createHandler(myvar[i]));
Похоже на решение? Функция addEvent приведена выше.
2) Приведите проблемный код, я не догоняю, видимо конец рабочего дня сказывается.
VeshchiyOleg
20-09-2006, 10:12
решение оказалось неожиданно простым!!!
использование функции addEvent поначалу оказалось безрезультатным.
надо было лишь отказаться от innerHTML!!! в пользу elt.appendChild(document.createTextNode(text))
всё замечательно, только вот как теперь сделать так, чтобы текст с имеющимися тэгами был именно в виде HTML, т.е. без преобразования html символов в их сущности???
Prisoner
20-09-2006, 12:30
VeshchiyOleg, я буду пытаться помочь Вам, если Вы будете вводить меня в курс проблемы, мой навык телепатии на зачаточном уровне. А то Вы прыгаете на одних понятных Вам вещах, а вопросы задаете мне... в частности.
VeshchiyOleg
20-09-2006, 14:47
я всё понимаю, мне тоже нелегко выщемить проблемное место...
попытаюсь описать проблему как можно подробнее
я пишу чат и делаю popup меню по правой кнопке мыши (в прилагаемом архиве картинка)
правая часть чата - список присутствующих, заполняется ф-ей TeamsUpdate (строка 460 в chat.js)
левая верхняя - собсна окно сообщений (ChatUpdate - [chat.js:253])
сообщение состоит из имени говорящего (объект с событием по правому клику мыши) и собсна текста сообщения - ajax`ом из бд подгружается (может содержать html-тэги - смайлики, например)
собственно сообщения пишутся в строках 279-290 (chat.js)
меню отображается ф-ей visibleMenu() (popup.js:31)
объекты создаются ф-ями:
- участник в окне чата: tObj (chat.js:225)
- участник в списке (потом объединю с ф-ей tObj): teamObj (chat.js:169)
- сообщение - непосредственно в цикле - (chat.js:280)
файлы сейчас в том виде, как есть у меня
перед выкладыванием на сервер я их естессно почищу от мусора
так что извините за неудобства если что
собсна проблемы ПОКА кончились ;)
теперь привожу всё в божеский вид
картинки в div`е не кэшируются:
справа в списке участников у каждого по три картинки - приват, инфа и блок
каждый раз при обновлении списка ВСЕ картинки подгружаются...
т.е. если 100 участников, то грузится 300 картинок (!!!)
где рыть??? как решить??? кто-нить с таким сталкивался???
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.