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에 추가되지는 않지만 방화범 일 수 있습니다.

누구든지 이것을 시도 했습니까?


1
저는 부트 스트랩으로 작업하지 않았지만 콘텐츠를 추가하려고 할 때 요소가 존재하지 않을 가능성이 있다고 생각하지만 추측입니다. 자바 스크립트 오류가 발생합니까?
Seth

여러 개의 팝 오버가 있고 각 팝 오버에 대해 서로 다른 콘텐츠 를로드하려는 경우이 답변은 매우 깔끔하며 팝 오버에 대한 기본 설정을 많이 유지할 수 있습니다. 팝 오버의 ID를 저장하기 만하면됩니다. 링크의 속성을 확인하고 '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()하고 새 hover 이벤트를 바인딩합니다. 마우스 오버 이벤트마다 데이터를 새로 고치려면 끄기를 제거해야합니다.

예제 의 작동하는 JSFiddle 을 참조하십시오 .


4
ajax 호출이 완료되기 전에 마우스를 두 번 가져 갔을 때 이상한 점이 생겼습니다. $ .get () 바로 앞에 "el.unbind ( 'hover')"를 이동하여 해결했습니다.
Luke The Obscure 2012

1
이것은 작동하지만,

2
외부 URL을로드하려는 경우 교차 도메인 액세스 제한이 발생합니다. 이 문제를 해결하려면 팝 오버의 html속성을 true로 설정 한 다음 속성 을와 content같은 iframe HTML 태그 로 설정할 수 content: '<iframe src="http://www.google.com"></iframe>'있습니다. 또한 max-widthCSS를 사용하여 팝 오버의 속성 을 재정의해야하며 , 대부분 CSS를 사용하여 iframe의 스타일을 제거해야합니다.
Gavin

1
당신은 사용할 수 있습니다 @FrzKhan e.off('hover')방법
codenamev

3
이것은 stackoverflow.com/questions/4111194/… 때문에 작동하지 않습니다. .hover (function () {})로 변경하면 작동합니다.
arisalexis

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
훌륭한 솔루션입니다. 그러나 현재 버전의 부트 스트랩에서는이 방법에 문제가있을 수 있습니다 . github.com/twbs/bootstrap/issues/12563 . 나는 두 번 문제가 있었고 빠른 해결책은 각 팝 오버에서 제목을 확인하는 것이 었습니다. 이것은 또한 실제로 사용중인 Loading 텍스트를 볼 수 없음을 의미합니다.
Rasmus Christensen

작동하지만 href 대신 데이터 링크를 사용해야하는 경우를 제외하고, href를 사용하면 브라우저가 단순히 새 창에서 href에서 URL을 열 것입니다.
TinusSky

20
이것이 정렬 문제를 일으키지 않습니까? 3.3.1 (및 Chrome 사용)에서이 방법을 사용하면 "Loading ..."이 표시 될 때 팝 오버가 자동으로 정렬되지만 내 팝 오버의 실제 콘텐츠가로드 되 자마자 그에 따라 정렬이 조정되지 않습니다. .
Matt

5
좋은 솔루션입니다. 이 솔루션의 한 가지 단점은 ajax 호출이 두 번 수행된다는 것입니다. 팝 오버 컴포넌트는 먼저 hasContent를 사용하여 콘텐츠를 확인한 다음 setContent로 콘텐츠를 가져 오는 툴팁입니다.
Liam

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가 내용을 반환하기 전에 특정 위치에서 팝 오버 렌더링에 문제가 있었기 때문에 많은 도움이되었습니다 (화면에서로드를 유발). 감사합니다!
Derek

더 간단 할 수도 있지만 @Ivan Klass가 게시 한 솔루션보다 덜 우아합니다.
Ian Kemp

6
async: false나를 위해 이것을 죽입니다
mxmissile

확실히 더 쉽지만 JavaScript와 동기 코드는 함께 잘 작동하지 않습니다. JavaScript는 단일 스레드이므로 요청이 걸리는 동안 모든 코드가 실행되지 않도록 차단합니다.
IluTov

1
동기식 AJAX는 더 이상 사용되지 않습니다.
Barmar

9

가장 인기있는 답변을 업데이트했습니다. 그러나 변경 사항이 승인되지 않을 경우 여기에 별도의 답변을 입력합니다.

차이점은 다음과 같습니다.

  • 콘텐츠가로드되는 동안 표시되는 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 을 참조하십시오 .


7

Ç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');
    }
});

최근 jquery의 경우 : $ ( '* [data-poload]'). on ( 'mouseenter mouseleave', function (event) {
jpprade

7

Ç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});       
    });     

});

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');
});

여기서 아이디어는 mouseentermouseleave 이벤트 로 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 이벤트에서 팝 오버를 숨기십시오.


