Javascript работает только в Safari с предупреждением

Я новичок в javascript, и у меня возникли проблемы с тем, чтобы мой скрипт работал в Safari. Я сделал множество поисков в Google, чтобы найти решение, но не нашел ничего, что сработало.

У меня есть HTML-страница, которая использует javascript для загрузки swf и подписи из двух отдельных массивов. Существует следующая кнопка, которая загрузит другой SWF и новую подпись при нажатии. Он отлично работает в IE и Firefox, но в Safari новый SWF не отображается. В отладчике Safari отображается правильное имя нового SWF-файла, но на экране отображается исходный SWF-файл. Единственный способ, которым я заставил его работать, - это если у меня есть предупреждение после кода. Я попытался настроить порядок событий в своей функции, но это ничего не решило.

Есть идеи? (Прошу прощения, если я предоставил слишком много кода, я просто хочу дать вам полную картину.)

Javascript (находится в шапке):

var swfFrame=new Array();
swfFrame[0]='frame_01.swf';
swfFrame[1]='frame_02.swf';
swfFrame[2]='frame_03.swf';

var paragraphTxt=new Array();
paragraphTxt[0]='caption 1';
paragraphTxt[1]='caption 2';
paragraphTxt[2]='caption 3';

function nextFrame(x){
i = i+x;
if(i>=swfFrame.length){
    i=i-1;
    window.open('quiz.html');
}else{
document.getElementById("framenum").innerHTML = (i+1) + " of " + swfFrame.length;
document.getElementById("paragraph").innerHTML = paragraphTxt[i];
// IE
document.getElementById("flashPlayer").movie = "swf/" + swfFrame[i];
// FIREFOX et al
<!--[if !IE]>-->
document.getElementById("flashPlayer").data = "swf/" + swfFrame[i];
<!--[endif}-->
//  ALERT (doesn't work in Safari if alert is off)
alert(document.getElementById("flashPlayer").data);
}
if(i>0){
    document.getElementById("button_Bck").style.visibility = "visible";
}else{
    hideBack();
}
}

function hideBack(){
document.getElementById("button_Bck").style.visibility = "hidden";
}

Код кнопки, используемой для перехода к следующему SWF-файлу:

<a href="javascript://" onclick="nextFrame(1)"><div id="button_Nxt"><div id="buttonText">Next</div></div></a>

person rlane423    schedule 15.03.2011    source источник
comment
Вы получаете какие-либо ошибки или предупреждения javascript?   -  person drudge    schedule 16.03.2011
comment
Никаких ошибок или предупреждений, он просто не загружается в новый swf.   -  person rlane423    schedule 16.03.2011


Ответы (4)


@ rlane423: Я не думаю, что вы действительно можете использовать такие условные комментарии в блоке скрипта.

Пытаться --

    /* preceding code omitted for brevity */

    var isIE = false; // set to false by default
</script>

<!--[if IE]>
<script type="text/javascript">
    isIE = true;
</script>
<![endif]-->

<script type="text/javascript">
     if (isIE) {
         // IE
         document.getElementById("flashPlayer").movie = "swf/" + swfFrame[i];
     } else {
         // FIREFOX et al
         document.getElementById("flashPlayer").data = "swf/" + swfFrame[i];
     }

     /* rest of script omitted for brevity */
</script>
person stealthyninja    schedule 15.03.2011
comment
У меня не было никаких проблем сделать это так, как я написал. Я пробовал это так, и это все еще не работало в Safari. Но он также перестал работать в Firefox. Спасибо за предложение. - person rlane423; 16.03.2011
comment
@rlane423: Это где-нибудь доступно онлайн? - person stealthyninja; 16.03.2011
comment
Он находится на защищенном паролем сайте разработки моей компании, к которому я не могу предоставить доступ. Коллега помог мне реализовать этот код, и теперь он снова работает в Firefox, но по-прежнему не работает в Safari. - person rlane423; 16.03.2011
comment
@rlane423: Я думаю, проблема в том, что Safari также использует .movie, а не .data. Я собираюсь посмотреть позже, чтобы увидеть, не могу ли я найти хороший способ обнаружить Safari в JavaScript, чтобы затем передать ему ту же строку, что и IE. - person stealthyninja; 16.03.2011
comment
Когда я проверяю код в веб-инспекторе Safari, он показывает, что он использует данные. - person rlane423; 16.03.2011

Я думаю, что ваша проблема связана с тем, что flash работает в отдельном потоке от javascript. Когда вы используете оповещение для отладки, а ваша страница включает флэш-память, вы можете столкнуться с подобными гейзенбагами. При отсутствии flash все на вашей странице, включая javascript, будет блокироваться во время оповещения. С другой стороны, Flash работает в отдельном потоке и не блокируется для предупреждений.

Этот пример иллюстрирует то, о чем я говорю:

<object width="480" height="390"><param name="movie" value="http://www.youtube.com/v/oHg5SJYRHA0?fs=1&amp;hl=en_US&amp;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/oHg5SJYRHA0?fs=1&amp;hl=en_US&amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="390"></embed></object>
<a href="javascript:alert('hello'); return false;">Click me!</a>

