Событие готовности AJAX после загрузки HTML-страницы и скриптов

Я создаю веб-приложение с несколькими страницами контента, которые я загружаю динамически с помощью AJAX и API истории HTML5. Когда пользователь пытается изменить страницу, новый контент загружается с помощью $.get и внедряется в тело, например:

$.get("somepage.html", function (data)
{
    $("body").html(data);
});

Для большинства этих страниц требуется загрузка дополнительных скриптов. Это не было бы проблемой, если бы не тот факт, что $(document).ready срабатывает до загрузки этих скриптов. Somepage.html выглядит примерно так.

<script src='http://getjquerysomewhere/'></script>
<script src='my_script_that_depends_on_jQuery'></script>

Этот вопрос осложняется тем, что эти страницы должны иметь возможность загружаться самостоятельно. Поэтому я не уверен, как я могу исключить функции $(document).ready, не влияя при этом и на это поведение.

Как мне подойти к этой проблеме?


person Jack Guy    schedule 22.12.2014    source источник
comment
Вы можете использовать Promise.   -  person Gaurav Kalyan    schedule 23.12.2014
comment
Это выглядит потрясающе. Жаль, что пока нет широкой поддержки.   -  person Jack Guy    schedule 23.12.2014
comment
Существует несколько библиотек, реализующих интерфейс Promise.   -  person Kevin B    schedule 23.12.2014
comment
Мне кажется, что вам нужна структура внедрения зависимостей, или вам нужно просто загрузить весь код заранее.   -  person Kevin B    schedule 23.12.2014
comment
Я думал сделать позже. Что касается фреймворка, можете ли вы что-нибудь порекомендовать?   -  person Jack Guy    schedule 23.12.2014
comment
Я предполагаю, что вы имеете в виду прежний, например, инъекцию зависимости? Я использовал require.js в прошлом, похоже, он неплохо справлялся со своей задачей. Я не слишком знаком с тем, что доступно сейчас, потому что у меня не было потребности в этом некоторое время. Я обычно загружаю большую часть своего кода для приложений, и мои сайты используют очень мало js.   -  person Kevin B    schedule 23.12.2014
comment
Я хотел сказать, что рассматривал возможность загрузки всего кода заранее. Однако я проверю require.js. Я предполагаю, что в контексте онлайн-веб-приложения/игры мои пользователи будут ожидать некоторой загрузки. Как вы думаете, будет ли проблемой загрузить все мои сценарии заранее? Это составляет не более 20 килобайт в минимизированном виде.   -  person Jack Guy    schedule 23.12.2014
comment
Я не думаю, что 20 КБ так сильно повлияют на время загрузки.   -  person Kevin B    schedule 23.12.2014
comment
Когда вы извлекаете somepage.html с помощью $.get, это только часть (например, <div>lots of content</div> или целая страница?   -  person Matijs    schedule 23.12.2014
comment
Это целая страница @Matijs.   -  person Jack Guy    schedule 23.12.2014
comment
Почему ты бы так поступил? У вас уже есть страница. Звучит для меня, вам нужно только частичное. Страница, на которую вы помещаете свой фрагмент, должна иметь JavaScript, независимо от того, через RequireJS или все за один раз.   -  person Matijs    schedule 23.12.2014
comment
Некоторые страницы загружаются частично, а другие нет (в данном случае это целая страница). Для согласованности я использую History для взаимодействия со всеми ними. Если кто-то хочет порекомендовать внедрение зависимостей или все в одном в ответе, я с радостью приму это. :)   -  person Jack Guy    schedule 23.12.2014
comment
Я стараюсь избегать загрузки скриптов в html, потому что тогда вам придется иметь дело с удалением ссылок на библиотеки/плагины, которые уже включены. В этот момент все становится очень сложным. Например, демонстрационный HTML-код, который вы включили, содержит ссылку на jquery.js. это должно быть удалено, прежде чем вы сможете скомпилировать элементы вниз по узлам dom, что можно сделать только с помощью манипуляций со строками. Если вы проанализируете его с помощью jQuery, он выполнит сценарии до того, как вы сможете их удалить, тем самым лишив возможности загрузки страниц с помощью ajax.   -  person Kevin B    schedule 23.12.2014
comment
Звучит так, будто RequireJS — это ответ для меня!   -  person Jack Guy    schedule 23.12.2014


Ответы (2)


То, что вы пытаетесь сделать, безусловно, возможно, но в долгосрочной перспективе это будет не очень удобно.

Одна из самых больших проблем, с которой вы столкнетесь, — это правильная вставка кода из загруженного ajax html в текущую страницу. Вы не можете просто проигнорировать это и позволить всему этому работать, потому что тогда вы будете включать библиотеки несколько раз (в результате чего плагины будут перезаписаны/удалены), а код для загружаемой страницы может произойти слишком рано из-за того, что dom уже быть готовым.

Это в значительной степени оставляет вам два варианта: внедрение зависимостей или предварительная загрузка.

Внедрение зависимостей, вероятно, будет для вас самым простым из двух способов реализации, поскольку он требует наименьшего количества изменений в вашей текущей кодовой базе. Все, что вам нужно сделать, это убедиться, что все страницы, запрошенные с помощью ajax, включают только содержимое <body> (что можно сделать с помощью кода на стороне сервера) и убедиться, что весь код, специфичный для страницы, включен до закрытия </body> каждой страницы. . Тогда вам просто нужно будет использовать методы внедрения зависимостей для запуска вашего кода с правильными зависимостями.

Вы также можете включить только <div id="#content">...</div> для ваших частей, что когда-либо имеет больше смысла для вашего варианта использования.

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

person Kevin B    schedule 22.12.2014

Вы можете вызывать функции из оригинальных скриптов на странице, которую вы загрузили. Например, вы можете сделать это в своем основном:

<script>
    function ExternalScriptLoaded(){}
</script>

Затем на вашей внешней странице:

<script>
    try{ ExternalScriptLoaded(); }catch(err){alert('This page was not loaded with ajax because i can't find the function');}
</script>

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

person Zze    schedule 22.12.2014
comment
Если я вызываю функцию, основанную на внедренном файле скрипта, который, как я не уверен, загрузился, как я узнаю, что он будет вызван в подходящее время? - person Jack Guy; 23.12.2014
comment
Вот что задает мой первоначальный вопрос. Надеюсь, мои правки прояснят ситуацию. - person Jack Guy; 23.12.2014
comment
Вы создали файл сценария, который вводится? Если это так, document.ready сработает внутри этого, а затем, когда он закончит разрешение, выполните попытку catch. В противном случае вы можете использовать .done и вызвать его там? - person Zze; 23.12.2014
comment
Первое я не создавал, а второе делал, но это зависит от первого. - person Jack Guy; 23.12.2014
comment
Так что технически вы должны знать, когда разрешится второй сценарий, поскольку первый является обязательным условием. Затем вы можете просто сделать попытку поймать, когда будете готовы. - person Zze; 23.12.2014
comment
И вы узнаете об этом, потому что функция $(document).ready сработает, как только она будет создана на странице. - person Zze; 23.12.2014