AJAX로 부트 스트랩 팝 오버 콘텐츠를로드합니다. 이게 가능해?
내가 시도한 적절한 부분은 다음과 같습니다.
<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에 추가되는 것을 보지 못했지만 방화범 일 수 있습니다.
누구든지 이것을 시도 했습니까?
작업 솔루션에 대한 내 블로그 게시물을 참조하십시오 : 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()
하고 새 hover 이벤트를 바인딩합니다. 마우스 오버 이벤트마다 데이터를 새로 고치려면 끄기를 제거해야합니다.예제 의 작동하는 JSFiddle 을 참조하십시오 .
나를 위해 잘 작동합니다.
$('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');
});
가장 인기있는 답변을 업데이트했습니다. 그러나 내 변경 사항이 승인되지 않을 경우 여기에 별도의 답변을 입력합니다.
차이점은 다음과 같습니다.
- 콘텐츠가로드되는 동안 표시되는 LOADING 텍스트입니다. 느린 연결에 매우 좋습니다.
- 마우스가 처음 팝업을 떠날 때 발생하는 깜박임을 제거했습니다.
먼저 팝업을 추가하려는 요소에 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()
하고 새 hover 이벤트를 바인딩합니다. 마우스 오버 이벤트마다 데이터를 새로 고치려면 끄기를 제거해야합니다.
예제 의 작동하는 JSFiddle 을 참조하십시오 .
Çağatay Gürtürk 코드의 변형으로, 대신 위임 함수를 사용하고 호버 아웃시 팝 오버를 숨길 수 있습니다.
$('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');
}
});
Çağatay Gürtürk의 솔루션은 훌륭하지만 Luke The Obscure가 설명한 것과 동일한 기이함을 경험했습니다.
ajax 로딩이 너무 오래 지속될 때 (또는 마우스 이벤트가 너무 빠르면) 주어진 요소에 .popover ( 'show')가 있고 .popover ( 'hide')가 없어 팝 오버가 열린 상태로 유지됩니다.
이 대규모 사전로드 솔루션을 선호했습니다. 모든 팝 오버 콘텐츠가로드되고 이벤트는 일반 (정적) 팝 오버처럼 부트 스트랩에 의해 처리됩니다.
$('.popover-ajax').each(function(index){
var el=$(this);
$.get(el.attr('data-load'),function(d){
el.popover({content: d});
});
});
또 다른 해결책 :
$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');
});
여기서 아이디어는 mouseenter 및 mouseleave 이벤트 로 PopOver 표시를 수동으로 트리거하는 것 입니다.
에 mouseenter , 당신의 항목이 생성되지 않음 팝 오버 (이 경우없는 경우 ($ (이) .DATA ( '팝 오버가') == NULL) )을 만들 수 있습니다. 흥미로운 점은 popover () 함수에 인수 ( template ) 로 전달하여 자신 만의 PopOver 콘텐츠를 정의 할 수 있다는 것 입니다. html 매개 변수 도 true 로 설정하는 것을 잊지 마십시오 .
여기에서는 popovertemplate 이라는 숨겨진 템플릿을 만들고 JQuery로 복제합니다. 복제 한 후에는 id 속성을 삭제하는 것을 잊지 마십시오. 그렇지 않으면 DOM에서 중복 된 ID로 끝날 것입니다. 또한 페이지에서 템플릿을 숨기려면 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>
생성 단계 후에 (또는 이미 생성 된 경우) $ (this) .popover ( 'show'); 와 함께 popOver를 표시합니다 .
그런 다음 고전적인 Ajax 호출. 성공하면 서버에서 새 데이터를 넣기 전에 이전 팝 오버 콘텐츠 를 정리 해야 합니다 . 현재 팝 오버 콘텐츠를 어떻게 얻을 수 있습니까? 와 .popover.in 선택! .IN 클래스는 팝 오버가 현재 여기에 트릭이 있다고 표시되어 있음을 나타냅니다!
끝내려면 mouseleave 이벤트에서 팝 오버를 숨기십시오.
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')
});
팝 오버의 콘텐츠가 변경 될 가능성이없는 경우 한 번만 검색하는 것이 좋습니다. 또한 여기에있는 일부 솔루션에는 여러 "미리보기"를 빠르게 이동하면 여러 개의 열린 팝업이 표시되는 문제가 있습니다. 이 솔루션은 이러한 문제를 모두 해결합니다.
$('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로드 된 콘텐츠에서도 잘 작동하는 솔루션입니다.
/*
* 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';
}
나는 Çağatay Gürtürk의 해결책을 시도했지만 Luke the Obscure와 같은 이상 함을 얻었습니다. 그런 다음 Asa Kusuma의 솔루션을 시도했습니다. 이것은 작동하지만 팝 오버가 표시 될 때 마다 Ajax 읽기를 수행한다고 생각합니다 . unbind ( 'hover') 호출은 효과가 없습니다. 델리게이트가 특정 클래스의 이벤트를 모니터링하기 때문입니다.하지만 해당 클래스는 변경되지 않았습니다.
다음은 Asa Kusuma를 기반으로 한 내 솔루션입니다. 변경 사항 :
- 새 JQuery 라이브러리와 일치하도록 대체
delegate
되었습니다on
. - 바인딩 해제 이벤트 (바인딩되지 않은) 대신 'withajaxpopover'클래스 제거
- 팝업에 "트리거 : hover"를 추가하여 부트 스트랩이 두 번째 사용부터 완전히 처리하도록합니다.
- 내 데이터 로딩 기능은 JSon을 반환하므로 팝 오버의 제목과 내용을 쉽게 지정할 수 있습니다.
/ * 목표 : 콘텐츠를 가져 오는 도구 설명 / 팝 오버를 처음으로 만 신청하십시오. 방법 : 적절한 콘텐츠를 가져오고 처음에 툴팁 / 팝 오버를 등록합니다. 마우스가 "withajaxpopover"클래스로 DOM 요소에 들어갑니다. 제거 다음 번에 마우스가 들어갈 때 그렇게하지 않습니다. 그러나 처음으로 툴팁 / 팝 오버가 표시되지 않습니다. (툴팁 등록시 마우스가 이미 입력되어 있기 때문입니다.) 그래서 우리는 그것을 직접 보여 주거나 숨겨야합니다. * / $ (function () { $ ( 'body'). on ( 'hover', '.withajaxpopover', function (event) { if (event.type === 'mouseenter') { var el = $ (this); $ .get (el.attr ( 'data-load'), function (d) { el.removeClass ( 'withajaxpopover') el.popover ({trigger : 'hover', 제목 : d. 제목, 내용 : d.content}). popover ( 'show'); }); } else { $ (this) .popover ( 'hide'); } }); });
나는 여기에서 몇 가지 제안을 시도했고 나는 내 (조금 다른) 제안하고 싶습니다. 누군가에게 도움이되기를 바랍니다. 첫 번째 클릭시 팝업 을 표시하고 두 번째 클릭시 숨기고 싶었습니다 (물론 매번 데이터를 업데이트 함). 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>
자바 스크립트 :
$('#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");
});
이와 유사한 답변이이 스레드에서 제공되었습니다. 데이터 콘텐츠 설정 및 팝 오버 표시 -달성하고자하는 작업을 수행하는 더 좋은 방법입니다. 그렇지 않으면 popover 메소드의 옵션에서 live : true 옵션을 사용해야합니다. 도움이 되었기를 바랍니다.
$("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 및 사용자에게 자바 스크립트가없는 경우에도 좋습니다.
나는 Çağatay의 솔루션을 좋아하지만 팝업이 mouseout에 숨어 있지 않았습니다. 이 추가 기능을 추가했습니다.
// hides the popup
$('*[data-poload]').bind('mouseout',function(){
var e=$(this);
e.popover('hide');
});
원래 솔루션을 사용했지만 몇 가지 변경했습니다.
첫째, json 스크립트를로드했기 때문에 getJSON()
대신 사용 했습니다 get()
. 다음으로 스티키 팝 오버 문제를 해결하기 위해 hover 트리거 동작을 추가했습니다.
$('*[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', {
});
});
});
hover 트리거를 사용하여 정적 요소에 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 에서 코드의 일부를 가져 왔습니다.
다음은 몇 가지 문제를 해결하는 방법입니다.
- 콘텐츠가 업데이트 된 후, 특히 배치가 "상단"인 경우 정렬 문제가 있습니다. 핵심은
._popper.update()
팝 오버의 위치를 다시 계산하는 호출 입니다. - 콘텐츠가 업데이트 된 후 너비가 변경됩니다. 그것은 아무것도 깨뜨리지 않고 단지 사용자에게 거슬리는 것처럼 보입니다. 이를 줄이기 위해 팝 오버의 너비를 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");
});
});
'developer tip' 카테고리의 다른 글
.dll과 .exe의 차이점은 무엇입니까? (0) | 2020.09.15 |
---|---|
파일 내용 내에서 문자열 바꾸기 (0) | 2020.09.15 |
Gulp 오류 : 감시 작업은 함수 여야합니다. (0) | 2020.09.15 |
UILabel 글꼴 크기? (0) | 2020.09.15 |
`react-native run-ios`가 오류를 반환합니다 : iPhone X 시뮬레이터를 찾을 수 없음 (0) | 2020.09.15 |