나에게도 똑같은 일, 가장 단순하고 최고의 것 ;-)
Thomas

이 문제는 서버에서 데이터를 요청하는 모든 호버에 있습니다. 데이터를 한 번만로드해야합니다.
Richard Torcato 2013-06-17

2
@Richard Torcato 한 손으로 당신이 옳습니다. 결과를 캐시에 저장하는 것은 매우 쉽습니다. 다른 한편으로, 우리는 매 호버링 할 때마다 새로운 데이터를로드하기 위해 서버에 접속하고 싶을 수도 있습니다. 그래서 캐싱을 구현하는 당신까지
doanduyhai

나는 이것이 이제 오래되었다는 것을 알고 있지만 누군가 이것을보고있는 경우 여러 팝 오버가 있고 각 팝 오버를 스크롤하면 이것이 잘 작동한다고 상상할 수 없습니다. 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

나는 Çağatay Gürtürk의 해결책을 시도했지만 Luke the Obscure와 같은 이상 함을 얻었습니다. 그런 다음 Asa Kusuma의 솔루션을 시도했습니다. 이것은 작동하지만 팝 오버가 표시 마다 Ajax 읽기를 수행한다고 생각합니다 . unbind ( 'hover') 호출은 효과가 없습니다. 델리게이트가 특정 클래스의 이벤트를 모니터링하기 때문입니다.하지만 해당 클래스는 변경되지 않았습니다.

다음은 Asa Kusuma를 기반으로 한 내 솔루션입니다. 변경 사항 :

  • 새 JQuery 라이브러리와 일치하도록 대체 delegate되었습니다 on.
  • 바인딩 해제 이벤트 (바인딩되지 않은) 대신 'withajaxpopover'클래스 제거
  • 팝업에 "trigger : hover"를 추가하여 Bootstrap이 두 번째 사용부터 완전히 처리하도록합니다.
  • 내 데이터 로딩 기능은 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');
          }
      });
    });

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>

자바 스크립트 :

$('#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);   
    });
}   
});

건배!


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에서 변경되었는지 확실하지 않습니까?
Ben in CA

100 % 너비는 요소가 배치되는 방식에 따라 달라질 수 있습니다. 콘텐츠가로드 된 후에도 상자가 계속 확장됩니까?
Gabriel Luci

위치에 대해 중단 점을 설정하고 , 및 모두에 예상 값이 popover._popper.update()있는지 확인할 수 있습니다 . 그것들이 변경되었을 가능성이 있습니다. popover_popperupdate
Gabriel Luci

오른쪽-새 콘텐츠 후에 상자가 넓어집니다. 그리고 일부 값을 콘솔에 쓰려고 시도했지만 정의되지 않았습니다.
Ben in CA

1
- 네가 옳아. 동시에 좀 더 복잡한 작업을하려고했지만 작동하지 않는 것으로 나타났습니다. 하지만 이제 저도 그것을 통합 할 수있었습니다. 다음은 바이올린입니다. jsfiddle.net/udfz5wrv/1 선택기를 사용하고 (처리기를 바인딩해야하는 경우 등), 선택기에서 데이터에 액세스하고, 부트 스트랩 로딩 스피너를 표시 할 수 있습니다.
Ben in CA

1

여기에 너무 많은 답변이 있지만 내가 원하는 답이 없다는 것도 발견했습니다. Ivan Klass의 답변을 Bootstrap 4에 적합하고 지능적으로 캐시하도록 확장했습니다.

스 니펫은 Stackoverflow의 CORS 정책으로 인해 실제로 원격 주소를로드하지 않습니다.

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>


이 솔루션을 필요한 솔루션에 쉽게 적용 할 수있었습니다. 감사합니다!
Nieminen

0

이와 유사한 답변이이 스레드에서 제공되었습니다. 데이터 콘텐츠 설정 및 팝 오버 표시 -달성하고자하는 작업을 수행하는 더 좋은 방법입니다. 그렇지 않으면 popover 메소드의 옵션에서 live : true 옵션을 사용해야합니다. 도움이 되었기를 바랍니다.


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 및 사용자에게 자바 스크립트가없는 경우에도 좋습니다.


0

나는 Çağatay의 솔루션을 좋아하지만 팝업이 mouseout에 숨어 있지 않았습니다. 이 추가 기능을 다음과 같이 추가했습니다.

// hides the popup
$('*[data-poload]').bind('mouseout',function(){
   var e=$(this);
   e.popover('hide'); 
});

0

원래 솔루션을 사용했지만 몇 가지 변경했습니다.

첫째, 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');
        });
    });
});

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

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>

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;


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 에서 코드의 일부를 가져 왔습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.