Компоненты, вставленные в страницу с использованием функции .load () jquery, не имеют дескриптора javascript [duplicate]

Посмотрите на этот пример:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope,$http) {

    var getJoke = function(){
        return $http.get('http://api.icndb.com/jokes/random').then(function(res){
            return res.data.value;  
        });
    }

    getJoke().then(function(res) {
        console.log(res.joke);
    });
});

Как вы можете видеть, getJoke возвращает разрешенное обещание (оно разрешено при возврате res.data.value). Таким образом, вы ждете, пока запрос $ http.get не будет завершен, а затем выполнится console.log (res.joke) (как обычный асинхронный поток).

Это plnkr:

http://embed.plnkr.co/XlNR7HpCaIhJxskMJfSg/

50
задан Anthony Grist 23 June 2014 в 13:23
поделиться

5 ответов

Селектора jQuery выбирают совпадающие элементы, которые существуют в DOM при выполнении кода и не динамически обновляются. Когда вы вызываете функцию, например .hover(), чтобы добавить обработчик событий, она добавляет их только к этим элементам. Когда вы выполняете вызов AJAX и заменяете раздел своей страницы, вы удаляете эти элементы с привязанными к ним обработчиками событий и заменяете их новыми элементами. Даже если эти элементы теперь соответствуют этому селектору, они не получают привязки обработчика события, потому что уже выполненный код.

Обработчики событий

В частности, для обработчиков событий (т. Е. .click()), вы можете использовать делегирование событий, чтобы обойти это. Основной принцип заключается в том, что вы привязываете обработчик событий к статическому (существует, когда страница загружается, не заменяется) элемент, который будет содержать весь ваш динамический (загруженный AJAX) контент. Вы можете узнать больше о делегировании событий в документации jQuery .

Для вашего обработчика событий click обновленный код будет выглядеть так:

$(document).on('click', "#click", function () {
    $('#click').css({
        "background-color": "#f00",
        "color": "#fff",
        "cursor": "inherit"
    }).text("Open this window again and this message will still be here.");
    return false;
});

Это привяжет обработчик события ко всему документу (поэтому он никогда не удаляется до выгрузки страницы), который будет реагировать на события click на элементе с свойством id в click. В идеале вы должны использовать что-то ближе к своим динамическим элементам в DOM (возможно, <div> на вашей странице, которая всегда присутствует и содержит все содержимое вашей страницы), поскольку это немного улучшит эффективность.

Проблема возникает, когда вам нужно обрабатывать .hover(). В JavaScript нет реального события hover, jQuery просто предоставляет эту функцию как удобное сокращение для привязки обработчиков событий к событиям mouseenter и mouseleave. Однако вы можете использовать делегирование делегирования:

$(document).on({
    mouseenter: function () {
        $(this).stop().animate({
            width: xwidth * 3,
            height: xheight * 3,
            margin: -(xwidth / 3)
        }, 200); //END FUNCTION

        $(this).addClass('image-popout-shadow');
    },
    mouseleave: function () {
        $(this).stop().animate({
            width: xwidth,
            height: xheight,
            margin: 0
        }, 200, function () {
            $(this).removeClass('image-popout-shadow');
        }); //END FUNCTION

    }
}, '.image-popout img');

плагины jQuery

Что касается привязок обработчика событий. Однако это еще не все, что вы делаете. Вы также инициализируете плагин jQuery (colorbox), и нет возможности делегировать их элементам. Вам придется просто называть эти строки снова, когда вы загрузили свой контент AJAX; самым простым способом было бы переместить их в отдельную именованную функцию, которую вы можете вызвать в обоих местах (при загрузке страницы и в обратном вызове AJAX success):

function initialiseColorbox() {
    $(".iframe").colorbox({
        iframe: true,
        width: "1000px",
        height: "500px"
    });
    $(".inline").colorbox({
        inline: true,
        width: "50%"
    });
    $(".callbacks").colorbox({
        onOpen: function () {
            alert('onOpen: colorbox is about to open');
        },
        onLoad: function () {
            alert('onLoad: colorbox has started to load the targeted content');
        },
        onComplete: function () {
            alert('onComplete: colorbox has displayed the loaded content');
        },
        onCleanup: function () {
            alert('onCleanup: colorbox has begun the close process');
        },
        onClosed: function () {
            alert('onClosed: colorbox has completely closed');
        }
    });
}
108
ответ дан Anthony Grist 25 August 2018 в 09:04
поделиться

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

Так, как сказал Тамер Дургун, мы также разместим ваш код внутри ajaxStop, поэтому ваш код будет восстановлен каждый раз, когда какое-либо событие будет завершено ajax.

$( document ).ajaxStop(function() {

//your code

}

Работал для меня:)

20
ответ дан Aamer Shahzad 25 August 2018 в 09:04
поделиться

Ваши обработчики событий теряются при замене содержимого. Когда вы устанавливаете события hover, jQuery устанавливает их в событиях на странице в настоящее время. Поэтому, когда вы заменяете их на ajax, события не связаны с этими элементами, потому что они новы.

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

Таким образом, событие устанавливается в документе, и любые новые элементы получат вызванное событие.

3
ответ дан Community 25 August 2018 в 09:04
поделиться

Вы можете использовать полную функцию jQuery ajax после извлечения формы данных где-нибудь, она увидит обновленные элементы после завершения ajax

4
ответ дан Tamer Durgun 25 August 2018 в 09:04
поделиться

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

, этот $(selector).click(function(e){}

стал таким после использования метода delegate ()

$( "body" ).delegate( "selector", "click", function(e) {}

Надеюсь, это поможет;)

0
ответ дан user111286 25 August 2018 в 09:04
поделиться
Другие вопросы по тегам:

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