Застрял на странной ошибке jQuery

Хорошо, вот мой код, он хранится во внешнем файле js и правильно включен в основной html в разделе заголовка.

$(document).ready(function(){
    var checkForConfirmation = function(){
    for(var i=0; i<myOrders.length; i++){
        $.ajax({
            type: "GET",
            url: "orderStatus.php",
            data: {action: 'get', id: myOrders[i]},
            success: function(data){
                if (data){
                    var reply = jQuery.parseJSON(data);
                    $("#fancyAlertLink").fancybox().trigger('click');
                    myOrders.splice(myOrders[i], 1);
                }
            }
        });
        if (myorders.length == 0){
            clearInterval(waitForRestourantInterval);
        }
    }
}
if (myOrders.length > 0){
    var waitForRestourantInterval = setInterval(function(){checkForConfirmation()}, 5000);
}
});

Как видите, я пытаюсь отобразить fancybox, когда внутренний скрипт ("orderStatus.php") получает правильные данные.

Все работает нормально, если я не использую jQuery (пример: window.alert вместо fancybox), но когда я пытаюсь использовать jQuery внутри этой функции, я получаю странную ошибку.

Firebug говорит, что в строке $("#fancyAlertLink").fancybox().trigger('click'); есть ошибка

Описания ошибки нет, просто "$("

Что я делаю не так???


Извини. Я знаю, что это не ответ, но я не могу все это комментировать. Вот "обновленный" код. Ошибка исчезла, но fancybox по-прежнему не запускается из моего скрипта.

EDIT: триггер не работает внутри функции успеха. Я попытался переместить его наружу, и он работает. Проблема в том, что мне действительно нужно это внутри успеха. Я попытался переместить вызов триггера в отдельную функцию и вызвать функцию из успеха, но тот же результат. Не работает! Какие-либо предложения?

подтверждениеDaemon.js

$(document).ready(function(){
var checkForConfirmation = function(){
    for(var i=0; i<myOrders.length; i++){
        $.ajax({
            type: "GET",
            url: "orderStatus.php",
            data: {action: "get", id: myOrders[i]},
            context: i,
            success: function(data){
                if(data!="null"){
                    var reply = jQuery.parseJSON(data);
                    $("#fancyAlertLink").trigger("click");
                    myOrders.splice(this, 1);
                }
            }
        });
        if (myOrders.length == 0){
            clearInterval(waitForRestourantInterval);
        }
    }
}
if (myOrders.length>0){
    var waitForRestourantInterval = setInterval(function(){checkForConfirmation()}, 5000);
}
});

основной html-файл: (smarty+html, теги smarty {literal} игнорируются в этом посте)

<html>
    <head>
        <script src="jquery-1.4.4.min.js" type="text/javascript"></script>
        <script src="fancyBox/jquery.fancybox-1.3.4.pack.js" type="text/javascript"></script>
        <link rel="stylesheet" href="fancybox/jquery.fancybox-1.3.4.css" type="text/css" media="screen" />
        <script type="text/javascript">
            var myOrders = new Array();
            {foreach from=$smarty.session.my_orders item=id}
                myOrders.push({$id}):
            {/foreach}
        </script>
        <script type="text/javascript">
            $(document).ready(function{
                $("#fancyAlertLink").fancybox();
            });
        </script>
        <script src="confirmationDaemon.js" type="text/javascript"></script>
    </head>
    <body>
        --- some content here ---
        <a id="fancyAlertLink" href="#fancyAlert">Show fancy</a>
        <div style="display:none">
            <div id="fancyAlert">Fancybox hell yeah!!!</div>
        </div>
    </body>
</html>

Установка интервалов и AJAX работают должным образом. Fancybox отображается, когда я нажимаю ссылку «Показать фантазии». Но он не запускается из внешнего js. Я отладил это. Он должен работать, он выполняет эту строку, но ничего не появляется


