Подтвердить что ты не робот

Sys.Application.add_load() vs. $(document).ready() vs. pageLoad()

У меня есть страница, на которой есть javascript, который нужно запускать при загрузке страницы. Указанный javascript должен найти клиентский компонент ServerControl, который он выполняет с помощью $find().

Конечно, если я испускаю свой код непосредственно на страницу, он выполняется, когда страница читается и терпит неудачу, потому что ничего не зависит от нее еще не инициализирована.

Если я поместил свой код внутри функции pageLoad(), он работает просто отлично, потому что asp.net автоматически подключает обработчик onload для любой функции с именем pageLoad(). Проблема в том, что мне действительно не нравится решение pageLoad() - главным образом потому, что это одно глобальное имя. Если я передаю некоторый код с помощью pageLoad(), я просто знаю, что какой-то другой программист собирается скопировать подход, где-то неуместным, и мы собираемся в конечном итоге со страницей, которая включает в себя две или более разные функции pageLoad() и результатом будет куча загадочных ошибок, которые будут навсегда отслежены.

Итак, я поместил свой код внутри анонимной функции, переданной в jquery $(document).ready(). Это не удается, поскольку оно выполняется до того, как клиентский компонент ServerControl существует.

Итак, я поместил свой код внутри анонимной функции, переданной Sys.Application.add_load(). Это также терпит неудачу, поскольку Sys undefined.

Итак, я наконец решил разместить свой код внутри Sys.Application.add_load(), а затем поместить его внутри функции, называемой $(document).ready(). Это работает, но оно дает почти такую ​​же изжогу, как pageLoad().

<script type="text/javascript">
    $(document).ready(function(){
        Sys.Application.add_load(function(){
            var component = $find(<clientid>);
            if (component) { <do something> }
        });
    });
</script>

Должен быть лучший способ справиться с этим.

Любые идеи?

4b9b3361

Ответ 1

Если у вас есть контроль над кодом, вы можете зарегистрировать JavaScript для запуска при запуске через что-то вроде:

this.Page.ClientScript.RegisterStartupScript(
    this.GetType(), 
    "StartupScript", 
    "Sys.Application.add_load(function() { functioncall(); });", 
    true);

Пока ваш компонент загружен через Sys.Application.add_init(), вы должны быть в порядке...

Ответ 2

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

pageLoad - отличный способ автоматически подключать AJAX-события, которые должны запускаться при каждой загрузке страницы (независимо от того, происходит ли эта загрузка с обратной кнопки на этой странице, перемотка вперед на страницу, обратный вызов AJAX, стандартная страница загрузка и т.д.), и поскольку вам не нужно беспокоиться о том, чтобы ScriptManager существовал в DOM, и он назван таким образом, который имеет смысл, по большей части (pageLoad и body.onload немного запутывают для не .NET-кодов, но для .NET-пользователя имеет смысл, что pageLoad запускает загрузку любой загрузки страницы, в том числе после обратных вызовов, так как поведение идентично для серверной стороны Page_Load). При этом ваши проблемы хороши - вам не нужны два экземпляра pageLoad на заданной странице, так как он сломается. Здесь прямое решение javascript, которое безопасно для ваших разработчиков для всех, позволяет использовать pageLoad, не беспокоится о существующей DOM, не обеспечивает кодовых конфликтов и прекрасно работает для нас.

В вашей основной библиотеке javascript определите pageLoad, а также вспомогательную функцию:

if (!pageLoad) { var pageLoad = function (sender, args) {}; };
if (!mylibrarynamespace) {var mylibrarynamespace = {};};
if (!mylibrarynamespace.registerStartupScript) mylibrarynamespace.registerStartupScript = function (fn) {
    /* create local pointer for added function */
    var f = fn;

    /* create pointer to existing pageLoad function */
    var pLoad = pageLoad;

    /* add new function pointer to pageLoad by creating new anonymous function (search Google for "javascript enclosures" for why pl and f will persist with this newly defined anonymous function) */
    pageLoad = function (sender, args) {
    pLoad(sender,args);
    f(sender, args);
    }
}

Затем, чтобы использовать его в любом месте вашего кода на стороне клиента, выполните следующие действия:

mylibrarynamespace.registerStartupScript(
    function (sender, args){ 
        /* do my AJAX always enabled startup code logic here*/
    }
);

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

Ответ 3

Я полагаю, что если вы добавите (или переместите) элемент управления ScriptManager над блоком script, вам не нужно будет обертывать его в функцию jQuery $(document).ready(). Таким образом, Sys будет доступен как ScriptManager:

вводит основную часть этого JavaScript в точное местоположение, в котором Элемент управления ScriptManager расположен на на странице. [http://encosia.com/2007/08/16/updated-your-webconfig-but-sys-is-still-undefined/]

Однако это решение может по-прежнему давать вам изжогу, поскольку для любого ничего не подозревающего разработчика не было бы очевидно, что на самом деле предоставляет ScriptManager.

Другой метод, когда ссылки script добавляются внутри ScriptManager (см. "Лучший способ", обсуждаемый в связанной статье выше), не так хорошо сочетается со мной, поскольку я не являюсь большим поклонником всего подхода ScriptManager.

Ответ 4

Попробуйте использовать ScriptManager для регистрации клиентского script блока, но дать уникальный заголовок для каждого вызова дополнительной функции, особенно если он имеет уникальные параметры, если вы используете одну и ту же функцию, но с разными значениями параметров. Если вы используете метод add_load, его следует использовать только тогда, когда загрузка страницы не является обратной записью, т.е. Вызывается только один раз после обновления страницы или загрузки страницы без обратной связи.

попробуйте это вместо:   ScriptManager.RegisterClientScriptBlock(это, GetType(), "уникальный заголовок", "alert (" быстрый тест ");", true);