PDA

Просмотр полной версии : Не устанавливается обработчик события - не могу понять почему


NeverSummer
19.10.2007, 18:24
Подскажите плиз - есть такой код (картинка нормально подгружается но обработчик onRelease не работает :( )


var loader_mcl:MovieClipLoader = new MovieClipLoader();
var listener:Object = new Object();
loader_mcl.addListener(listener);

set_thumbnail();

function set_thumbnail( )
{
this.createEmptyMovieClip("img_thumb", 0);
loader_mcl.loadClip("suse10_t.jpg", this.img_thumb);
}

trace("img_thumb = " + this.img_thumb._name);

this.img_thumb.onRelease = function()
{
trace("Release entered");
}

listener.onLoadInit = function(target_mc:MovieClip) {
target_mc._x = 544;
target_mc._y = 107;
}

вывод проги:

img_thumb = img_thumb

- т.е. объект существует - по идее должен присваиватся обрабтчик сообщений и работать.
Причем если я обрабтчик размещаю в onLoadInit подобным образом


listener.onLoadInit = function(target_mc:MovieClip) {
target_mc._x = 544;
target_mc._y = 107;

target_mc.onRelease = function()
{
trace("Release entered");
}
}

то все работает - но не могу понять почему - объясните плиз - никак не могу врубится в логику работы флэша не говоря уже о том, что конструкции с вложенными функциями выглядят жуть как некрасиво имхо... Неаккуратненько как то :)
Желательно если укажете мне место в хелпе или статью какую (можно на инглиш) где прямо написанно почему работает так а не этак...

Wolsh
19.10.2007, 19:05
"Машенька, а как тебя зовут?"
Конечно же onRelease должен вешаться на клип только после загрузки, т.е. когда сработает onLoadInit.

NeverSummer
19.10.2007, 19:28
2Wolsh - а есть где написанно об этом? Блин никак не могу найти как сообщения ходят в хелпе .. Все равно не понятно - а можно в жтом случае определить обработчик не в тебе другой функции?

Wolsh
19.10.2007, 19:35
Не совсем понятно, что Вы имеете в виду...
"не в тебе другой функции" - значит "в теле этой"
какой ЭТОЙ?
Может проще объяснить, чего Вы хотите добиться, что это будет.

NeverSummer
19.10.2007, 19:56
2Wolsh - я имел ввиду что хотел бы избежать определения функции обрабтчика onRelease в теле функции onInit - так как такие определения ведут к порождению запутанного и плохочитаемого кода (имхо конечно).
Во вторых мне не очень понятна логика флэша в том смысле - что я должен ждать пока в мувик загрузится содержимое что бы определить обработчик события. Отсюда вопрос - есть ли разделы хелпа или сторонние статьи (можно на инглиш) в которых хорошо разжеванная вот такая мудреная логика .. Просто я вот еще совсем новичок в AS хотя раньше писал много на С++ и у меня в процессе написания просто на кажом шагу затык какой то - измучился я совсем.

alexcon314
19.10.2007, 23:28
В вашем примере логика такова, имхо.
вы создали ПУСТОЙ мувик "img_thumb" и попытались ТУТЖЕ повесить на него "onRelease" - обработчик не работает, хотябы потому, что в этот момент "img_thumb" имеет размеры 0х0
если вешать "onRelease" на НЕПУСТОЙ мувик, т.е с уже загруженной картинкой - все в порядке.
проблема в том что
this.img_thumb.onRelease = function()
{
trace("Release entered");
}

выполняется РАНЬШЕ, чем
loader_mcl.loadClip("suse10_t.jpg", this.img_thumb);

т.к. загрузка идет асинхронно.
некрасивость можно легко исправить
var handleFunc = function () {
trace("Release entered");
};
var loader_mcl:MovieClipLoader = new MovieClipLoader();
var listener:Object = new Object();
loader_mcl.addListener(listener);
set_thumbnail();
function set_thumbnail() {
this.createEmptyMovieClip("img_thumb", 0);
loader_mcl.loadClip("suse10_t.jpg", this.img_thumb);
}
trace("img_thumb = " + this.img_thumb._name);
listener.onLoadInit = function(target_mc:MovieClip) {
target_mc._x = 544;
target_mc._y = 107;
target_mc.onRelease = handleFunc;
};

............
что касается общего понимания и разжевывания - то как говорится "мы все учились по-немногу, чему-нибудь и как-нибудь..."
искать базовые знания в нете - полный изврат, вмечсто знаний получится каша в голове.
варианты:
- обычная книга (на этом форуме особой популярностью пользуется (и вполне заслуженно) автор Колин Мук (Colin Moock, http://moock.org)
и как минимум два его бестселлера
"ActionScript for Flash MX: The Definitive Guide"
"Essential ActionScript 2.0"
(есть переводы, ссылок на скачку нет!)
- хороший наставник.
Наилучшим результатам способствует сочетание 1 и 2

Wolsh
20.10.2007, 00:14
alexcon314 , отличный ответ, только одна поправка. Обработчик не работает не потому что размер клипа 0х0 :) Нет, всё гораздо логичнее. Просто после загрузки нового содержимого в клип все повешанные на него обработчики отменяются (слетают). Это легко проверить, создав my_mc вручную, с какой-нить картинкой внутри, поместив его на сцене. И повесить, скажем, такой код
my_mc.onRelease = function(){trace("Release!")}
my_mc.loadMovie("img.jpg");
После загрузки картинки никакого релиза не будет.
По аналогии с работой вручную это примерно тоже самое, что перейти с одного ключевого кадра, на котором повешен код, на другой ключевой кадр, где кода с обработчиком уже нет, хотя экземпляр вроде тотже и даже с тем же именем - код с первого ключевого кадра на него уже не действует. Т.е. имя остается, но сам объект уже считается другим, прежний удаляется - ну и логично, что его обработчики удаляются вместе с ним. но есть интересный момент - его свойства при этом не удаляются и переходят объекту с таким же именем, т.е. в данном случае - преемнику :) Именно поэтому новая картинка будет иметь те же координаты, что и созданный вручную my_mc. Переменные типа my_mc.a также останутся в доступе. Я думаю, это вызвано простой экономией ресурсов - при удалении "первого" my_mc переменные не удаляются по той простой причине, что с исчезновением my_mc вроде как пропадает ссылка на них (my_mc.a).

