Загрузите содержимое всплывающего окна Bootstrap с помощью AJAX. Это возможно?

90

Соответствующие фрагменты того, что я пробовал, находятся здесь:

<a href="#" data-content="<div id='my_popover'></div>"> Click here </a>

$(".button").popover({html: true})

$(".button").click(function(){
    $(this).popover('show');
    $("#my_popover").load('my_stuff')
})

Когда я нажимаю, я вижу, что запрос сделан, но не заполняет всплывающее окно. Я даже не вижу, чтобы HTML для всплывающего окна добавлялся в DOM, но это может быть firebug.

Кто-нибудь пробовал это?

Кембридж Майк
источник
1
Я не работал с начальной загрузкой, но могу предположить, что, возможно, элемент не существует, когда вы пытаетесь добавить к нему контент, но это предположение. Возникают ли ошибки JavaScript?
Сет
Если у вас есть несколько всплывающих окон и вы хотите загружать разный контент для каждого всплывающего окна, то этот ответ очень аккуратный и позволяет вам сохранить большую часть готовых настроек для всплывающих окон - все, что вам нужно сделать, это сохранить идентификатор всплывающего окна атрибутов ссылки и прочтите их в 'shown.bs.popover'обработчике: stackoverflow.com/a/39028723/1371408
Matty J

Ответы:

105

См. Мое сообщение в блоге для рабочего решения: https://medium.com/cagataygurturk/load-a-bootstrap-popover-content-with-ajax-8a95cd34f6a4

Сначала мы должны добавить атрибут data-poload к элементам, к которым вы хотите добавить всплывающее окно. Содержимым этого атрибута должен быть загружаемый URL (абсолютный или относительный):

<a href="#" title="blabla" data-poload="/test.php">blabla</a>

И в JavaScript, желательно в $ (document) .ready ();

$('*[data-poload]').hover(function() {
    var e=$(this);
    e.off('hover');
    $.get(e.data('poload'),function(d) {
        e.popover({content: d}).popover('show');
    });
});

off('hover')предотвращает загрузку данных более одного раза и popover()связывает новое событие зависания. Если вы хотите, чтобы данные обновлялись при каждом наведении курсора, вам следует удалить параметр off.

См. Рабочий JSFiddle примера.

Чагатай Гюртюрк
источник
4
У меня возникла некоторая странность, когда я дважды наведал курсор мыши до завершения вызова ajax ... Мои всплывающие окна "прилипали" к открытию. Я решил это, переместив el.unbind ('hover') прямо перед $ .get ().
Люк Непонятный,
1
Это работает, но всплывающее окно также придерживается у меня, хотя отвязка выполняется до получения
Андром
2
Если вы пытаетесь загрузить внешний URL-адрес, вы столкнетесь с ограничениями междоменного доступа. Чтобы обойти это, вы можете установить для htmlсвойства popover значение true, а затем установить для contentсвойства HTML-тег iframe, например content: '<iframe src="http://www.google.com"></iframe>'. Вам также потребуется переопределить max-widthсвойство вашего всплывающего окна с помощью CSS и, скорее всего, удалить стиль iframe с помощью CSS.
Gavin
1
@FrzKhan, вы можете использовать e.off('hover')метод
codenamev
3
это не работает из-за того, что stackoverflow.com/questions/4111194/… меняется на .hover (function () {}) работает.
arisalexis 01
132

У меня работает нормально:

$('a.popup-ajax').popover({
    "html": true,
    "content": function(){
        var div_id =  "tmp-id-" + $.now();
        return details_in_popup($(this).attr('href'), div_id);
    }
});

function details_in_popup(link, div_id){
    $.ajax({
        url: link,
        success: function(response){
            $('#'+div_id).html(response);
        }
    });
    return '<div id="'+ div_id +'">Loading...</div>';
}
Иван Класс
источник
1
Гениальный ответ! и поэтому отредактировал его, чтобы сделать его более читаемым
itsazzad
2
Отличное решение. Однако с текущей версией начальной загрузки кажется, что der может быть проблемой для этого метода github.com/twbs/bootstrap/issues/12563 . У меня была двойная проблема, и быстрое решение заключалось в обеспечении заголовка в каждом всплывающем окне. Это также означает, что на самом деле я никогда не вижу загружаемого текста, который вы используете.
Расмус Кристенсен
Работает, за исключением того, что мне пришлось использовать ссылку на данные вместо href, при использовании href мой браузер просто открывал URL-адрес в href в новом окне.
TinusSky 08
20
Не вызывает ли это проблем с выравниванием? При использовании этого подхода в 3.3.1 (и использовании Chrome) всплывающее окно выравнивается, когда отображается «Загрузка ...», но как только истинное содержимое моего всплывающего окна загружается, выравнивание не регулируется соответствующим образом. .
Matt
5
Хорошее решение. Одним из недостатков этого решения является то, что вызов ajax выполняется дважды. Компонент popover - это всплывающая подсказка, которая сначала проверяет содержимое с помощью hasContent, а затем получает содержимое с помощью setContent.
Лиам
23

