Вопрос по html, ajax, jquery – Заставить функцию jquery .on работать с загруженным контентом AJAX

23

У меня возникают проблемы при получении .on 'click & apos; функция для работы с загруженным контентом AJAX.

Я работал с jquery .live раньше, но это первый раз с .on и понимаю, что он работает точно так же, поэтому не знаю, почему у меня проблемы.

Ниже приведен HTML-код, который дает элемент, на который вы нажимаете

    <h1>Press &amp; Media</h1>
    <div id="back"></div>
    <div id="overlay-content">
        <span id="edocs" class="tab"></span>
        <span id="news" class="tab"></span>
        <span id="partners" class="tab"></span>
    </div>

Ниже приведена функция, которая загружает содержимое AJAX.

    $("#overlay-content").on('click','#news',function() {
        var active = 1;
        $("#loading").show();
        $("#overlay-content").fadeOut(1000, function() {
            $.get("http://<? echo ROOT; ?>includes/functions.php", { pressmediaNews: active }, function(data) {
                $("#loading").hide(400);
                $("#overlay-content").empty().append(data).fadeIn(1000);
            });
        });
    });

Это должно загрузить следующий HTML

    <div id="news-left-panel">
        <h4>News Section</h4>
        <ul>
            <li id="newsID2" class="newsYear">
                <p>2012</p>
                <ul class="newsMonths" style="display:none">
                    <li>Jan
                        <ul class="newsArticles" style="display:none">
                            <li onClick="newsID(2)">test</li>
                        </ul>
                    </li>
                    <li>Feb</li>
                    <li>Mar</li>
                </ul>
            </li>
            <li id="newsID1" class="newsYear">
                <p>2011</p>
                <ul class="newsMonths" style="display:none">
                    <li>Dec
                        <ul class="newsArticles" style="display:none">
                            <li onClick="newsID(1)">Test</li>
                        </ul>
                    </li>
                </ul>
            </li>
        </ul>
    </div>

Теперь вышеприведенный код просто не будет выполняться, покажет любые ошибки и так далее в firebug.

Поэтому я немного растерялся из-за того, почему он не будет выполнен, alert () даже не будет выполнен.