alexcon314
20.10.2007, 00:31
"мы все учились по-немногу, чему-нибудь и как-нибудь..."
я действительно этого не знал, спасибо.
впрочем я исходил из этого

this.createEmptyMovieClip("mc",0);
this.mc.onRelease = function(){
trace("Release");
}

this.createEmptyMovieClip("mc",0);
this.mc.onEnterFrame = function(){
trace("EnterFrame");
}
обработчик onRelease не работает из-за "0х0" имхо, причем тут загрузка? хотя это, конечно не относится к примеру темы, дествительно:
this.createEmptyMovieClip("mc", 0);
this.mc.onEnterFrame = function() {
trace("EnterFrame");
};
var loader_mcl:MovieClipLoader = new MovieClipLoader();
var listener:Object = new Object();
loader_mcl.addListener(listener);
loader_mcl.loadClip("suse10_t.jpg", mc);
ОДИН раз выводит в output EnterFrame

Wolsh
20.10.2007, 01:16
>> обработчик onRelease не работает из-за "0х0" имхо, причем тут загрузка?
Поделись как проверял? :)

alexcon314
20.10.2007, 01:26
this.createEmptyMovieClip("mc",0);
this.mc.onRelease = function(){
trace("Release");
}

в output ничего не выводит. возможная причина - нулевой размер клипа.
сам обработчик у клипа есть.

for( i in mc){
trace(i);
}

вот и вся проверка. физически не возможно реализовать :) onRelease у объекта нулевых размеров. разве не логично?

Wolsh
20.10.2007, 01:40
Вот я и прикололся. Вот код, который убедительно показывает, что всё дело в загрузке.
_root.createEmptyMovieClip("mc", 0);

mc.onRelease = function(){ trace("RELEASE!")}

trace("1 " + mc._width); // ширина пустого клипа - выводит 0
trace("1 " + mc.onRelease); // наличие обработчика - выводит Type Function
mc.onRelease(); //Вызываем событие (нажимаем на пустой клип) - выводит RELEASE!

var loader_mcl:MovieClipLoader = new MovieClipLoader();
var listener:Object = new Object();
loader_mcl.addListener(listener);
listener.onLoadInit = function(success){ // после загрузки
if(success){
trace("2 " + mc._width); // ширина == ширине картинки
trace("2 " + mc.onRelease); // наличие обработчика - выводит undefined
mc.onRelease(); // вызываем событие - ничего не происходит
}
}
loader_mcl.loadClip("suse10_t.jpg", mc);
-----------
Не выдержал и прокомментировал :)

alexcon314
20.10.2007, 01:57
я и не спорю, что после загрузки контента обработчик пропадает. сам написал нечто подобное
var handleFunc = function () {
trace("Release entered");
};
this.createEmptyMovieClip("mc", 0);
for (i in mc) {
trace("1 "+i);
}
mc.onRelease = function() {
trace("onRelease");
};
for (i in mc) {
trace("2 "+i);
}
var loader_mcl:MovieClipLoader = new MovieClipLoader();
loader_mcl.addListener(this);
loader_mcl.loadClip("suse10_t.jpg", mc);
onLoadInit = function (target_mc:MovieClip) {
for (i in mc) {
trace("3 "+i);
}
target_mc.onRelease = handleFunc;
for (i in mc) {
trace("4 "+i);
}
};

речь не об этом.
почему не работает ИМЕЮЩИЙСЯ у empty клипа обработчик onRelease? пример:

this.createEmptyMovieClip("mc", 0);
for (i in mc) {
trace("1 "+i);
}
mc.onRelease = function() {
trace("onRelease");
};
for (i in mc) {
trace("2 "+i);
}

нету его по-началу, вешаем - есть, но не работает. вот о чем речь.
с загрузкой понятно - пропадает он. а здесь - нет никакой загрузки, обработчик есть, но не работает.
так при при чем тут загрузка?
я думаю что это происходит (!без загрузок, блин!) из-за нулевых размеров клипа.

Wolsh
20.10.2007, 02:18
>>почему не работает ИМЕЮЩИЙСЯ у empty клипа обработчик onRelease?

Я тебя могу конечно еще раз спросить, как проверял, но этот метод на тебя не действует :)
Где в твоем коде проверка? Где ты создаешь событие onRelease? Ты только создаешь обработчик, а событие не вызываешь. Напротив, в моем коде как раз вызывается событие - обрати внимание, и оно обрабатывается до загрузки и не обрабатывается после, поскольку, собственно, и обработчик undefined. Посмотри внимательно, ОК?

NeverSummer
20.10.2007, 02:40
Ой писал такое подробный мессаг .. и нажал не туда - все пропало - сил нет уже повторить. Просто скажу - большое спасибо за ответы ...

udaaff
20.10.2007, 02:58
alexcon314, все работает, просто при этом нужно умудриться нажать на клип не имеющий размеров =)