Прочитав все эти решения, я думаю, что решение станет намного проще, если вы будете использовать синхронный вызов ajax. Затем вы можете использовать что-то вроде:

  $('#signin').popover({
    html: true,
    trigger: 'manual',
    content: function() {
      return $.ajax({url: '/path/to/content',
                     dataType: 'html',
                     async: false}).responseText;
    }
  }).click(function(e) {
    $(this).popover('toggle');
  });
Спутанность сознания
источник
1
Это помогло мне тонны, так как у меня была проблема с рендерингом всплывающего окна в определенной позиции до того, как ajax вернул содержимое (что привело к его загрузке с экрана). Спасибо, сэр!
Дерек
Это может быть проще, но оно менее элегантно, чем решение, опубликованное @Ivan Klass.
Ян Кемп,
6
async: falseубивает это для меня
mxmissile 01
Хотя, конечно, это проще, но JavaScript и синхронный код не очень хорошо работают вместе. Поскольку JavaScript является однопоточным, выполнение любого кода будет блокироваться на время выполнения запроса.
ИлуТов 01
1
Синхронный AJAX устарел.
Barmar
9

Я обновил самый популярный ответ. Но если мои изменения не будут одобрены, я помещаю здесь отдельный ответ.

Отличия заключаются в следующем:

  • ЗАГРУЗКА текст отображается во время загрузки содержимого. Очень хорошо для медленного соединения.
  • Убрано мерцание, возникающее, когда мышь покидает всплывающее окно в первый раз.

Сначала мы должны добавить атрибут data-poload к элементам, к которым вы хотите добавить всплывающее окно. Содержимым этого атрибута должен быть загружаемый URL (абсолютный или относительный):

<a href="#" data-poload="/test.php">HOVER ME</a>

И в JavaScript, желательно в $ (document) .ready ();

 // On first hover event we will make popover and then AJAX content into it.
$('[data-poload]').hover(
    function (event) {
        var el = $(this);

        // disable this event after first binding 
        el.off(event);

        // add initial popovers with LOADING text
        el.popover({
            content: "loading…", // maybe some loading animation like <img src='loading.gif />
            html: true,
            placement: "auto",
            container: 'body',
            trigger: 'hover'
        });

        // show this LOADING popover
        el.popover('show');

        // requesting data from unsing url from data-poload attribute
        $.get(el.data('poload'), function (d) {
            // set new content to popover
            el.data('bs.popover').options.content = d;

            // reshow popover with new content
            el.popover('show');
        });
    },
    // Without this handler popover flashes on first mouseout
    function() { }
);

off('hover')предотвращает загрузку данных более одного раза и popover()связывает новое событие зависания. Если вы хотите, чтобы данные обновлялись при каждом наведении курсора, вам следует удалить параметр off.

См. Рабочий JSFiddle примера.

Александр Чжень
источник
7

Вариант кода от Чагатая Гюртюрка, вы можете использовать вместо этого функцию делегата и принудительно скрывать всплывающее окно при наведении курсора.

