продолжайте пробовать функцию, пока не будет загружен требуемый элемент DOM

#javascript #jquery #ajax

#javascript #jquery #ajax

Вопрос:

Я загружаю другую страницу в el via XHR . На загруженной странице есть js, который выдает ошибку и завершается сбоем, если на странице не загружен требуемый элемент dom. Поскольку это XHR .ready и др. не будет работать.

У меня это работает с таймаутом 500 мс, но это не нормально; должен быть лучший способ. При тайм-ауте элемент dom не всегда загружается, и страница завершается с ошибкой.

На странице есть жестко запрограммированная таблица с id . Скрипт на странице является плагином jquery (datatables) и не будет инициализирован, пока не будет загружена таблица.

Я думал о том, чтобы иметь функцию, которая вводит данные в таблицы данных, и вызывать ее повторно while $('#tableID') null , но не уверен, что это правильно.

 <div id="contactQueue">
<table cellpadding="0" cellspacing="0" border="0" class="display" id="contactsQueueTable">
    <thead>
        <tr>
            <th class="" rowspan="1" colspan="1" style="width: 185px; ">Contact Name</th>
            <th class="" rowspan="1" colspan="1" style="width: 148px; ">Bus. Name</th>
            <th class="" rowspan="1" colspan="1" style="width: 116px; ">Is Client</th>
            <th class="" rowspan="1" colspan="1" style="width: 165px; ">Remove</th>
        </tr>
    </thead>
    <tbody>
    </tbody>
</table>
</div>
<?php echo form_open('',array('id'=>'step2form','name'=>'step2form'));?>
<input type="hidden" name="clientID" value="<?php echo $clientID; ?>">
<?php echo form_close();?>


<script type="text/javascript" charset="utf-8">
console.log(jq('#currentContactsTable'))
while(jq('#currentContactsTable').html()==null){
    initXHRPage();
    console.log(jq('#currentContactsTable') ' not ready');
}
function initXHRPage(){
    //init tables stuffs
}
  

Редактировать;

Проблема была в чем-то другом, вроде. Скрипт для таблиц данных загружается через getScript() . Элемент загружался нормально, но initDatatables() запускался до getScript() завершения загрузки, а не до загрузки el.

Решение состояло в том, чтобы вызвать initDatatables() функцию при getScript() успешном обратном вызове:

 <script type="text/javascript" charset="utf-8">
var jsf = '/js/jquery.dataTables.js';
jq.getScript(jsf, function(data, textStatus){
    console.log('Loaded:' jsf " From: <?php echo $this->uri->uri_string(); ?>");
    initDatatable();
});
</script>
  

Ответ №1:

Вы пробовали $(el).ready(...) ? Это, безусловно, должно сработать. Если это не так, что-то еще идет не так.


Редактировать

Извините, это должно было быть $("#your_xhr_loaded_content").ready()... .

Я все время делаю такие вещи, и это работает, я думаю, ключ в том, что я загружаю документ.

Основной HTML-документ, index.html:

     ...
    <body>
        ...
        <div id="activity_content">
        </div>
        ...
        <script type="text/javascript" src="js/jquery-1.6.4.min.js"></script>
        <script type="text/javascript" src="js/main.js"></script>
    </body>
</html>
  

main.js:

 ...

