Соответствующие фрагменты того, что я пробовал, находятся здесь:
<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.
Кто-нибудь пробовал это?
jquery
twitter-bootstrap
Кембридж Майк
источник
источник
'shown.bs.popover'
обработчике: stackoverflow.com/a/39028723/1371408Ответы:
См. Мое сообщение в блоге для рабочего решения: https://medium.com/cagataygurturk/load-a-bootstrap-popover-content-with-ajax-8a95cd34f6a4
<a href="#" title="blabla" data-poload="/test.php">blabla</a>
$('*[data-poload]').hover(function() { var e=$(this); e.off('hover'); $.get(e.data('poload'),function(d) { e.popover({content: d}).popover('show'); }); });
источник
html
свойства popover значениеtrue
, а затем установить дляcontent
свойства HTML-тег iframe, напримерcontent: '<iframe src="http://www.google.com"></iframe>'
. Вам также потребуется переопределитьmax-width
свойство вашего всплывающего окна с помощью CSS и, скорее всего, удалить стиль iframe с помощью CSS.e.off('hover')
методУ меня работает нормально:
$('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>'; }
источник
Прочитав все эти решения, я думаю, что решение станет намного проще, если вы будете использовать синхронный вызов 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'); });
источник
async: false
убивает это для меняЯ обновил самый популярный ответ. Но если мои изменения не будут одобрены, я помещаю здесь отдельный ответ.
Отличия заключаются в следующем:
Сначала мы должны добавить атрибут 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 примера.
источник
Вариант кода от Чагатая Гюртюрка, вы можете использовать вместо этого функцию делегата и принудительно скрывать всплывающее окно при наведении курсора.
$('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'); } });
источник
Решение Чагатая Гюртюрка хорошее, но я испытал ту же странность, которую описал Люк Неизвестный:
Когда загрузка ajax длится слишком долго (или события мыши происходят слишком быстро), у нас есть .popover ('show') и нет .popover ('hide') для данного элемента, из-за чего всплывающее окно остается открытым.
Я предпочел это решение с массивной предварительной загрузкой, все содержимое всплывающего окна загружается, а события обрабатываются с помощью начальной загрузки, как в обычных (статических) всплывающих окнах.
$('.popover-ajax').each(function(index){ var el=$(this); $.get(el.attr('data-load'),function(d){ el.popover({content: d}); }); });
источник
В 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') });
источник
Другое решение:
$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 просто скройте всплывающее окно.
источник
Вот мое решение, которое отлично работает и с загруженным контентом 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'; }
источник
Если содержимое всплывающего окна вряд ли изменится, имеет смысл получить его только один раз. Кроме того, у некоторых решений здесь есть проблема, заключающаяся в том, что если вы быстро перемещаетесь по нескольким «превью», вы получаете несколько открытых всплывающих окон. Это решение решает обе эти проблемы.
$('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'); } }); } });
источник
Я думаю, что мое решение более простое с функциональностью по умолчанию.
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>
источник
Я попробовал решение Чагатая Гюртюрка, но получил ту же странность, что и Люк Неизвестный. Затем попробовал решение Асы Кусумы. Это работает, но я считаю, что Ajax читает каждый раз, когда отображается всплывающее окно. Призыв к отвязке («наведение») не имеет никакого эффекта. Это потому, что делегат отслеживает события в определенном классе, но этот класс не изменяется.
Вот мое решение, во многом основанное на предложении Асы Кусумы. Изменения:
delegate
с ,on
чтобы соответствовать новым библиотекам JQuery.источник
Я попробовал некоторые из предложений здесь, и я хотел бы представить свое (которое немного отличается) - надеюсь, это кому-то поможет. Я хотел показать всплывающее окно при первом щелчке и скрыть его при втором щелчке (конечно, с обновлением данных каждый раз). Я использовал дополнительную переменную,
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); }); } });
Ура!
источник
<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"); });
источник
Вот способ решения нескольких проблем:
._popper.update()
, который пересчитывает положение всплывающего окна.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"); }); });
источник
popover._popper.update()
и убедитесь , чтоpopover
,_popper
иupdate
все они имеют ожидаемые значения. Конечно, возможно, что они изменились.Здесь слишком много ответов, но я также не нашел ни одного из них того, что я хотел. Я расширил ответ Ивана Класса, чтобы он был как подходящим для 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>
источник
ответ, подобный этому, был дан в этой теме: Установка содержимого данных и отображение всплывающего окна - это лучший способ сделать то, что вы надеетесь достичь. В противном случае вам придется использовать параметр live: true в параметрах метода popover. Надеюсь, это поможет
источник
$("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!
источник
Мне нравится решение Чагатая, но всплывающие окна не скрывались при наведении курсора мыши. Я добавил эту дополнительную функциональность следующим образом:
// hides the popup $('*[data-poload]').bind('mouseout',function(){ var e=$(this); e.popover('hide'); });
источник
Я использовал исходное решение, но внес несколько изменений:
Во-первых, я использовал
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'); }); }); });
источник
Я добавил 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', { }); }); });
источник
Отображение всплывающего окна 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>
источник
$('[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;
источник
Я сделал это, и он отлично работает с 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 . Перейдите к этому и наведите указатель мыши на имя пользователя.
источник
Для меня работает изменение содержимого данных перед загрузкой всплывающего окна:
$('.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') }}) })
источник
Это работает для меня, этот код исправляет возможные проблемы с выравниванием:
<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
источник