Выполнение скрипта на странице, загруженной через AJAX?

Доброе время суток.



Возможно, вопрос поднимался и уже не раз, но нагуглить решение я так и не смог.



Ситуация следующая: есть небольшая корпоративная система, которая написана с использованием самописного php движка и библиотеки jQuery для фронтенда. Сейчас добавляю аяксовость к имеющейся функциональности и столкнулся с проблемой. В теле страницы есть блоки javascript-ового кода, вроде



<script><br>
    jQuery(document).ready(function(){<br>
       jQuery("#birth_date").datepicker({<br>
            dateFormat: "dd.mm.yy",<br>
            showOn: "both",<br>
            buttonImage: "{$web_root}css/_core/jUI/images/calendar.gif",<br>
            buttonImageOnly: true,<br>
            changeYear: true<br>
        });<br>
        jQuery("#tabs").tabs();<br>
        jQuery("#tabs-secondary").tabs();<br>
    });<br>
</script><br>




Если страница загружается по прямой ссылке, то код исполняется и проблем нет, если страница загружается через ajax, то этого кода в теле страницы вообще нет.



Навешивает аяксовость простой jQ код:



(function($){<br>
    function asuAjax(params){<br>
        this._doc = null;<br>
<br>
        _initCenter = function(doc){<br>
            var links = jQuery(doc).find("div.asu_center_container").find("a");<br>
            for (var i = 0; i < links.length; i++) {<br>
                jQuery(links[i]).on("click", {parentObj: this}, function(event){<br>
                    event.data.parentObj._showOverlay();<br>
                    jQuery.ajax(this.href, {<br>
                        cache: false,<br>
                        dataType: "html",<br>
                        complete: event.data.parentObj._linkAjaxComplete,<br>
                        success: event.data.parentObj._linkAjaxSuccess,<br>
                        parentObj: event.data.parentObj<br>
                    });<br>
                    return false;<br>
                });<br>
            }<br>
        };<br>
<br>
        /**<br>
         * После выполнения запроса<br>
         * @private<br>
         */<br>
        _linkAjaxComplete = function() {<br>
            this.parentObj._hideOverlay();<br>
        };<br>
<br>
        /**<br>
         * Загрузка содержимого<br>
         * @private<br>
         */<br>
        _linkAjaxSuccess = function(doc){<br>
            var body = jQuery(doc).find("div.asu_center");<br>
            /**<br>
             * Если это не страница с новым дизайном, то просто редирект<br>
             */<br>
            if (body.length == 0) {<br>
                window.location.href = this.url;<br>
                return true<br>
            }<br>
            /**<br>
             * Выполняем замену содержимого текущей страницы<br>
             */<br>
            var oldDoc = jQuery("div.asu_center");<br>
            jQuery(oldDoc).html(jQuery(doc).find("div.asu_center").html());<br>
            /**<br>
             * Замена пунктов меню справа<br>
             */<br>
            var oldRight = jQuery("div.asu_right");<br>
            jQuery(oldRight).replaceWith(jQuery(doc).find("div.asu_right"));<br>
            /**<br>
             * Запускаем парсер для загруженной страницы<br>
             */<br>
            this.parentObj._initCenter(jQuery(document));<br>
            /**<br>
             * Меняем url в окне<br>
             */<br>
            window.history.pushState("data", "title", this.url);<br>
            window.history.replaceState("data", "title", this.url);<br>
        };<br>
<br>
        _hideOverlay = function(){<br>
            var overlay = this._getOverlay();<br>
            jQuery(overlay).css("display", "none");<br>
        };<br>
<br>
        _showOverlay = function(){<br>
            var overlay = this._getOverlay();<br>
            jQuery(overlay).css("display", "block");<br>
        };<br>
<br>
        _getOverlay = function(){<br>
            this._overlay = jQuery("#overlay")<br>
            if (this._overlay.length == 0) {<br>
                this._overlay = jQuery('<div id="overlay"></div>');<br>
                this._overlay.appendTo(document.body)<br>
            }<br>
            return this._overlay;<br>
        };<br>
<br>
        __construct = function(doc){<br>
            /**<br>
             * Инициализируем ссылки в документе<br>
             */<br>
            this._initCenter(doc);<br>
        }(params);<br>
    }<br>
<br>
    $.fn.asuAjax = function(){<br>
        var ajax = new asuAjax(this[0]);<br>
    }<br>
}(jQuery));<br>
/**<br>
 * Основной код, которые запускает все преобразование<br>
 */<br>
jQuery(document).ready(function(){<br>
    jQuery(document).asuAjax();<br>
});<br>




Т.е. страница загружается с сервера целиком, а обновляется в браузере только два блока. В этих блоках javascript точно есть, он жестко в шаблоне, по которому генерится страница прописан, но потом он куда-то пропадает.



Заметил особенность, есть загрузить страницу целиком через jQuery.load(), то скрипты отрабатывают, если загрузить только часть, например jQuery.load(url + " #container"), то скрипты, из #container также не отрабатывают.



Подскажите, в какую сторону копать.
  • Вопрос задан
  • 23673 просмотра
Пригласить эксперта
Ответы на вопрос 5
timokhin
@timokhin
iOS developer
В _linkAjaxComplete:
eval($("script", doc).text());
Ответ написан
ogregor
@ogregor
арендатор vpn сервера debian
Только что у себя решил такую же задачку:

$("#images").load(location.href+" #images",function(){
$.getScript("js/productHelper.js");
});

Подгрузил скрипт как написано.
Ответ написан
Комментировать
Slavenin999
@Slavenin999
программист php/erlang/elixir/js
если мне нужно, чтобы выполнились какие-то скрипты, то я обычно выношу их в отдельные функции, и в success их вызываю. Чтобы они всегда были на странице еще и в отдельные файлы выделяю.
Ответ написан
estum
@estum
Перемудрил с asuAjax — это не тут случай где нужны объекты. Ну и вообще, на мой взгляд много лишнего и есть косяки. Например, хватило бы один раз вызвать $(".asu_center_container a").on('click', function(e){… }) — событие будет вешаться и на новые элементы с этим селектором.

Что касается самого вопроса: если по-хорошему, я бы не использовал встроенный js в теле страницы. Если по-плохому, то в инлайн-блоках вместо $(document).ready(… ) можно обернуть в $(document).one('mynamespace.loaded', ...) и вызывать $(document).trigger('mynamespace.loaded') когда готово, но, повторюсь, я бы так делать не стал.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы