Предыстория
Имеется скрипт (?) swf - видеочат. Делался на заказ сторонним программистом (квалификацию его не знаю, вообще не знаю кто он такой).
Я прикрутил его к сайту, над которым работаю. И все вроде нормально работало.
Проблема
После правки (флэшером) внешнего вида чата был замечен баг - в IE9 (насчет младших версий не в курсе - не проверяли) стали валиться ошибки js:
Сообщение: Объект не поддерживает свойство или метод "invite"
и т.п., где объект возвращала такая ф-ция:
function getFlashMovie(movieName) {
var isIE = navigator.appName.indexOf("Microsoft") != -1;
return (isIE) ? window[movieName] : document[movieName];
}
и html:
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="agent" codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab" width="1" height="1">
<param name="movie" value="<?php echo SWFURL . 'agent.swf' ?>" />
<param name="quality" value="high" />
<param name="allowScriptAccess" value="sameDomain" />
<param name="bgcolor" value="#ffffff" />
<param name="flashvars" value="id=<?php echo $user->id ?>&nick=<?php echo HTML::chars($user->name) ?>" />
<embed src="<?php echo SWFURL . 'agent.swf' ?>" name="agent" play="true" loop="false" quality="high" allowscriptaccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer" align="middle" width="1" height="1" bgcolor="#ffffff" flashvars="id=<?php echo $user->id ?>&nick=<?php echo HTML::chars($user->name) ?>" />
</object>
После дебага выяснилось, что в ie9 getFlashMovie('agent') возвращает
[object HTMLCollection] {
agent : [object HTMLCollection],
length : 2,
item : function item() { [native code] } ,
namedItem : function namedItem() { [native code] }
а в остальных браузерах объект HTMLEmbedElement (или что-то в этом роде, точно не помню уже :))
фикс пролучился простым, хотя проблему я не совсем понял (точнее не понял, почему ранее в ie9 возвращалось HTMLObjectElement, а сейчас вдруг стала взвращаться коллекция object и embed, хотя html я не трогал, он у меня вообще в отдельном файле этот кусок). Вот:
function getFlashMovie(movie) {
return $.browser.msie ? $('#' + movie + '-1')[0] : $('#' + movie + '-2')[0];
}
возвращает то что нужно, при этом как вы догадались html был немного подкорректирован
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="agent-1" codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab" width="1" height="1">
<param name="movie" value="<?php echo SWFURL . 'agent.swf' ?>" />
<param name="quality" value="high" />
<param name="allowScriptAccess" value="sameDomain" />
<param name="bgcolor" value="#ffffff" />
<param name="flashvars" value="id=<?php echo $user->id ?>&nick=<?php echo HTML::chars($user->name) ?>" />
<embed src="<?php echo SWFURL . 'agent.swf' ?>" id="agent-2" play="true" loop="false" quality="high" allowscriptaccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer" align="middle" width="1" height="1" bgcolor="#ffffff" flashvars="id=<?php echo $user->id ?>&nick=<?php echo HTML::chars($user->name) ?>" />
</object>
А теперь самое интересное - вопрос на засыпку:
какого хрена
function getFlashMovie(movie) {
return $.browser.msie ? $('object.' + movie)[0] : $('embed.' + movie)[0]; // в html соответственно были добавлены классы agent для object и embed
}
возвращает нужные объекты, но в них нет методов для работы с чатом (invite(), cancel() и т.п.) ??? А если выбирать по id - то они чудесным образом появляются в этих объектах ??????!!
$('object.agent')[0]
[object HTMLObjectElement] {
ReadyState : 4,
TotalFrames : 1,
Playing : false,
Quality : 1,
ScaleMode : 3,
AlignMode : 5,
BackgroundColor : 16777215,
Loop : true,
Movie : "http://domain.com/media/swf/agent.swf",
FrameNum : 0
...
}
$('#agent-1')[0]
[object HTMLObjectElement] {
invite : function () { return eval(instance.CallFunction("<invoke name=\""+name+"\" returntype=\"javascript\">" + __flash__argumentsToXML(arguments,0) + "</invoke>")); },
accept : function () { return eval(instance.CallFunction("<invoke name=\""+name+"\" returntype=\"javascript\">" + __flash__argumentsToXML(arguments,0) + "</invoke>")); },
reject : function () { return eval(instance.CallFunction("<invoke name=\""+name+"\" returntype=\"javascript\">" + __flash__argumentsToXML(arguments,0) + "</invoke>")); },
cancel : function () { return eval(instance.CallFunction("<invoke name=\""+name+"\" returntype=\"javascript\">" + __flash__argumentsToXML(arguments,0) + "</invoke>")); },
ReadyState : 4,
TotalFrames : 1,
Playing : false,
Quality : 1,
ScaleMode : 3,
AlignMode : 5
...
}
PS. И вопрос вдогонку - в чем была причина появления бага? почему в ie9 начала возвращаться коллекция вместо объекта ? Это может быть косяком флэшера или javascript-движок в ie9 обновился ?
PPS. СОРРИ ЗА МНОГА БУКАФФ :D
_____________
Профессиональная разработка на заказ
Я на GitHub | второй профиль