Важное примечание: вам понадобится jQuery 1.7.0 или выше, поэтому, если вы используете более старую версию, она не сможет работать. bodi0
У вас есть онлайн пример этого? Я реализовал ваш код именно локально, и он, кажется, работает как надо.milliamp.org/test/10416689 (#news - синяя рамка) Alex Taylor
отредактировал оригинальное сообщение, чтобы отразить ваш запрос. zealisreal
Как выглядит HTML-элемент контейнера, в который вы вставляете свой динамический контент? Erik Philips
Судя по вопросу и ответам, кажется, что мы упускаем что-то еще в деталях вашего вопроса или точной ситуации. Возможно, кросс-доменная проблема? Является ли ваш сайт https, и он использует http? Нет содержимого на вкладке & quot; #Новости, чтобы щелкнуть показано здесь. Можете ли вы воспроизвести в тестовой среде? Я думаю, что нам нужно знать, какую часть этого нам не хватает, что необходимо знать. Если я просто использую строку вместо вашего & quot; get & quot; используя ваш возврат в качестве строки, это работает. Mark Schultheiss

Ваш Ответ

7   ответов
0

что ранее работали с .live (), может ли проблема заключаться в том, что вы пытаетесь привязать свой клик к тому, что вы добавляете в документ, прежде чем добавить его?

Когда вы используете live, он обрабатывает подобные вещи автоматически, но когда вы не используете live, вещи обычно должны существовать на странице, прежде чем связывать с ними какие-либо события. Если вы что-то добавляете с помощью AJAX, вы не можете настроить события щелчка для этих вещей до того, как загрузите их с помощью AJAX. Когда вы используете .live (), вы можете сделать это заранее.

Я бы сделал это так:

$("#overlay-content").on('click','#news',function() {
        var active = 1;
        $("#loading").show();
        $("#overlay-content").fadeOut(1000, function() {
            $.get("http://<? echo ROOT; ?>includes/functions.php", { pressmediaNews: active }, function(data) {
                $("#loading").hide(400);
                $("#overlay-content").empty().append(data).fadeIn(1000);

                //put your delegate/call/function,etc here

            });
        });
    });
к сожалению, событие делегата .on все еще не будет выполнено. zealisreal
3

http://bugs.jquery.com/ticket/11203

Ключевое предложение

If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page.

Для работы с этим сценарием попробуйте связать объект документа с параметром селектора:

$(document).on('click','#news',function() {...}
Привет @Rockitsauce, спасибо, что нашли время, чтобы помочь. Я только что попытался изменить целевой элемент на документ, но он все равно не дал никакого эффекта. Есть еще идеи? zealisreal
0

что ваш Ajax-вызов правильный / возвращает правильный HTML?

Я заменил $ .get () на setTimeout () (и немного упростил) здесь:http://jsfiddle.net/q23st/

Кажется, это работает, поэтому я подозреваю, что ваш $ .get () не возвращает то, что ожидал вернуть.

Проблема в том, что .on 'click & apos; событие не выполняется, так как упрощенная версия, которая просто выполняет команду оповещения, также не будет работать. zealisreal
0

News-left-panel

year_Month_newsID Your News's Year, Month, News ID. For example 2012_5_16, 2012_5_17 etc

<div id="news-left-panel">
    <h4>News Section</h4>
    <ul>
        <li id="newsID2" class="newsYear">
            <p>2012</p>
            <ul class="newsMonths" style="display:none">
                <li>Jan
                    <ul class="newsArticles" style="display:none">
                        <li id="year_Month_newsID">test</li>
                    </ul>
                </li>
                <li>Feb</li>
                <li>Mar</li>
            </ul>
        </li>
        <li id="newsID1" class="newsYear">
            <p>2011</p>
            <ul class="newsMonths" style="display:none">
                <li>Dec
                    <ul class="newsArticles" style="display:none">
                        <li id="year_Month_newsID">Test</li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>
</div>

Jquery Function

$("#news-left-panel ul li").live("click", function(event) {
            var news=(this.id).split("_");
            var year=news[0];
            var month=news[1];
            var newsID =news[2];

            $.ajax({
                type: "POST",
                url: 'http://<? echo ROOT; ?>includes/functions.php',
                data: {
                    year: year,month:month,newsID :newsID
                },
                error: function(){
                    $('#news').html( "<p>Page Not Found!!</p>" );
                    // Here Loader animation
                },
                beforeSend: function(){
                    // Here Loader animation
                    $("#news").html('');
                },
                success: function(data) {
                    $('#news').html(data);

                }
            });
        });​
Спасибо за совет. Твое право. Я разницу понял по (), делегату (), слепому ().jsperf.com/jquery-live-vs-delegate-vs-on
Метод live устарел и не должен использоваться. Из документов: «Начиная с jQuery 1.7, метод .live () устарел. Используйте .on (), чтобы прикрепить обработчики событий. Пользователи более старых версий jQuery должны использовать .delegate () вместо .live (). & Quot;
Я отказался, потому что мне не нравятся такие сложные ответы с большим количествомBOLD UPPERCASE текст
10

$('#overlay-content').on('click', '#newsID2', function() { });

Это будет связывать событие на#overlay-content и проверьте наличие всплывающих событий, если они произошли от#newsID2.

Как примечание: у вас есть опечатка в вашем обработчике событий (chikdren должно бытьchildren) и тебе действительно стоит избавиться от этого безобразногоonClick встроенное событие.

@ Даниил, все еще хорошо, если ты не собираешься делать сложные вещи в пределах этой связанной функции и / или изменять этоonClick Сам обработчик.
Кроме того, я чувствую, что использование onClick устарело, так что бы вы порекомендовали заменить вместо этого для работы с событием? zealisreal
Я бы поставил ID вdata- атрибут и получит доступ к нему из делегированного события.
ты побил нас этим :)
Спасибо за быстрый ответ. Я добавил код, который вы предлагаете, я изменил & #posID # newsID2 & apos; на ".newsYear" как класс будет необходимо после завершения фазы тестирования. К сожалению, хотя это не работает, как задумано. zealisreal
4

$("#overlay-content").on('click', '#newsID2', function() {
    ....
});

Или другими словами:

$('.wrapper').on('event', '.target', function() {
    ...
});

куда.wrapper элемент, который уже существует (или документ), и.target это элемент (ы) внутри оболочки, для которой вы хотите запустить событие.

live функция в основном эквивалентна:

$(document).on('event', '.target', function() { 
    ... 
});

    
Спасибо за то, что изложили основную функциональность .on (), как и в ответе @ThiefMaster с использованием этого исправления, ничего не изменится. zealisreal
Это было исправлением, которое решило ту же проблему, что и у вас для меня. На этом этапе, вероятно, потребуется больше усилий для устранения неполадок.
37

что вы попали в цель, попробуйте это и посмотрите, отображается ли предупреждение:

$(function() {
    $(document).on('click', '#news', function() {
       alert('ok');
    });
});

Если при нажатии на элемент #news отображается предупреждение, все в порядке.

Теперь к этой строке:

$.get("http://<? echo ROOT; ?>includes/functions.php",

Вы используете сокращенное открытие PHP, и это нужно включить, вы можете попробовать

<?php echo ROOT; ?>

Но что такое «ROOT», он никогда не видел этого раньше и не мог найти ничего в руководстве по PHP для ROOT, поэтому я попробовал на своем собственном сервере с самой новой версией PHP и получил ошибку «ROOT». не существует, вместо этого он предполагал, что это строка, и просто echo 'ed & quot; ROOT & quot ;, поэтому ваша ссылка будет выглядеть так:

$.get("http://ROOTincludes/functions.php",

Если это переменная, которую вы где-то определили самостоятельно, она должна начинаться с знака доллара, если она определена с помощью чего вы определилиdefine()убедитесь, что он настроен правильно, и если он использует что-то вроде$_SERVER['DOCUMENT_ROOT']; это не всегда то, к чему вы можете получить доступ в javascript, так как обычно это папка, которая выше, чем ваш webroot, и к ней нельзя получить доступ на стороне клиента, но только на стороне сервера.

Кроме того, как вы написали это, начиная сhttp:// это должно быть доменное имя. Попробуйте открыть источник просмотра в браузере, найдите функцию ajax и посмотрите, что на самом деле выводит ROOT, так как конечный результат будет виден в источнике, и если он установлен с помощью define () во включенном файле конфигурации и т. Д., Вы можете увидеть что он был настроен правильно.

Ваш JavaScript также должен быть внутри PHP-файла для выполнения PHP, или вам придется изменить настройки сервера для запуска файлов JS через PHP.

По моему мнению, просто использовать путь и имя файла - правильный способ сделать это, попробуйте это и обратите внимание на консоль (F12):

$(document).on('click','#news',function() {
    var active = 1;
    var XHR = $.ajax({
                   type: 'GET',
                   url : '/actualpath/includes/functions.php',
                   data: { pressmediaNews: active }
              }).done(function(data) {
                   console.log(data);
              }).fail(function(e1, e2, e3) {
                   console.log('error : '+e1+' - '+e2+' - '+e3);
              });
    $("#loading").show();
    $("#overlay-content").fadeOut(1000, function() {
        XHR.done(function(data) {
            $("#overlay-content").empty().append(data).fadeIn(1000);
            $("#loading").hide(400);
        });
    });
});
извините за огромную задержку с ответом. Я был в больнице и не смог ответить ни на одно сообщение, так как я разместил награду :(. Я попробовал ваш первый фрагмент кода, и он не вызвал оповещение, поэтому я думаю, проблема в этом. В ответ команда ROOT - это определение php, использующее $ _server ['a HTTP_HOST & apos;]. zealisreal
Этот ответ решил многие проблемы, которые у меня были, несмотря на то, что мой код был совершенно другим. спасибо и палец вверх.
Я решил отказаться от этого подхода и попробовать что-то совершенно другое, большое спасибо за вашу помощь. zealisreal
Нет проблем. Если предупреждение не отображается, значит, что-то не так с вашим JS. Попробуй сделать​$(function() { alert('ok'); }​);​ чтобы увидеть, загружен ли jQuery вообще, если это так, проблема почти наверняка состоит в том, что элемент #news не вставлен или вставлен неправильно и не существует.
jQuery определенно загружается, так как выполняет множество других запросов при загрузке страницы. Так что это должно быть как-то связано с элементом #new. zealisreal

Похожие вопросы