function ruleManagement.loadContent() {
    $.ajax({
        url: "subdocs/ruleMgmt.html",
            cache: false,
            success: function(html) {
                $("#activity_content").html(html);
            }
    }
}

ruleManagement.onReady = function(event) {
    // Init contents of the rule_management_pane
    ...
}
  

Вложенный документ HTML, ruleMgmt.html

 <div id="rule_management_pane">
    <!-- Content here -->
    ...
</div>
<script type="text/javascript" language="JavaScript">
    jQuery("#rule_management_pane").ready(ruleManagement.onReady);
</script>
  

Если я вызываю ruleManagement.loadContent() , то ruleManagement.onReady() вызывается после успешной загрузки div#rule_management_pane . Я не могу с уверенностью сказать, что onReady вызывается до того, как div#rule_management_pane вставляется в #activity_content, но я думаю, что это так.

Комментарии:

1. Состояния документации .ready() могут использоваться только в документе: Метод .ready() может быть вызван только для объекта jQuery, соответствующего текущему документу, поэтому селектор можно опустить. Так $(el).ready(...) действительно?

2. Однако это не работает. Страница загружается, что el не готов, поэтому ready(function(){//blah не запускается. если я заменю el.ready на setTimeout 500, это сработает.

3. По какой-то причине он все еще не работает. Я не думаю, что это такая большая проблема с XHR; страница загружается через XHR, но данные с таблицами данных — нет; это метод, вызываемый в el, который создает таблицу. В DTBLS есть XHR, но это тоже не проблема. Проблема в том, что страница загружена, скрипт на странице (таблицы данных инициализации) запускается до того, как элементы на указанной странице будут отображены / созданы, и он останавливается, потому что el там нет. выполнение jq('#currentContactsTable').ready(function(){initDatatables();}) не работает: Uncaught TypeError: Object [object Object] has no method 'dataTable' спасибо

Ответ №2:

насколько я понимаю, загружается ваш html / js:

  • ContainerPage —> $.get(/ajax/getMiddlePage.php )
  • средняя страница XHR —> $.get(/ajax/getContactQueue.php )
  • средняя страница XHR —> $.get(/ajax/getCurrentContactsTable.php )

Грубо. хорошо, вот что, я думаю, вам нужно:

 <html>
<!---CONTAINER PAGE--->
<head>
    <script type="text/javascript">
    //this .ready is to register events we need to catch the '#currentContactsTable' load event
    $(document).ready(function(){
    //ajaxSuccess is a global ajax function, you need to check ajaxOptions object to ensure you have the correct 'ajaxSuccess' you thought you did.
      $.ajaxSuccess(function(event, XMLHttpRequest, ajaxOptions){
        if (ajaxOptions.url == '/ajax/getCurrentContactsTable.php') {
          $('#currentContactsTable').trigger('initDataTables');
        }
      });
// .live() does not need the element to exist on document.ready()
      $('#currentContactsTable').live('initDataTables', function(event){
          var dataTables = $(this).datatables({options:here});
      });
    });
    </script>
</head>
<body></body>
</html>
  

Комментарии:

1. однако я нахожусь вдали от среды разработки, чтобы запустить это, однако комбинация .live () и глобального события ajaxSuccess или ajaxComplete jquery — это путь, по которому я бы пошел для решения

2. Может быть, я просто плотный, но как это решит проблему? Сама страница загружается из запроса XHR, и я попытался выполнить инициализацию данных при ее завершенном обратном вызове с той же проблемой. Ваше решение проверяет успешность XHR вызова страницы с данными, верно? Спасибо.

3. этот javascript находится на «странице контейнера». XHR загружается в некоторую «страницу контейнера». Даже если вся «страница контейнера», получающая новое содержимое, полностью переписывается, document.ready() по-прежнему сохраняется для исходного DOM.

4. Действительно, грубо. Это приложение, похожее на настольный компьютер (MochaUI), поэтому в нем много XHR. Эта страница Desktop-> XHR-> Page2-> XHR-> ContactsPage; это похоже на НАЧАЛО, но с лучшим сюжетом. Как вы сказали, live() не требуется, чтобы el существовал, но Datatables существует. Вот в чем действительно заключалась проблема — datatables инициализировались до создания его div и отказывались, потому что div не существовал. Я думаю, что ready не работает именно потому, что, как вы сказали, OG .ready() для документа (index.php или что-то еще) является истинным, и любой документ.ready на любых страницах XHR см. .ready()==true из index.php и не стреляйте. Спасибо за ответ.

Ответ №3:

Это то, что я придумал. Спасибо респондентам за помощь.

 initPage();

function initPage(){
    if(jq('#currentContactsTable').length==1){
            initDatatable();
    }else{
            window.setTimeout(function(){
                    initPage();
            },250);
    }
}

function initDatatable(){
    jq('#currentContactsTable').dataTable( {
            //REST OF DATATABLE STUFF...
  

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


^^^^ BZZZZZZZZZ

Проблема была в чем-то другом, вроде. Скрипт для таблиц данных загружается через getScript(). Элемент загружался нормально, но функция initDatatables() запускалась до завершения загрузки getScript(), а не до загрузки el.

Решением было вызвать функцию initDatatables() в успешном обратном вызове getScript():

 <script type="text/javascript" charset="utf-8">
var jsf = '/js/jquery.dataTables.js';
jq.getScript(jsf, function(data, textStatus){
    console.log('Loaded:' jsf " From: <?php echo $this->uri->uri_string(); ?>");
    initDatatable();
});
</script>