Как избавиться от ошибки в цепочке функций
Написал небольшой код, но при вызове происходит ошибка:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Документ без названия</title> </head> <body> <div> <div onclick="alert($$(this).$$prev().innerHTML);">SJ_TEST 1</div> <div onclick="alert($$(this).$$prev().innerHTML);">SJ_TEST 2</div> <div onclick="alert($$(this).$$next().$$html());">SJ_TEST 3</div> <div onclick="alert($$(this).$$html());">SJ_TEST 4</div> <div onclick="alert($$(this).$$first().$$html());"><span>Привет 1</span> <span>Привет 2</span>SJ_TEST 5</div> <div onclick="alert($$(this).$$last().$$html());"><span>Привет 3</span> <span>Привет 4</span>SJ_TEST 6</div> <div onclick="alert($$(this).$$parent().$$html());">SJ_TEST 7</div> <div onclick="alert($$(this).$$next().$$html());">SJ_TEST 8</div> </div> <script type="text/javascript"> var _$$ = { $:function () { var obj; switch(arguments.length) { case 0: return document; break; case 2: _$$.$(arguments[0]).innerHTML=arguments[1]; break; case 3: _$$.$(arguments[0]).style[arguments[1]]=arguments[2]; break; } if(arguments.length>0) { if(typeof arguments[0] == 'string') { obj=_$$.$().getElementById(arguments[0]); } else { obj=arguments[0]; } } obj.$$ = function() { switch(arguments.length) { case 0: this.$$ = function () { return _$$.$.apply(null,arguments); } break; case 1: obj.innerHTML=arguments[0]; break; case 2: obj.style[arguments[0]] = arguments[1]; break; } return obj; } obj.$$prev = function() { var elm=this; do { elm = elm.previousSibling; } while(elm && elm.nodeType != 1); return _$$.$(elm); } obj.$$next = function() { var elm=this; do { elm = elm.nextSibling; } while(elm && elm.nodeType != 1); return _$$.$(elm); } obj.$$first = function() { var elm=this; elm = elm.firstChild; return _$$.$(elm && elm.nodeType != 1 ? elm.nextSibling : elm); } obj.$$last = function() { var elm=this; elm = elm.lastChild; return _$$.$(elm && elm.nodeType != 1 ? elm.previousSibling : elm); } obj.$$parent = function(num) { var elm=this; num = num || 1; for (var i=0; i<num; i++) if (elm != null) elm = elm.parentNode; return _$$.$(elm); } obj.$$html = function() { var elm=this; return _$$.$(elm).innerHTML; } return obj; } } var $$ = _$$.$; </script> </body> </html> т.е. смотрите в чем ошибка если не использовать вот эту строку var $$ = _$$.$; а вызывать функцию напрямую <div> <div onclick="alert(_$$.$(this).$$prev().innerHTML);">SJ_TEST 1</div> <div onclick="alert(_$$.$(this).$$prev().innerHTML);">SJ_TEST 2</div> <div onclick="alert(_$$.$(this).$$next().$$html());">SJ_TEST 3</div> <div onclick="alert(_$$.$(this).$$html());">SJ_TEST 4</div> <div onclick="alert(_$$.$(this).$$first().$$html());"><span>Привет 1</span> <span>Привет 2</span>SJ_TEST 5</div> <div onclick="alert(_$$.$(this).$$last().$$html());"><span>Привет 3</span> <span>Привет 4</span>SJ_TEST 6</div> <div onclick="alert(_$$.$(this).$$parent().$$html());">SJ_TEST 7</div> <div onclick="alert(_$$.$(this).$$next().$$html());">SJ_TEST 8</div> </div> то все работает четко как правильно работать с _$$.$ заменив его на $$ при этом не потеряв структуру? |
Какая ошибка?
|
если запустить код то он не работает корректно
в общем если вызывать _$$.$(this)то все четко, а если вызывать через $$(this)то не работает |
Дело в том, что когда обработчик события задаётся в атрибуте HTML-тэга, то он видит вначале свойства элемента, которому он принадлежит, а уже потом свойства window.
Когда при первом клике вызывается обработчик с кодом alert($$(this).$$prev().innerHTML); то у соответствующего элемента <div> нет свойства $$, поэтому идентификатор $$ возвращает соответствующее свойство window, то есть глобальную переменную с таким именем. После этого, при выполнении того же обработчика, в элементе <div> создаётся свойство $$. При втором клике внутри обработчика идентификатор $$ уже возвращает свойство $$ элемента <div>. |
Цитата:
Сможешь найти выход из возникшей ситуации? как разрулить эту ошибку? |
Цитата:
|
Цитата:
т.е. придётся и внутри заменять. |
Здесь дело не в структуре _$$.$ или $$, а в перекрытии областей видимости. Функция _$$.$ создает свойство $$ в элементе <div> с помощью:
obj.$$ = function() { switch(arguments.length) { case 0: this.$$ = function () { return _$$.$.apply(null,arguments); } break; case 1: obj.innerHTML=arguments[0]; break; case 2: obj.style[arguments[0]] = arguments[1]; break; } return obj; } Это свойство перекрывает глобальную переменную $$ внутри обработчика события. Я не понимаю, зачем нужен вышенаписанный код. Если его убрать, то все будет работать. |
И все же в чем ошибка, может кто догадается как подправить?
смотрите, оказывается все дело в this если получать элемент по id то все работает: вот пример <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Документ без названия</title> </head> <body> <div id="xxx"> <div onclick="alert($$(this).innerHTML);">SJ_TEST xxx</div> <div onclick="alert($$(this).$$prev().innerHTML);">SJ_TEST 1</div> <div onclick="alert($$(this).$$prev().innerHTML);">SJ_TEST 2</div> <div onclick="alert($$(this).$$next().$$('color','red').$$('color','blue').$$next().$$('color','red'));">SJ_TEST 3</div> <div id="sss" onclick="dd();">SJ_TEST 3sss</div> <div onclick="alert($$(this).$$html());">SJ_TEST 4</div> <div onclick="alert($$(this).$$first().$$html());"><span>Привет 1</span> <span>Привет 2</span>SJ_TEST 5</div> <div onclick="alert($$(this).$$last().$$html());"><span>Привет 3</span> <span>Привет 4</span>SJ_TEST 6</div> <div onclick="alert($$(this).$$parent().$$html());">SJ_TEST 7</div> <div onclick="alert($$(this).$$next().$$html());">SJ_TEST 8</div> </div> <script type="text/javascript"> function dd() { alert($$('sss').$$next().$$('color','red').$$('color','blue').$$next().$$('color','red')); } var _$$ = { $:function () { var obj; switch(arguments.length) { case 0: return document; break; case 2: _$$.$(arguments[0]).innerHTML=arguments[1]; break; case 3: _$$.$(arguments[0]).style[arguments[1]]=arguments[2]; break; } if(arguments.length>0) { if(typeof arguments[0] == 'string') { obj=_$$.$().getElementById(arguments[0]); } else { obj=arguments[0]; } } obj.$$ = function() { switch(arguments.length) { case 0: this.$$ = function () { return _$$.$.apply(null,arguments); } break; case 1: obj.innerHTML=arguments[0]; break; case 2: obj.style[arguments[0]] = arguments[1]; break; } return obj; } obj.$$prev = function() { var elm=this; do { elm = elm.previousSibling; } while(elm && elm.nodeType != 1); return _$$.$(elm); } obj.$$next = function() { var elm=this; do { elm = elm.nextSibling; } while(elm && elm.nodeType != 1); return _$$.$(elm); } obj.$$first = function() { var elm=this; elm = elm.firstChild; return _$$.$(elm && elm.nodeType != 1 ? elm.nextSibling : elm); } obj.$$last = function() { var elm=this; elm = elm.lastChild; return _$$.$(elm && elm.nodeType != 1 ? elm.previousSibling : elm); } obj.$$parent = function(num) { var elm=this; num = num || 1; for (var i=0; i<num; i++) if (elm != null) elm = elm.parentNode; return _$$.$(elm); } obj.$$html = function() { var elm=this; return _$$.$(elm).innerHTML; } return obj; } } var $$ = _$$.$; </script> </body> </html> если щелкнуть по элементу <div id="sss" onclick="dd();">SJ_TEST 3sss</div> несколько раз, то все работает правильно если щелкать по другим элементам с $$(this)несколько раз, то происходит ошибка как модифицировать вот эту часть кода: else { obj=arguments[0]; } именно в нем происходит при передаче this вот такой колабс obj=this; |
Цитата:
$$(this).$$next().$$('color','red').$$('color','blue').$$next().$$('color','red').$$next().$$('новый текст') и т.д. без него ничего работать не будет |
Ты ошибаешься. Дело не в this, а в том, что я написал несколько постов назад.
Твой последний пример работает, потому что идентификатор $$ теперь используется в другой области видимости - вне кода внутри тэга <div>. Попробуй написать: document.getElementsByTagName("div")[2].onclick=function(){ alert($$(this).$$prev().innerHTML); }; и убрать атрибут onclick в соответствующем <div>, и всё будет работать. |
Но ведь если убрать
066 obj.$$prev = function() { 067 var elm=this; 068 do { 069 elm = elm.previousSibling; 070 } while(elm && elm.nodeType != 1); 071 return _$$.$(elm); 072 } 073 obj.$$next = function() { 074 var elm=this; 075 do { 076 elm = elm.nextSibling; 077 } while(elm && elm.nodeType != 1); 078 return _$$.$(elm); 079 } 080 obj.$$first = function() { 081 var elm=this; 082 elm = elm.firstChild; 083 return _$$.$(elm && elm.nodeType != 1 ? elm.nextSibling : elm); 084 } 085 obj.$$last = function() { 086 var elm=this; 087 elm = elm.lastChild; 088 return _$$.$(elm && elm.nodeType != 1 ? elm.previousSibling : elm); 089 } 090 obj.$$parent = function(num) { 091 var elm=this; 092 num = num || 1; 093 for (var i=0; i<num; i++) 094 if (elm != null) elm = elm.parentNode; 095 return _$$.$(elm); 096 } 097 obj.$$html = function() { 098 var elm=this; 099 return _$$.$(elm).innerHTML; 100 } то все работает в любой области видимости... |
Можна подробнее, пожалуйста, если то убрать, то что работает?
|
все сам разобрался, нужно заворачивать this в функцию а потом вызывать по onclick ее с передачей ей this
|
Часовой пояс GMT +3, время: 04:27. |