person ZolaKt    schedule 17.02.2011    source источник
comment
кажется, что эта строка недействительна ($(#fancyAlertLink).fancybox().trigger('click');) что это вообще должно делать?   -  person corroded    schedule 17.02.2011
comment
@guildsbounty это абсолютно не так. В этой строке кода нет ничего плохого.   -  person Pointy    schedule 17.02.2011
comment
Что, если вы вызовете $(#fancyAlertLink).fancybox().trigger('click') из командной строки firebug? Что, если вы сделаете что-то с функцией $, которая не вызывает .fancybox()?   -  person jd.    schedule 17.02.2011
comment
Вот как вы открываете модальное окно fancybox, имитируя щелчок, и оно выглядит нормально, что, если вы удалите строку над ним?   -  person picus    schedule 17.02.2011
comment
@ZolaKt, можете ли вы опубликовать, как выглядит ответ JSON?   -  person Pointy    schedule 17.02.2011
comment
@guildsbounty Я не думаю, что проблема в двойных кавычках. Я использовал их в других скриптах, и все они работают нормально @corroded. Предполагается, что плагин fancybox свяжется с #fancyAlertLink (якорная ссылка) и вызовет событие ссылок onclick.   -  person ZolaKt    schedule 17.02.2011
comment
Цитирование не должно быть проблемой; Вы загружаете Fancybox после jQuery на своей странице?   -  person AlG    schedule 17.02.2011
comment
Ответ @Pointy JSON - это просто закодированный пользовательский объект, не очень важный. Если я полностью удалю эту строку, упомянутая проблема все еще существует   -  person ZolaKt    schedule 17.02.2011
comment
@ qor72 Да, я загружаю fancybox после jQuery. В основном html файле   -  person ZolaKt    schedule 17.02.2011


Ответы (3)


Вот одна проблема, с которой вы столкнетесь: когда вы устанавливаете эти вызовы AJAX внутри цикла for, код в обработчике успеха ссылается на переменную i, которая используется для итераций цикла. Это будет большой проблемой, потому что все функции будут ссылаться на одну и ту же переменную "i". Таким образом, когда функции действительно вызываются асинхронно после выполнения HTTP-запросов, все они увидят одно и то же значение «i» (которое будет последним значением «i», которое было при выполнении цикла). .

Чтобы обойти эту проблему, настройте обработчики «успеха» немного по-другому:

        success: (function(i) {
          return function(data) {
            if (data){
                var reply = jQuery.parseJSON(data);
                $("#fancyAlertLink").fancybox().trigger('click');
                myOrders.splice(myOrders[i], 1);
            }
          };
        })(i)

Это гарантирует, что каждый отдельный обработчик будет иметь собственную копию «i» и копию с правильным значением.

person Pointy    schedule 17.02.2011

EDIT: Вероятно, есть несколько проблем.

  • Вы передаете myOrders[i] в .splice(). Я предполагаю, что он не содержит порядковый номер, как требует .splice().

  • Значение проблемы i описано ниже.

  • Даже если эти две проблемы решены, у вас все еще есть проблема, потому что .splice() модифицирует массив, поэтому любой номер индекса выше того, который использовался в соединении, устарел, потому что ваш .splice() удаляет элементы из массива.


Ты делаешь:

myOrders.splice(myOrders[i], 1);

в обратном вызове success: для асинхронного вызова AJAX. К моменту срабатывания этого кода i будет тем же значением, что и length, поэтому в этом индексе нет элемента.

Другими словами, последний элемент — length - 1, но i == length значит myOrders[i] == undefined.

Одно простое и эффективное решение — установить myOrders[i] в качестве параметра context вызова AJAX.

    $.ajax({
        type: "GET",
        url: "orderStatus.php",
        context: myOrders[i],

Затем в обратном вызове success: this будет ссылаться на этот элемент.

       success: function(data){
            if (data){
                var reply = jQuery.parseJSON(data);
                $("#fancyAlertLink").fancybox().trigger('click');

                 //  -------------v-----references the proper item
                myOrders.splice( this, 1);
            }
        }
person user113716    schedule 17.02.2011
comment
хорошо спасибо. но я не думаю, что это вызывает ошибку. это не имеет ничего общего с jQuery. когда я делаю простой windows.alert, все работает - person ZolaKt; 17.02.2011
comment
@ZolaKt: Но когда/где вы предупреждаете? - person user113716; 17.02.2011
comment
@ZolaKt ну, нет абсолютно ничего плохого в том, чтобы поместить некоторые вызовы функций jQuery в подобную функцию-обработчик; в конце концов, это всего лишь код JavaScript. - person Pointy; 17.02.2011
comment
@patrick Я хочу отображать fancybox, когда внутренняя функция возвращает некоторые фактические значения, а не просто пустую строку. Это своего рода система уведомления о заказе - person ZolaKt; 17.02.2011
comment
@ZolaKt: Подожди. Каково значение myOrders[i]? Это порядковый номер? РЕДАКТИРОВАТЬ: ... splice() требует индекса для первого параметра. Что ты его проходишь? - person user113716; 17.02.2011
comment
@patrick Это порядковый номер. Это копия переменной PHP $_SESSION, которая содержит массив идентификаторов активных ордеров. - person ZolaKt; 17.02.2011
comment
@ZolaKt: Да, но относится ли этот порядковый номер к порядковым номерам массива myOrders? - person user113716; 17.02.2011
comment
@parick Нет, это не так. myOrders[i] — значение идентификатора заказа. к массиву отношения не имеет - person ZolaKt; 17.02.2011
comment
@ZolaKt: Тогда это бесполезно для .splice(). Попробуйте просто полностью удалить эту строку и посмотрите, станет ли она лучше для вас. - person user113716; 17.02.2011
comment
@патрик Ты прав. Я изменил контекст на i вместо myOrders[i]. Таймер и отмена работают нормально, но fancybox по-прежнему не срабатывает. - person ZolaKt; 17.02.2011
comment
@ZolaKt: я мало что знаю о fancybox, но кажется, что метод .fancybox() используется для создания галереи. Здесь вы пытаетесь воссоздать его с каждым возвращаемым ответом. Я думаю, вы, возможно, просто хотите $("#fancyAlertLink").click();, хотя вы все еще инициируете щелчок несколько раз. - person user113716; 17.02.2011

попробуйте вызвать щелчок по элементу, например $('#fancyAlertLink').trigger('click');

person matei    schedule 17.02.2011
comment
если я уберу весь fancybox() и вызову только элемент, ошибок не будет, но и поведения не будет - person ZolaKt; 17.02.2011
comment
вы должны вызывать $('#fancyAlertLink').fancybox() при загрузке страницы. после этого вы можете запустить его, как я сказал в ответе, но см. ответы Пойнти и Патрика Д.В. о проблеме i - person matei; 17.02.2011
comment
@matei Я пробовал это. Нет ошибок. Но он не запускается из внешнего скрипта. Могу ли я использовать live() с триггером()? - person ZolaKt; 17.02.2011
comment
Я объединил ваш метод и метод Патрика, и интервалы и ajax работают нормально. Но fancybox по-прежнему не срабатывает. Теперь я получаю это предупреждение в элементе firebug, на который ссылается ID/NAME в глобальной области. Вместо этого используйте стандартный документ W3C.getElementById(). - person ZolaKt; 17.02.2011
comment
Можете ли вы опубликовать обновленный код и соответствующий HTML? (элемент #fancyAlertLink) - person matei; 17.02.2011
comment
код мой новый ответ. не смог все вместить в комментарий - person ZolaKt; 17.02.2011