Запустите фильм, а затем нажмите на ссылку — видео не перестанет воспроизводиться, пока действует оповещение.

Самое простое решение для этого, вероятно, состоит в том, чтобы обернуть код после оператора предупреждения в функцию setTimeout с небольшой задержкой:

setTimeout(function() { ... }, 50);

Лучшим решением будет зарегистрировать событие во флэш-ролике или опросить его, пока он не будет готов к обновлению.

person tilleryj    schedule 15.03.2011
comment
Я попытался поместить setTimeout в кнопку onClick, и это, похоже, не повлияло. Я также попытался поместить его в свою функцию, где заменяется вспышка, и это тоже не сработало. - person rlane423; 16.03.2011
comment
Вы пытались поставить все после предупреждения в тайм-аут? Вы пытались увеличить задержку тайм-аута? - person tilleryj; 16.03.2011

Ваш индекс массива i действительно доходит до третьего индекса?

Если вы вызываете свою функцию nextFrame(1) каждый раз... вы только передаете номер 1 в функцию каждый раз, когда вызываете функцию, или у вас есть 3 разных вызова функций с

следующий кадр (1) следующий кадр (2) следующий кадр (3)

кроме того, вы не объявили i как в var i = 0; Я бы сделал это... для этих целей ваш код был бы намного легче, если бы вы объявили i глобальным за пределами вашей функции nextFrame, а затем увеличивали его на 1 каждый раз, когда вызывается функция nextframe(). А затем загрузите нужный фильм на основе глобального i.

var i = 0;
function nextFrame(){
    loadSwf[i];
    i++;
}

затем вызовите функцию с

onclick="nextFrame()"
person Tim Joyce    schedule 15.03.2011
comment
Извините, я случайно упустил это из кода, который я разместил. У меня переменная i=0; объявленный над моими массивами. Каждый раз, когда я вызываю функцию, она использует nextFrame(1). У меня также есть кнопка «Назад», поэтому она использует nextFrame(-1). - person rlane423; 16.03.2011
comment
Итак, можете ли вы сказать нам, действительно ли вы добираетесь до третьего индекса вашего массива? - person Tim Joyce; 16.03.2011
comment
Да, он проходит через весь массив. - person rlane423; 16.03.2011

Я придумал решение, которое работает. Это может быть полный взлом, но он работает во всех браузерах, которые мне нужны.

Сначала я изменил способ обнаружения IE, как предложил @stealthyninja. Затем я решил попробовать полностью перезагрузить флэш-память, а не просто поменять местами имя файла swf. Первая флэш-память загружается с использованием метода динамической публикации swfobject.js. Таким же образом я перезагружаю последующие кадры. Я хотел использовать для этого innerHTML, но мне не понравилось, что я пытался вставить в него javascript. Поэтому я добавил пустой блок javascript в div содержимого флэш-памяти и использовал innerHTML для загрузки в него вызова swfobject. (Надеюсь, это имеет смысл и не является полностью обратным способом.) Ниже приведен код.

<script type="text/javascript">
var isIE =false;
</script>

<!--[if IE]>
<script type="text/javascript">
    isIE = true;
</script>
<![endif]-->

<script type="text/javascript">
    var flashvars = {};
    var params = {};
    params.play = "true";
    params.loop = "false";
    params.menu = "false";
    params.quality = "best";
    params.wmode = "window";
    params.bgcolor = "#FFFFFF";
    params.allowscriptaccess = "sameDomain";
    var attributes = {};
    attributes.align = "middle";
    swfobject.embedSWF("swf/frame_01.swf", "flashPlayer", "100%", "100%", "9.0.0", false, flashvars, params, attributes);

var i=0;
var swfFrame=new Array();
    swfFrame[0]='frame_01.swf';
    swfFrame[1]='frame_02.swf';
    swfFrame[2]='frame_03.swf';

var paragraphTxt=new Array();
    paragraphTxt[0]='caption 1';
    paragraphTxt[1]='caption 2';
    paragraphTxt[2]='caption 3';

function nextFrame(x){
i = i+x;
//alert("i+x = " + (i));
if(i>=swfFrame.length){
    i=i-1;
    window.open('quiz.html');
}else{
    document.getElementById("framenum").innerHTML = (i+1) + " of " + swfFrame.length;
    document.getElementById("paragraph").innerHTML = paragraphTxt[i];
    if(isIE){
        // IE
        document.getElementById("flashPlayer").movie = "swf/" + swfFrame[i];
    }else{
        document.getElementById("newScript").innerHTML = swfobject.embedSWF("swf/" + swfFrame[i],"flashPlayer","100%","100%","9.0.0",false,flashvars,params,attributes);
    }
}
if(i>0){
    document.getElementById("button_Bck").style.visibility = "visible";
}else{
    hideBack();
}
}

Div расположение Flash-контента с недавно добавленным блоком javascript:

<div id="flash">
    <script type="text/javascript" id="newScript">
    </script>
        <div id="flashPlayer">
        <a href="http://www.adobe.com/go/getflashplayer">
            <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" />
        </a>
        </div>
</div>
person rlane423    schedule 16.03.2011