$('body').delegate('.withajaxpopover','hover',function(event){
    if (event.type === 'mouseenter') {
        var el=$(this);
        $.get(el.attr('data-load'),function(d){
            el.unbind('hover').popover({content: d}).popover('show');
        });
    }  else {
        $(this).popover('hide');
    }
});
Аса Кусума
источник
Для недавнего jquery: $ ('* [data-poload]'). On ('mouseenter mouseleave', function (event) {
jpprade
7

Решение Чагатая Гюртюрка хорошее, но я испытал ту же странность, которую описал Люк Неизвестный:

Когда загрузка ajax длится слишком долго (или события мыши происходят слишком быстро), у нас есть .popover ('show') и нет .popover ('hide') для данного элемента, из-за чего всплывающее окно остается открытым.

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

$('.popover-ajax').each(function(index){

    var el=$(this);

    $.get(el.attr('data-load'),function(d){
        el.popover({content: d});       
    });     

});
фустаки
источник
7

В 2015 году это лучший ответ

$('.popup-ajax').mouseenter(function() {
   var i = this
   $.ajax({
      url: $(this).attr('data-link'), 
      dataType: "html", 
      cache:true, 
      success: function( data{
         $(i).popover({
            html:true,
            placement:'left',
            title:$(i).html(),
            content:data
         }).popover('show')
      }
   })
});

$('.popup-ajax').mouseout(function() {
  $('.popover:visible').popover('destroy')
});
Дориан Марджиняну
источник
6

Другое решение:

$target.find('.myPopOver').mouseenter(function()
{
    if($(this).data('popover') == null)
    {
        $(this).popover({
            animation: false,
            placement: 'right',
            trigger: 'manual',
            title: 'My Dynamic PopOver',
            html : true,
            template: $('#popoverTemplate').clone().attr('id','').html()
        });
    }
    $(this).popover('show');
    $.ajax({
        type: HTTP_GET,
        url: "/myURL"

        success: function(data)
        {
            //Clean the popover previous content
            $('.popover.in .popover-inner').empty();    

            //Fill in content with new AJAX data
            $('.popover.in .popover-inner').html(data);

        }
    });

});

$target.find('.myPopOver').mouseleave(function()
{
    $(this).popover('hide');
});

Идея здесь состоит в том, чтобы вручную запускать отображение PopOver с событиями mouseenter и mouseleave .

В mouseenter , если для вашего элемента не создано PopOver ( if ($ (this) .data ('popover') == null) ), создайте его. Что интересно, вы можете определить свой собственный контент PopOver, передав его в качестве аргумента ( шаблона ) функции popover () . Не забудьте также установить для параметра html значение true .

Здесь я просто создаю скрытый шаблон под названием popovertemplate и клонирую его с помощью JQuery. Не забудьте удалить атрибут id после его клонирования, иначе вы получите дублированные идентификаторы в DOM. Также обратите внимание, что style = "display: none", чтобы скрыть шаблон на странице.

<div id="popoverTemplateContainer" style="display: none">

    <div id="popoverTemplate">
        <div class="popover" >
            <div class="arrow"></div>
            <div class="popover-inner">
                //Custom data here
            </div>
        </div>
    </div>
</div>

После этапа создания (или если он уже был создан) вы просто отображаете popOver с $ (this) .popover ('show');

Потом классический вызов Ajax. В случае успеха вам необходимо очистить старое содержимое всплывающего окна, прежде чем помещать новые свежие данные с сервера . Как мы можем получить текущий всплывающий контент? С селектором .popover.in ! указывает, что всплывающее окно в настоящее время отображается, вот в чем фокус!

Чтобы закончить, при событии mouseleave просто скройте всплывающее окно.

доандуйхай
источник
То же самое для меня, самый простой и лучший ;-)
Thomas Decaux
проблема в том, что при каждом наведении курсора вы запрашиваете данные с сервера. Он должен загрузить данные только один раз.
Ричард Торкато
2
@ Ричард Торкато. С одной стороны, ты прав. Хотя поместить результат в кеш должно быть довольно легко. С другой стороны, возможно, мы ДЕЙСТВИТЕЛЬНО хотим подключиться к серверу, чтобы загружать свежие данные при каждом наведении курсора. Так что вам
решать
Я понимаю, что это устарело, но, если кто-то смотрит на это, я не могу представить, чтобы это работало хорошо, если у вас есть несколько всплывающих окон и вы прокручиваете каждое из них. Наведите указатель мыши на A, запрос отправлен для A, наведите указатель мыши на B и оставайтесь на нем, запрос отправлен для B, приходит ответ от B, обновляет всплывающее окно для B, приходит ответ для A, обновляет всплывающее окно для B (поскольку функция успеха будет просто очистите что-нибудь с этим классом. Если посмотреть на это в дополнение к вышесказанному, это может помочь, хотя stackoverflow.com/a/34030999/2524589
KSib
3

Вот мое решение, которое отлично работает и с загруженным контентом ajax.

/*
 * popover handler assigned document (or 'body') 
 * triggered on hover, show content from data-content or 
 * ajax loaded from url by using data-remotecontent attribute
 */
$(document).popover({
    selector: 'a.preview',
    placement: get_popover_placement,
    content: get_popover_content,
    html: true,
    trigger: 'hover'
});

function get_popover_content() {
    if ($(this).attr('data-remotecontent')) {
        // using remote content, url in $(this).attr('data-remotecontent')
        $(this).addClass("loading");
        var content = $.ajax({
            url: $(this).attr('data-remotecontent'),
            type: "GET",
            data: $(this).serialize(),
            dataType: "html",
            async: false,
            success: function() {
                // just get the response
            },
            error: function() {
                // nothing
            }
        }).responseText;
        var container = $(this).attr('data-rel');
        $(this).removeClass("loading");
        if (typeof container !== 'undefined') {
            // show a specific element such as "#mydetails"
            return $(content).find(container);
        }
        // show the whole page
        return content;
    }
    // show standard popover content
    return $(this).attr('data-content');
}

function get_popover_placement(pop, el) {
    if ($(el).attr('data-placement')) {
        return $(el).attr('data-placement');
    }
    // find out the best placement
    // ... cut ...
    return 'left';
}
бурильщик
источник
3

Если содержимое всплывающего окна вряд ли изменится, имеет смысл получить его только один раз. Кроме того, у некоторых решений здесь есть проблема, заключающаяся в том, что если вы быстро перемещаетесь по нескольким «превью», вы получаете несколько открытых всплывающих окон. Это решение решает обе эти проблемы.

$('body').on('mouseover', '.preview', function() 
{
    var e = $(this);
    if (e.data('title') == undefined)
    {
        // set the title, so we don't get here again.
        e.data('title', e.text());

        // set a loader image, so the user knows we're doing something
        e.data('content', '<img src="/images/ajax-loader.gif" />');
        e.popover({ html : true, trigger : 'hover'}).popover('show');

        // retrieve the real content for this popover, from location set in data-href
        $.get(e.data('href'), function(response)
        {
            // set the ajax-content as content for the popover
            e.data('content', response.html);

            // replace the popover
            e.popover('destroy').popover({ html : true, trigger : 'hover'});

            // check that we're still hovering over the preview, and if so show the popover
            if (e.is(':hover'))
            {
                e.popover('show');
            }
        });
    }
});
буксир
источник
3

Я думаю, что мое решение более простое с функциональностью по умолчанию.

http://jsfiddle.net/salt/wbpb0zoy/1/

$("a.popover-ajax").each(function(){
		 $(this).popover({
			trigger:"focus",
			placement: function (context, source) {
                  var obj = $(source);
				  $.get(obj.data("url"),function(d) {
                        $(context).html( d.titles[0].title)
                  });	
			},
			html:true,
			content:"loading"
		 });
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>


<ul class="list-group">
  <li class="list-group-item"><a href="#" data-url="https://tr.instela.com/api/v2/list?op=today" class="popover-ajax">Cras justo odio</a></li>
  <li class="list-group-item"><a href="#" data-url="https://tr.instela.com/api/v2/list?op=today" class="popover-ajax">Dapibus ac facilisis in</a></li>
  <li class="list-group-item"><a href="#" data-url="https://tr.instela.com/api/v2/list?op=today" class="popover-ajax">Morbi leo risus</a></li>
  <li class="list-group-item"><a href="#" data-url="https://tr.instela.com/api/v2/list?op=today" class="popover-ajax">Porta ac consectetur ac</a></li>
  <li class="list-group-item"><a href="#" data-url="https://tr.instela.com/api/v2/list?op=today" class="popover-ajax">Vestibulum at eros</a></li>
</ul>

Соляной гарекет
источник
1

Я попробовал решение Чагатая Гюртюрка, но получил ту же странность, что и Люк Неизвестный. Затем попробовал решение Асы Кусумы. Это работает, но я считаю, что Ajax читает каждый раз, когда отображается всплывающее окно. Призыв к отвязке («наведение») не имеет никакого эффекта. Это потому, что делегат отслеживает события в определенном классе, но этот класс не изменяется.

Вот мое решение, во многом основанное на предложении Асы Кусумы. Изменения:

  • Заменено delegateс , onчтобы соответствовать новым библиотекам JQuery.
  • Удалите класс withajaxpopover вместо отмены привязки события зависания (которое никогда не было привязано)
  • Добавьте в всплывающее окно «trigger: hover», чтобы Bootstrap полностью обработал его, начиная со второго использования.
  • Моя функция загрузки данных возвращает JSon, что позволяет легко указать заголовок и содержимое всплывающего окна.
    / * Цель: отобразить всплывающую подсказку / всплывающее окно, в котором контент извлекается из
              приложение только в первый раз.

        Как: получить соответствующий контент и зарегистрировать всплывающую подсказку / всплывающее окно в первый раз 
              мышь входит в элемент DOM с классом withajaxpopover. Удалить
              class из элемента, чтобы мы не делали этого при следующем входе мыши.
              Однако это не показывает всплывающую подсказку / всплывающее окно впервые
              (потому что мышь уже введена, когда всплывающая подсказка зарегистрирована).
              Так что мы должны сами это показать / спрятать.
    * /
    $ (function () {
      $ ('body'). on ('hover', '.withajaxpopover', function (событие) {
          if (event.type === 'mouseenter') {
              var el = $ (это);
              $ .get (el.attr ('загрузка данных'), function (d) {
                  el.removeClass ('withajaxpopover')
                  el.popover ({триггер: 'навести', 
                              title: d.title, 
                              контент: d.content}). popover ('показать');
              });
          } else {
              $ (это) .popover ('спрятать');
          }
      });
    });
bwbecker
источник
1

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

<button type="button" id="votingTableButton" class="btn btn-info btn-xs" data-container="body" data-toggle="popover" data-placement="left" >Last Votes</button>

Javascript:

$('#votingTableButton').data("visible",false);

$('#votingTableButton').click(function() {  
if ($('#votingTableButton').data("visible")) {
    $('#votingTableButton').popover("hide");
    $('#votingTableButton').data("visible",false);          
}
else {
    $.get('votingTable.json', function(data) {
        var content = generateTableContent(data);
        $('#votingTableButton').popover('destroy');
        $('#votingTableButton').popover({title: 'Last Votes', 
                                content: content, 
                                trigger: 'manual',
                                html:true});
        $('#votingTableButton').popover("show");
        $('#votingTableButton').data("visible",true);   
    });
}   
});

Ура!

ItayB
источник
1
<button type="button" id="popover2" title="" data-content="<div id='my_popover' style='height:250px;width:300px;overflow:auto;'>Loading...Please Wait</div>" data-html="true" data-toggle="popover2" class="btn btn-primary" data-original-title="A Title">Tags</button>

$('#popover2').popover({ 
    html : true,
    title: null,
    trigger: "click",
    placement:"right"
});

$("#popover2").on('shown.bs.popover', function(){
    $('#my_popover').html("dynamic content loaded");

});
Шанкар Гупта
источник
1

Вот способ решения нескольких проблем:

  1. Проблемы с выравниванием после обновления содержимого, особенно если место размещения находится «вверху». Ключ вызывает вызов ._popper.update(), который пересчитывает положение всплывающего окна.
  2. Изменение ширины после обновления содержимого. Он ничего не ломает, это просто раздражает пользователя. Чтобы уменьшить это, я установил ширину всплывающего окна на 100% (который затем ограничивается max-width).
var e = $("#whatever");
e.popover({
    placement: "top",
    trigger: "hover",
    title: "Test Popover",
    content: "<span class='content'>Loading...</span>",
    html: true
}).on("inserted.bs.popover", function() {
    var popover = e.data('bs.popover');
    var tip = $(popover.tip);
    tip.css("width", "100%");
    $.ajax("/whatever")
        .done(function(data) {
            tip.find(".content").text(data);
            popover._popper.update();
        }).fail(function() {
            tip.find(".content").text("Sorry, something went wrong");
        });
});
Габриэль Люси
источник
Мне нравятся концепции, но, к сожалению, они не работают для меня ... (а именно, обновление позиции и 100% ширина). Не уверены, изменились ли они с помощью Bootstrap 4?
Бен из Калифорнии,
Ширина 100%, вероятно, зависит от того, как расположены ваши элементы ... возможно. Поле все еще расширяется после загрузки содержимого?
Габриэль Люси
Для позиции, вы можете установить точку останова popover._popper.update()и убедитесь , что popover, _popperи updateвсе они имеют ожидаемые значения. Конечно, возможно, что они изменились.
Габриэль Люси
Справа - поле расширяется после нового содержания. И я попытался записать некоторые значения в консоль и получал undefined.
Бен из Калифорнии,
1
- Ты прав. Оказалось, что я одновременно пытался сделать что-то более сложное, но это не сработало. Но теперь я смог включить и это. Вот скрипка: jsfiddle.net/udfz5wrv/1 Позволяет использовать селекторы (если вам нужно привязать обработчики и т. Д.), Получать доступ к данным из селектора, отображать счетчик загрузки начальной загрузки и т. Д.
Бен в Калифорнии,
1

Здесь слишком много ответов, но я также не нашел ни одного из них того, что я хотел. Я расширил ответ Ивана Класса, чтобы он был как подходящим для Bootstrap 4, так и разумно кешированным.

Обратите внимание, что фрагмент фактически не загружает удаленный адрес из-за политики CORS Stackoverflow.

var popoverRemoteContents = function(element) {
  if ($(element).data('loaded') !== true) {
    var div_id = 'tmp-id-' + $.now();
    $.ajax({
      url: $(element).data('popover-remote'),
      success: function(response) {
        $('#' + div_id).html(response);
        $(element).attr("data-loaded", true);
        $(element).attr("data-content", response);
        return $(element).popover('update');
      }
    });
    return '<div id="' + div_id + '">Loading...</div>';
  } else {
    return $(element).data('content');
  }
};

$('[data-popover-remote]').popover({
  html: true,
  trigger: 'hover',
  content: function() {
    return popoverRemoteContents(this);
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>

<span data-popover-remote="http://example.com/">Remote Popover test with caching</span>

Архонический
источник
Я смог легко адаптировать это к нужному мне решению. Спасибо!
Ниеминен,
0

ответ, подобный этому, был дан в этой теме: Установка содержимого данных и отображение всплывающего окна - это лучший способ сделать то, что вы надеетесь достичь. В противном случае вам придется использовать параметр live: true в параметрах метода popover. Надеюсь, это поможет

E Стивен
источник
0
$("a[rel=popover]").each(function(){
        var thisPopover=$(this);
                var thisPopoverContent ='';
                if('you want a data inside an html div tag') {
                thisPopoverContent = $(thisPopover.attr('data-content-id')).html();
                }elseif('you want ajax content') {
                    $.get(thisPopover.attr('href'),function(e){
                        thisPopoverContent = e;
                    });
            }
        $(this).attr(   'data-original-title',$(this).attr('title') );
        thisPopover.popover({
            content: thisPopoverContent
        })
        .click(function(e) {
            e.preventDefault()
        });

    });

обратите внимание, что я использовал тот же тег href и сделал так, чтобы он не менял страницы при нажатии, это хорошо для SEO, а также, если у пользователя нет javascript!

Нео
источник
0

Мне нравится решение Чагатая, но всплывающие окна не скрывались при наведении курсора мыши. Я добавил эту дополнительную функциональность следующим образом:

// hides the popup
$('*[data-poload]').bind('mouseout',function(){
   var e=$(this);
   e.popover('hide'); 
});
Мино
источник
0

Я использовал исходное решение, но внес несколько изменений:

Во-первых, я использовал getJSON()вместо, get()потому что загружал json-скрипт. Затем я добавил триггерное поведение при наведении, чтобы исправить проблему с липким всплыванием.

$('*[data-poload]').on('mouseover',function() {
    var e=$(this);
    $.getJSON(e.data('poload'), function(data){
        var tip;
        $.each(data, function (index, value) {
           tip = this.tip;
           e.popover({content: tip, html: true, container: 'body', trigger: 'hover'}).popover('show');
        });
    });
});
Марк Флавин
источник
0

Я добавил html: true, чтобы он не отображал необработанный вывод html, если вы хотите отформатировать свои результаты. Вы также можете добавить дополнительные элементы управления.

    $('*[data-poload]').bind('click',function() {
        var e=$(this);
        e.unbind('click');
        $.get(e.data('poload'),function(d) {
            e.popover({content: d, html: true}).popover('show', {

            });
        });
    });
Уоррен Лэндис
источник
0

Отображение всплывающего окна ajax на статическом элементе с триггером наведения:

$('.hover-ajax').popover({
    "html": true,
    trigger: 'hover',
    "content": function(){
        var div_id =  "tmp-id-" + $.now();
        return details_in_popup($(this).attr('href'), div_id);
    }
});

function details_in_popup(link, div_id){
    $.ajax({
        url: link,
        success: function(response){
            $('#'+div_id).html(response);
        }
    });
    return '<div id="'+ div_id +'">Loading...</div>';
}

HTML:

<span class="hover-ajax" href="http://domain.tld/file.php"> Hey , hoover me ! </span>
Алин Разван
источник
0
  $('[data-poload]').popover({
    content: function(){
      var div_id =  "tmp-id-" + $.now();
      return details_in_popup($(this).data('poload'), div_id, $(this));
    },
    delay: 500,

    trigger: 'hover',
    html:true
  });

  function details_in_popup(link, div_id, el){
      $.ajax({
          url: link,
          cache:true,
          success: function(response){
              $('#'+div_id).html(response);
              el.data('bs.popover').options.content = response;
          }
      });
      return '<div id="'+ div_id +'"><i class="fa fa-spinner fa-spin"></i></div>';
  }   

Контент Ajax загружается один раз! увидетьel.data('bs.popover').options.content = response;

SirCumz
источник
0

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

var originalLeave = $.fn.popover.Constructor.prototype.leave;
        $.fn.popover.Constructor.prototype.leave = function(obj){
            var self = obj instanceof this.constructor ?
                obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
            var container, timeout;

            originalLeave.call(this, obj);

            if(obj.currentTarget) {
                container = $(obj.currentTarget).siblings('.popover')
                timeout = self.timeout;
                container.one('mouseenter', function(){
                    //We entered the actual popover – call off the dogs
                    clearTimeout(timeout);
                    //Let's monitor popover content instead
                    container.one('mouseleave', function(){
                        $.fn.popover.Constructor.prototype.leave.call(self, self);
                    });
                })
            }
        };
        var attr = 'tooltip-user-id';
        if ($('a['+ attr +']').length)
            $('a['+ attr +']').popover({
                html: true,
                trigger: 'click hover',
                placement: 'auto',
                content: function () {
                    var this_ = $(this);
                    var userId = $(this).attr(attr);
                    var idLoaded = 'tooltip-user-id-loaded-' + userId;
                    var $loaded = $('.' + idLoaded);
                    if (!$loaded.length) {
                        $('body').append('<div class="'+ idLoaded +'"></div>');
                    } else if ($loaded.html().length) {
                        return $loaded.html();
                    }
                    $.get('http://example.com', function(data) {
                        $loaded.html(data);
                        $('.popover .popover-content').html(data);
                        this_.popover('show');
                    });
                    return '<img src="' + base_url + 'assets/images/bg/loading.gif"/>';
                },
                delay: {show: 500, hide: 1000},
                animation: true
            });

Вы можете проверить это на http://kienthuchoidap.com . Перейдите к этому и наведите указатель мыши на имя пользователя.

Хо Тхань Бинь
источник
0

Для меня работает изменение содержимого данных перед загрузкой всплывающего окна:

$('.popup-ajax').data('content', function () {
    var element = this;
    $.ajax({
        url: url,
        success: function (data) {

            $(element).attr('data-content', data)

            $(element).popover({
                html: true,
                trigger: 'manual',
                placement: 'left'
            });
            $(element).popover('show')
        }})
})
Тьяго Бусики
источник
0

Это работает для меня, этот код исправляет возможные проблемы с выравниванием:

<a class="ajax-popover" data-container="body" data-content="Loading..." data-html="data-html" data-placement="bottom" data-title="Title" data-toggle="popover" data-trigger="focus" data-url="your_url" role="button" tabindex="0" data-original-title="" title="">
  <i class="fa fa-info-circle"></i>
</a>

$('.ajax-popover').click(function() {
  var e = $(this);
  if (e.data('loaded') !== true) {
    $.ajax({
      url: e.data('url'),
      dataType: 'html',
      success: function(data) {
        e.data('loaded', true);
        e.attr('data-content', data);
        var popover = e.data('bs.popover');
        popover.setContent();
        popover.$tip.addClass(popover.options.placement);
        var calculated_offset = popover.getCalculatedOffset(popover.options.placement, popover.getPosition(), popover.$tip[0].offsetWidth, popover.$tip[0].offsetHeight);
        popover.applyPlacement(calculated_offset, popover.options.placement);
      },
      error: function(jqXHR, textStatus, errorThrown) {
        return instance.content('Failed to load data');
      }
    });
  }
});

На всякий случай конечная точка, которую я использую, возвращает html (частичное рельсы)

Я взял часть кода отсюда https://stackoverflow.com/a/13565154/3984542

vicente.fava
источник