Как использовать AJAX в качестве альтернативы iframe - PullRequest
0 голосов
/ 18 февраля 2012

Я пытаюсь собрать быстрое веб-приложение, используя JS, Prototype и AJAX для всех моих запросов после загрузки графического интерфейса. Приложение простое: набор ссылок и элемент контейнера для отображения того, на что указывают ссылки, как в iframe. Вот примерный HTML-фрагмент:

<a class="ajax" href="/somearticle.html">An article</a>
<a class="ajax" href="/anotherarticle.html">Another article</a>
<a class="ajax" href="/someform.html">Some form</a>
<div id="ajax-container"></div>

JS, который сопровождает вышесказанное (извините, он немного длинен) выглядит так:

document.observe('dom:loaded', function(event) {
    ajaxifyLinks(document.documentElement);
    ajaxifyForms(document.documentElement);
});

function ajaxifyLinks(container) {
    container.select('a.ajax').each(function(link) {
        link.observe('click', function(event) {
            event.stop();
            new Ajax.Updater($('ajax-container'), link.href, {
                method: 'get',
                onSuccess: function(transport) {
                    // Make sure new ajax-able elements are ajaxified
                    ajaxifyLinks(container);
                    ajaxifyForms(container);
                }
            });
        });
    });
}

function ajaxifyForms(container) {
    console.debug('Notice me');
    container.select('form.ajax').each(function(form) {
        form.observe('submit', function(event) {
            event.stop();
            form.request({
                onSuccess: function(transport) {
                    $('ajax-container').update(transport.responseText);
                    // Make sure new ajax-able elements are ajaxified
                    ajaxifyLinks(container);
                    ajaxifyForms(container);
                }
            });
        });
    });
}

При нажатии на ссылку ответ отображается в контейнере. Я не использую здесь iframe для контейнера, потому что я хочу, чтобы все элементы на странице могли взаимодействовать друг с другом через JS в какой-то момент. Теперь есть одна большая проблема и одно любопытное явление:

Проблема: если форма возвращается и отображается в контейнере, JS выше пытается применить то же поведение к форме, чтобы любой ответ, полученный после отправки, отображался в контейнере. Это не удается, так как событие submit никогда не перехватывается. Зачем? Обратите внимание, что все возвращаемые элементы формы имеют атрибут class = "ajax".

Феномен: обратите внимание на оператор console.debug () в ajaxifyForms (). Я ожидаю, что он будет выводиться на консоль один раз после загрузки страницы, а затем каждый раз, когда контейнер обновляется с помощью формы. Правда состоит в том, что число выходов на консоль удваивается при каждом нажатии на ссылку, указывающую на форму. Почему?

1 Ответ

0 голосов
/ 19 февраля 2012

Я нашел другой способ добиться того, чего хотел. На самом деле, код для этого меньше и менее подвержен ошибкам. Вместо того, чтобы пытаться убедиться, что каждая ссылка и элемент формы на странице наблюдаются в любой момент времени, я использую всплывающее событие и слушаю только сам документ. Изучая каждое событие, которое к нему относится, я могу определить, является ли оно объектом для запроса AJAX или нет. Вот новый JS:

document.observe('submit', function(event) {
    if (event.target.hasClassName('ajax')) {
        event.stop();
        event.target.request({
            onSuccess: function(transport) {
                $('ajax-container').update(transport.responseText);
            }
        });
    }
});

document.observe('click', function(event) {
    if (event.target.hasClassName('ajax')) {
        event.stop();
        new Ajax.Updater($('ajax-container'), event.target.href, {
            method: 'get'
        });
    }
});

Работает как шарм:)

...