ฉันจะปิดป็อปโอเวอร์ Twitter Bootstrap ด้วยการคลิกจากที่ใดก็ได้ (อื่น ๆ ) บนหน้าได้อย่างไร


155

ฉันกำลังใช้ป๊อปอัปกับ Twitter Bootstrap ซึ่งริเริ่มขึ้นดังนี้:

$('.popup-marker').popover({
        html: true,
        trigger: 'manual'
    }).click(function(e) {
        $(this).popover('toggle');
        e.preventDefault();
    });

อย่างที่คุณเห็นพวกมันจะถูกเรียกใช้งานด้วยตนเองและคลิกที่. popup-marker (ซึ่งเป็น div ที่มีภาพพื้นหลัง) เพื่อเปิดป๊อปอัป สิ่งนี้ใช้งานได้ดี แต่ฉันต้องการที่จะสามารถปิดป๊อปโอเวอร์ด้วยการคลิกที่ใดก็ได้บนหน้าเว็บ (แต่ไม่ใช่ในป๊อปโอเวอร์เอง!)

ฉันได้ลองทำสิ่งต่าง ๆ รวมถึงรายการต่อไปนี้ แต่ไม่มีผลลัพธ์ที่จะแสดง:

$('body').click(function(e) {
    $('.popup-marker').popover('hide');
});

ฉันจะปิด popover ด้วยการคลิกที่ใดก็ได้บนหน้าเว็บ แต่จะไม่ปิดคลิกด้วยตัวเอง


อืมฉันคิดว่ามันจะใช้งานได้ ... คุณมีลิงค์เชื่อมโยงออนไลน์โดยบังเอิญหรือไม่?
Thatryan

คำตอบ:


102

สมมติว่ามีป๊อปโอเวอร์เดียวเท่านั้นที่สามารถมองเห็นได้ตลอดเวลาคุณสามารถใช้ชุดธงเพื่อทำเครื่องหมายเมื่อมีป๊อปโอเวอร์ปรากฏให้เห็นจากนั้นซ่อนเฉพาะ

หากคุณตั้งค่าฟังเหตุการณ์ในเนื้อหาเอกสารมันจะทริกเกอร์เมื่อคุณคลิกองค์ประกอบที่มีเครื่องหมาย 'ป๊อปอัพมาร์กเกอร์' ดังนั้นคุณจะต้องโทรstopPropagation()วัตถุเหตุการณ์ และใช้เคล็ดลับเดียวกันเมื่อคลิกที่ป๊อปโอเวอร์เอง

ด้านล่างเป็นรหัส JavaScript ที่ใช้งานได้ มันใช้ jQuery> = 1.7

jQuery(function() {
    var isVisible = false;

    var hideAllPopovers = function() {
       $('.popup-marker').each(function() {
            $(this).popover('hide');
        });  
    };

    $('.popup-marker').popover({
        html: true,
        trigger: 'manual'
    }).on('click', function(e) {
        // if any other popovers are visible, hide them
        if(isVisible) {
            hideAllPopovers();
        }

        $(this).popover('show');

        // handle clicking on the popover itself
        $('.popover').off('click').on('click', function(e) {
            e.stopPropagation(); // prevent event for bubbling up => will not get caught with document.onclick
        });

        isVisible = true;
        e.stopPropagation();
    });


    $(document).on('click', function(e) {
        hideAllPopovers();
        isVisible = false;
    });
});

http://jsfiddle.net/AFffL/539/

ข้อแม้เดียวคือคุณจะไม่สามารถเปิดป๊อปอัป 2 แห่งในเวลาเดียวกันได้ แต่ฉันคิดว่านั่นจะสร้างความสับสนให้กับผู้ใช้อย่างไรก็ตาม :-)


1
การคลิกที่ตัว popover เองใน jsfiddle นั้นทำให้ popover นั้นซ่อนตัว - ไม่ใช่สิ่งที่ถามมา
Jonathon Hill

1
@RaduCugut นั่นเป็นทางออกที่ดี แต่มันมีข้อผิดพลาด คลิกหนึ่งครั้งที่ zzzzz และ popover จะปรากฏขึ้น ตอนนี้คลิกหนึ่งครั้งบนพื้นหลังสีขาว ป๊อปอัปหายไป ตอนนี้คลิกอีกครั้งบนพื้นหลังสีขาว และตอนนี้คลิกอีกครั้งบน zzzz และมันไม่ทำงาน : - |
Houman

1
@ ให้ถูกต้องฉันได้แก้ไขซอและคำตอบเพื่อแก้ไขปัญหานี้ jsfiddle.net/AFffL/177
Radu Cugut

3
ทำไมไม่เพียงแค่เรียกใช้ $ ('. popup-marker'). popover ('ซ่อน') (เพื่อซ่อนทั้งหมด) ก่อนหน้า $ (นี้). popover ('แสดง') ซึ่งจะกำจัดความต้องการตัวแปร isVisible และ clicked Away ใด ๆ
Nathan Hangen

1
วิธีการแก้ปัญหานี้ทำให้ฉันมีปัญหาบางอย่าง (คลิกที่องค์ประกอบ '. popup-marker' ของ popover ที่เปิดทำให้ popovers ไม่ทำงานหลังจากนั้น) ฉันคิดวิธีแก้ปัญหาอื่น (โพสต์ด้านล่าง) ที่เหมาะกับฉันและดูเหมือนง่ายกว่า (ฉันใช้ Bootstrap 2.3.1)
RayOnAir

76

ง่ายยิ่งขึ้น:

$('html').click(function(e) {
    $('.popup-marker').popover('hide');
});

$('.popup-marker').popover({
    html: true,
    trigger: 'manual'
}).click(function(e) {
    $(this).popover('toggle');
    e.stopPropagation();
});

ตกลง และอย่างน้อยสำหรับฉันนั่นเป็นวิธีที่เหมาะสมที่จะทำ ตัวเลือกแรกดูเหมือนจะเป็น "การแก้ไขด่วน"
Denis Lins

4
ต้องการใช้สิ่งนี้ แต่ด้วยเหตุผลบางอย่างไม่ได้ผล เหตุการณ์การคลิกไม่เคยมาถึงhtmlเพราะe.stopPropagation();ฉันใช้สิ่ง$('.popup-marker').on('show', function(event) { $('.popup-marker').filter(function(index, element) { return element != event.target; }).popover('hide'); });ที่ทำงานได้ดีเช่นกัน (แต่ไม่รู้ว่ามีความแตกต่างด้านประสิทธิภาพหรือไม่)
Cornelis

1
นี่คือคำตอบที่ดีที่สุด IMO
Loolooii

1
การรวบรวมคำตอบ @pbaron และ @Cornelis ทำงานได้ดีที่สุด สิ่งที่ฉันเพิ่มคือรหัส Cornelis ภายในฟังก์ชั่น 'คลิก' ที่สอง (ก่อน$(this).popover('toggle');ส่วนหนึ่งจากนั้นถ้าคุณมีวัตถุ 'ป๊อปอัปมาร์ก
เกอร์

2
ปัญหาหนึ่งที่เกิดขึ้นกับสิ่งนี้คือ popover ยังคงซ่อนอยู่ ตัวอย่างเช่นหากคุณมีลิงค์ใน popover คุณสามารถเลื่อนเคอร์เซอร์ไปที่ที่เคยเป็นและยังได้รับเคอร์เซอร์เปลี่ยนไปที่ลิงค์เหล่านั้น
Glacials

48

ผมมีความต้องการที่คล้ายกันและพบนี้ขยายเล็ก ๆ น้อย ๆ ที่ดีของเงินทุน Twitter popover โดยลีคาร์ไมเคิเรียก BootstrapX - clickover นอกจากนี้เขายังมีตัวอย่างการใช้งานบางอย่างที่นี่ โดยทั่วไปมันจะเปลี่ยน popover เป็นองค์ประกอบแบบโต้ตอบซึ่งจะปิดเมื่อคุณคลิกที่อื่นบนหน้าหรือที่ปุ่มปิดภายใน popover นอกจากนี้ยังอนุญาตให้เปิดป๊อปอัปหลายรายการพร้อมกันและคุณสมบัติอื่น ๆ อีกมากมาย

ปลั๊กอินสามารถพบได้ที่นี่ปลั๊กอินสามารถพบได้ที่นี่

ตัวอย่างการใช้งาน

<button rel="clickover" data-content="Show something here. 
    <button data-dismiss='clickover'
    >Close Clickover</button>"
>Show clickover</button>

javascript:

// load click overs using 'rel' attribute
$('[rel="clickover"]').clickover();

1
มันยอดเยี่ยมจริงๆ ง่ายสุด ๆ
Doug

ปลั๊กอินที่ยอดเยี่ยม! ขอบคุณสำหรับลิงค์
แมตต์วิลสัน

1
เพียงแค่ให้มันยิงและมันใช้งานได้ดี เป็นเรื่องง่ายเหมือนการเปลี่ยน rel ของ popover ที่มีอยู่จาก "popover" เป็น "clickover"
Dmase05

ทำงานบน Bootstrap v2.3.1 ไม่มีปัญหา
Kevin Dewalt

37

ทางออกที่ได้รับการยอมรับทำให้ฉันมีปัญหาบางอย่าง (คลิกที่องค์ประกอบ '. popup-marker' ของ popover ที่เปิดทำให้ popovers ไม่ทำงานหลังจากนั้น) ฉันมากับโซลูชันอื่นที่ทำงานได้อย่างสมบูรณ์แบบสำหรับฉันและมันค่อนข้างง่าย (ฉันใช้ Bootstrap 2.3.1):

$('.popup-marker').popover({
    html: true,
    trigger: 'manual'
}).click(function(e) {
    $('.popup-marker').not(this).popover('hide');
    $(this).popover('toggle');
});
$(document).click(function(e) {
    if (!$(e.target).is('.popup-marker, .popover-title, .popover-content')) {
        $('.popup-marker').popover('hide');
    }
});

UPDATE: รหัสนี้ใช้ได้กับ Bootstrap 3 เช่นกัน!


1
นี่เป็นทางออกที่ดี ขอบคุณ.
กาวิน

1
ทางออกที่ดี ทำไมคุณไม่ใช้ if (!$(e.target).is('.popup-marker') && !$(e.target).parents('.popover').length > 0)วิธีนี้ป๊อปอัปจะไม่ปิดแม้ว่าจะมีเนื้อหา HTML
ykay พูดว่า Reinstate Monica

2
หรือดีกว่าif (!$(e.target).is('.popup-marker') && $(e.target).closest('.popover').length === 0)
fabdouglas

19

อ่าน "ปิดเมื่อคลิกถัดไป" ที่นี่http://getbootstrap.com/javascript/#popovers

คุณสามารถใช้ทริกเกอร์โฟกัสเพื่อปิดป๊อปอัปในการคลิกครั้งถัดไป แต่คุณต้องใช้<a>แท็กไม่ใช่<button>แท็กและคุณต้องมีtabindexแอตทริบิวต์ ...

ตัวอย่าง:

<a href="#" tabindex="0" class="btn btn-lg btn-danger"
  data-toggle="popover" data-trigger="focus" title="Dismissible popover"
  data-content="And here's some amazing content. It's very engaging. Right?">
  Dismissible popover
</a>

2
คำถามดังกล่าวระบุว่าเขาไม่ต้องการให้ยกเลิกหากมีการคลิกที่ป๊อปโอเวอร์ วิธีนี้จะปิดเมื่อคลิกได้ทุกที่
Fred

1
การเพิ่ม data-trigger = "focus" หยุดไม่ให้ป๊อปอัปของฉันเปิดตัวจนกว่าฉันจะอ่านโพสต์นี้และเพิ่มแอตทริบิวต์ tabindex ตอนนี้มันใช้งานได้!
PixelGraph

2
สำหรับข้อมูลนี้ยังใช้งานtooltipได้แม้ว่าจะไม่ได้กล่าวถึงอย่างชัดเจนในเอกสารจริง
AlexB

7

คำตอบที่มีอยู่ทั้งหมดค่อนข้างอ่อนแอเนื่องจากต้องอาศัยการบันทึกเหตุการณ์เอกสารทั้งหมดแล้วค้นหาป๊อปอัปที่ใช้งานอยู่หรือแก้ไขการโทร.popover()ใช้งานหรือการปรับเปลี่ยนการเรียกร้องให้

วิธีที่ดีกว่าคือฟังshow.bs.popoverเหตุการณ์ในเนื้อหาของเอกสารจากนั้นตอบสนองตามนั้น ด้านล่างคือรหัสที่จะปิดป๊อปอัปเมื่อเอกสารถูกคลิกหรือescถูกกดจะมีเพียงผู้ฟังเหตุการณ์ที่ผูกมัดเมื่อมีการแสดงป๊อปอัป:

function closePopoversOnDocumentEvents() {
  var visiblePopovers = [];

  var $body = $("body");

  function hideVisiblePopovers() {
    $.each(visiblePopovers, function() {
      $(this).popover("hide");
    });
  }

  function onBodyClick(event) {
    if (event.isDefaultPrevented())
      return;

    var $target = $(event.target);
    if ($target.data("bs.popover"))
      return;

    if ($target.parents(".popover").length)
      return;

    hideVisiblePopovers();
  }

  function onBodyKeyup(event) {
    if (event.isDefaultPrevented())
      return;

    if (event.keyCode != 27) // esc
      return;

    hideVisiblePopovers();
    event.preventDefault();
  }

  function onPopoverShow(event) {
    if (!visiblePopovers.length) {
      $body.on("click", onBodyClick);
      $body.on("keyup", onBodyKeyup);
    }
    visiblePopovers.push(event.target);
  }

  function onPopoverHide(event) {
    var target = event.target;
    var index = visiblePopovers.indexOf(target);
    if (index > -1) {
      visiblePopovers.splice(index, 1);
    }
    if (visiblePopovers.length == 0) {
      $body.off("click", onBodyClick);
      $body.off("keyup", onBodyKeyup);
    }
  }

  $body.on("show.bs.popover", onPopoverShow);
  $body.on("hide.bs.popover", onPopoverHide);
}

+1 นี่คือทางออกที่สะอาดและขยายได้มากที่สุด หากคุณกำลังใช้เฟรมเวิร์กเช่นแกนหลักเช่นกันให้ทิ้งข้อมูลนี้ไว้ในรหัสการเริ่มต้นของคุณและจะดูแลการจัดการป๊อปอัป
JohnP

คำตอบนี้ยังเพิ่มความกังวลด้านประสิทธิภาพและช่วยให้การจัดการ HTML ที่ซับซ้อนมากขึ้นภายในป๊อปโอเวอร์
Ricardo

ทางออกที่ดี; สามารถวางลงในวิธีการตอบสนองได้อย่างง่ายดาย คำแนะนำเดียวเพิ่ม$(event.target).data("bs.popover").inState.click = false;ไปยังฟังก์ชั่น onPopoverHide ดังนั้นคุณไม่จำเป็นต้องคลิกสองครั้งเพื่อเปิดอีกครั้งหลังจากปิด
sco_tt

อยากรู้อยากเห็นถ้าคุณสามารถทำเรื่องนี้กับป๊อปอัปสอง ในแอปพลิเคชันของฉันเมื่อฉันใช้รหัสของคุณฉันสามารถคลิกป๊อปอัพไปยังป๊อปอัปและมีหลายรายการปรากฏขึ้นจากนั้นคลิกที่ 'เนื้อหา' ลบเฉพาะรายการสุดท้ายที่แสดง
เทอร์รี่


2

ด้วยเหตุผลบางอย่างการแก้ปัญหาอื่นที่นี่ก็ไม่ได้ผลสำหรับฉัน อย่างไรก็ตามหลังจากการแก้ไขปัญหาจำนวนมากในที่สุดฉันก็มาถึงวิธีนี้ซึ่งทำงานได้อย่างสมบูรณ์แบบ (สำหรับฉันอย่างน้อย)

$('html').click(function(e) {
  if( !$(e.target).parents().hasClass('popover') ) {
    $('#popover_parent').popover('destroy');
  }
});

ในกรณีของฉันฉันเพิ่ม popover ลงในตารางและวางตำแหน่งไว้ด้านบน / ล่างtdที่ถูกคลิก การเลือกตารางได้รับการจัดการโดย jQuery-UI Selectable ดังนั้นฉันไม่แน่ใจว่าสิ่งนั้นรบกวน อย่างไรก็ตามเมื่อใดก็ตามที่ฉันคลิกภายใน popover ตัวจัดการการคลิกของฉันซึ่งเป้าหมาย$('.popover')ไม่ทำงานและการจัดการเหตุการณ์มักมอบหมายให้$(html)ตัวจัดการคลิก ฉันค่อนข้างใหม่สำหรับ JS ดังนั้นบางทีฉันแค่คิดถึงบางสิ่ง?

อย่างไรก็ตามฉันหวังว่านี่จะช่วยให้ใครบางคน!


BTW ฉันไม่แน่ใจว่ามันสำคัญ แต่ฉันใช้วิธีนี้สำหรับ Bootstrap 2 ฉันคิดว่ามันจะใช้ได้กับ Bootstrap 3 แต่ยังไม่ได้รับการยืนยัน
moollaza

2

ฉันให้ทุก popovers activate_popoverฉันเบรกชั้นเรียน ฉันเปิดใช้งานพวกเขาทั้งหมดในครั้งเดียว onload

$('body').popover({selector: '.activate-popover', html : true, container: 'body'})

เพื่อให้ฟังก์ชั่น Click Away ใช้งานได้ฉันใช้ (ใน coffee script)

$(document).on('click', (e) ->
  clickedOnActivate = ($(e.target).parents().hasClass("activate-popover") || $(e.target).hasClass("activate-popover"))
  clickedAway = !($(e.target).parents().hasClass("popover") || $(e.target).hasClass("popover"))
if clickedAway && !clickedOnActivate
  $(".popover.in").prev().popover('hide')
if clickedOnActivate 
  $(".popover.in").prev().each () ->
    if !$(this).is($(e.target).closest('.activate-popover'))
      $(this).popover('hide')
)

ซึ่งทำงานได้ดีอย่างสมบูรณ์แบบด้วย bootstrap 2.3.1


สิ่งนี้ได้ผลสำหรับฉันยกเว้นว่าฉันต้องกำจัด.prev()ในifประโยคแรก ฉันใช้ Bootstrap 3.2.0.2 อาจมีความแตกต่างหรือไม่? นอกจากนี้คุณยังสามารถละทิ้งifประโยคที่สองทั้งหมดหากคุณต้องการที่จะเปิดป๊อปอัปหลายรายการพร้อมกัน เพียงคลิกที่ใดก็ได้ที่ไม่ใช่องค์ประกอบป๊อปโอเวอร์เปิดใช้งาน (คลาส 'เปิดใช้งาน popover' ในตัวอย่างนี้) เพื่อปิดป๊อปอัปที่เปิดอยู่ทั้งหมด ใช้งานได้ดี!
Andrew Swihart

2

แม้ว่าจะมีวิธีแก้ปัญหามากมายที่นี่ฉันอยากจะเสนอของฉันเช่นกันฉันไม่รู้ว่ามีวิธีแก้ปัญหาอยู่ตรงนั้นที่แก้ได้ทั้งหมดหรือไม่ แต่ฉันลองพวกเขา 3 ข้อและพวกเขามีปัญหาเช่นคลิก บน popover มันทำให้มันซ่อนตัวเอง, อื่น ๆ ที่ถ้าฉันมีปุ่ม popover อื่นที่คลิกทั้งสอง / หลาย popovers จะยังคงปรากฏ (เช่นในโซลูชันที่เลือก), เคย, อันนี้แก้ไขได้ทั้งหมด

var curr_popover_btn = null;
// Hide popovers function
function hide_popovers(e)
{
    var container = $(".popover.in");
    if (!container.is(e.target) // if the target of the click isn't the container...
        && container.has(e.target).length === 0) // ... nor a descendant of the container
    {
        if( curr_popover_btn != null )
        {
            $(curr_popover_btn).popover('hide');
            curr_popover_btn = null;
        }
        container.hide();
    }
}
// Hide popovers when out of focus
$('html').click(function(e) {
    hide_popovers(e);
});
$('.popover-marker').popover({
    trigger: 'manual'
}).click(function(e) {
    hide_popovers(e);
    var $popover_btns = $('.popover-marker');
    curr_popover_btn = this;
    var $other_popover_btns = jQuery.grep($($popover_btns), function(popover_btn){
                return ( popover_btn !== curr_popover_btn );
            });
    $($other_popover_btns).popover('hide');
    $(this).popover('toggle');
    e.stopPropagation();
});

2

ฉันจะตั้งโฟกัสไปที่ป๊อปอัปที่สร้างขึ้นใหม่และลบออกด้วยความพร่ามัว วิธีนี้ไม่จำเป็นต้องตรวจสอบว่าองค์ประกอบใดของ DOM ที่ถูกคลิกและสามารถคลิกและเลือกป๊อปอัปได้เช่นกัน: มันจะไม่สูญเสียโฟกัสและจะไม่หายไป

รหัส:

    $('.popup-marker').popover({
       html: true,
       trigger: 'manual'
    }).click(function(e) {
       $(this).popover('toggle');
       // set the focus on the popover itself 
       jQuery(".popover").attr("tabindex",-1).focus();
       e.preventDefault();
    });

    // live event, will delete the popover by clicking any part of the page
    $('body').on('blur','.popover',function(){
       $('.popup-marker').popover('hide');
    });

1

นี่เป็นวิธีแก้ปัญหาที่ใช้งานได้ดีมากสำหรับฉันถ้ามันสามารถช่วย

/**
* Add the equals method to the jquery objects
*/
$.fn.equals = function(compareTo) {
  if (!compareTo || this.length !== compareTo.length) {
    return false;
  }
  for (var i = 0; i < this.length; ++i) {
    if (this[i] !== compareTo[i]) {
      return false;
    }
  }
  return true;
};

/**
 * Activate popover message for all concerned fields
 */
var popoverOpened = null;
$(function() { 
    $('span.btn').popover();
    $('span.btn').unbind("click");
    $('span.btn').bind("click", function(e) {
        e.stopPropagation();
        if($(this).equals(popoverOpened)) return;
        if(popoverOpened !== null) {
            popoverOpened.popover("hide");            
        }
        $(this).popover('show');
        popoverOpened = $(this);
        e.preventDefault();
    });

    $(document).click(function(e) {
        if(popoverOpened !== null) {
            popoverOpened.popover("hide");   
            popoverOpened = null;
        }        
    });
});

1

นี่คือทางออกของฉันสำหรับสิ่งที่คุ้มค่า:

// Listen for clicks or touches on the page
$("html").on("click.popover.data-api touchend.popover.data-api", function(e) {

  // Loop through each popover on the page
  $("[data-toggle=popover]").each(function() {

    // Hide this popover if it's visible and if the user clicked outside of it
    if ($(this).next('div.popover:visible').length && $(".popover").has(e.target).length === 0) {
      $(this).popover("hide");
    }

  });
});

1

ฉันมีปัญหาบางอย่างเพื่อให้มันทำงานบน bootstrap 2.3.2 แต่ฉันทำอย่างนี้:

$(function () {
  $(document).mouseup(function (e) {
        if(($('.popover').length > 0) && !$(e.target).hasClass('popInfo')) {
            $('.popover').each(function(){
                $(this).prev('.popInfo').popover('hide');
            });
        }
    });

    $('.popInfo').popover({
        trigger: 'click',
        html: true
    });
});

1

tweaked @David Wolever solution เล็กน้อย:

function closePopoversOnDocumentEvents() {
  var visiblePopovers = [];

  var $body = $("body");

  function hideVisiblePopovers() {
    /* this was giving problems and had a bit of overhead
      $.each(visiblePopovers, function() {
        $(this).popover("hide");
      });
    */
    while (visiblePopovers.length !== 0) {
       $(visiblePopovers.pop()).popover("hide");
    }
  }

  function onBodyClick(event) {
    if (event.isDefaultPrevented())
      return;

    var $target = $(event.target);
    if ($target.data("bs.popover"))
      return;

    if ($target.parents(".popover").length)
      return;

    hideVisiblePopovers();
  }

  function onBodyKeyup(event) {
    if (event.isDefaultPrevented())
      return;

    if (event.keyCode != 27) // esc
      return;

    hideVisiblePopovers();
    event.preventDefault();
  }

  function onPopoverShow(event) {
    if (!visiblePopovers.length) {
      $body.on("click", onBodyClick);
      $body.on("keyup", onBodyKeyup);
    }
    visiblePopovers.push(event.target);
  }

  function onPopoverHide(event) {
    var target = event.target;
    var index = visiblePopovers.indexOf(target);
    if (index > -1) {
      visiblePopovers.splice(index, 1);
    }
    if (visiblePopovers.length == 0) {
      $body.off("click", onBodyClick);
      $body.off("keyup", onBodyKeyup);
    }
  }

  $body.on("show.bs.popover", onPopoverShow);
  $body.on("hide.bs.popover", onPopoverHide);
}

1

คำถามนี้ถูกถามที่นี่และคำตอบของฉันไม่เพียง แต่เป็นวิธีการทำความเข้าใจวิธีการสำรวจเส้นทาง jQuery DOM แต่ยังมี 2 ตัวเลือกสำหรับจัดการการปิดป๊อปอัปโดยคลิกที่ด้านนอก

เปิด popovers หลายรายการพร้อมกันหรือหนึ่ง popover ต่อครั้ง

นอกจากนี้ข้อมูลโค้ดขนาดเล็กเหล่านี้สามารถจัดการการปิดปุ่มที่มีไอคอนได้!

https://stackoverflow.com/a/14857326/1060487


1

อันนี้ใช้งานได้อย่างมีเสน่ห์และฉันใช้มัน

มันจะเปิด popover เมื่อคุณคลิกและถ้าคุณคลิกอีกครั้งมันจะปิดลงเช่นกันหากคุณคลิกที่ด้านนอกของ popover ตัว popover จะถูกปิด

สิ่งนี้ใช้ได้กับป๊อปโอเวอร์มากกว่า 1 แห่ง

    function hideAllPopovers(){
    $('[data-toggle="popover"]').each(function() {
        if ($(this).data("showing") == "true"){
            $(this).data("showing", "false");
            $(this).popover('hide');                
        }
    });
}
$('[data-toggle="popover"]').each(function() {
        $(this).popover({
            html: true,
            trigger: 'manual'
        }).click(function(e) {
            if ($(this).data("showing") !=  "true"){
                hideAllPopovers();
                $(this).data("showing", "true");
                $(this).popover('show');
            }else{
                hideAllPopovers();
            }
            e.stopPropagation();
        });
});

$(document).click(function(e) {
    hideAllPopovers();
});

นี่เป็นคนเดียวที่ทำงานให้ฉัน Bootstrap 3.20 ขอบคุณ.
Telegard

1

วิธีแก้ปัญหาอื่นก็ครอบคลุมปัญหาที่ฉันมีเมื่อคลิกที่ลูกหลานของ popover:

$(document).mouseup(function (e) {
    // The target is not popover or popover descendants
    if (!$(".popover").is(e.target) && 0 === $(".popover").has(e.target).length) {
        $("[data-toggle=popover]").popover('hide');
    }
});

0

ฉันทำมันดังต่อไปนี้

$("a[rel=popover]").click(function(event){
    if(event.which == 1)
    {   
        $thisPopOver = $(this);
        $thisPopOver.popover('toggle');
        $thisPopOver.parent("li").click(function(event){
            event.stopPropagation();
            $("html").click(function(){
                $thisPopOver.popover('hide');
            });
        });
    }
});

หวังว่านี่จะช่วยได้!


0

หากคุณกำลังพยายามใช้ twitter bootstrap popover กับ pjax สิ่งนี้ใช้ได้สำหรับฉัน:

App.Utils.Popover = {

  enableAll: function() {
    $('.pk-popover').popover(
      {
        trigger: 'click',
        html : true,
        container: 'body',
        placement: 'right',
      }
    );
  },

  bindDocumentClickEvent: function(documentObj) {
    $(documentObj).click(function(event) {
      if( !$(event.target).hasClass('pk-popover') ) {
        $('.pk-popover').popover('hide');
      }
    });
  }

};

$(document).on('ready pjax:end', function() {
  App.Utils.Popover.enableAll();
  App.Utils.Popover.bindDocumentClickEvent(this);
});

0

@ RayOnAir ฉันมีปัญหาเดียวกันกับวิธีแก้ไขปัญหาก่อนหน้า ฉันเข้าใกล้โซลูชัน @RayOnAir ด้วย สิ่งหนึ่งที่ได้รับการปรับปรุงคือปิดป็อปอัพที่เปิดแล้วเมื่อคลิกที่เครื่องหมายผุดขึ้นอื่น ดังนั้นรหัสของฉันคือ:

var clicked_popover_marker = null;
var popover_marker = '#pricing i';

$(popover_marker).popover({
  html: true,
  trigger: 'manual'
}).click(function (e) {
  clicked_popover_marker = this;

  $(popover_marker).not(clicked_popover_marker).popover('hide');
  $(clicked_popover_marker).popover('toggle');
});

$(document).click(function (e) {
  if (e.target != clicked_popover_marker) {
    $(popover_marker).popover('hide');
    clicked_popover_marker = null;
  }
});

0

ฉันพบว่านี่เป็นโซลูชันที่แก้ไขแล้วของคำแนะนำของ pbaron ด้านบนเนื่องจากโซลูชันของเขาเปิดใช้งาน popover ('ซ่อน') ในองค์ประกอบทั้งหมดที่มีคลาส 'popup-marker' อย่างไรก็ตามเมื่อคุณใช้ popover () สำหรับเนื้อหา html แทนที่จะเป็น data-content อย่างที่ฉันทำอยู่การคลิกใด ๆ ภายใน html popup นั้นจะเป็นการเปิดใช้งาน popover ('ซ่อน') ซึ่งจะปิดหน้าต่างทันที วิธีการด้านล่างนี้จะทำซ้ำผ่านองค์ประกอบ. popup-marker แต่ละรายการและค้นพบก่อนหากผู้ปกครองเกี่ยวข้องกับรหัส. popup-marker ของผู้ที่ถูกคลิกและหากเป็นเช่นนั้นจะไม่ซ่อน div อื่น ๆ ทั้งหมดถูกซ่อนอยู่ ...

        $(function(){
            $('html').click(function(e) {
                // this is my departure from pbaron's code above
                // $('.popup-marker').popover('hide');
                $('.popup-marker').each(function() {
                    if ($(e.target).parents().children('.popup-marker').attr('id')!=($(this).attr('id'))) {
                        $(this).popover('hide');
                    }
                });
            });

            $('.popup-marker').popover({
                html: true,
                // this is where I'm setting the html for content from a nearby hidden div with id="html-"+clicked_div_id
                content: function() { return $('#html-'+$(this).attr('id')).html(); },
                trigger: 'manual'
            }).click(function(e) {
                $(this).popover('toggle');
                e.stopPropagation();
            });
        });

0

ฉันมากับสิ่งนี้:

สถานการณ์ของฉันรวมป๊อปอัปมากขึ้นในหน้าเดียวกันและซ่อนมันทำให้พวกเขามองไม่เห็นและด้วยเหตุนี้การคลิกที่รายการที่อยู่เบื้องหลังป๊อปโอเวอร์จึงไม่สามารถทำได้ แนวคิดคือการทำเครื่องหมายเฉพาะ popover-link เป็น 'active' และจากนั้นคุณสามารถ 'toggle' popover ที่ใช้งานอยู่ การทำเช่นนั้นจะปิดป๊อปโอเวอร์อย่างสมบูรณ์

$('.popover-link').popover({ html : true, container: 'body' })

$('.popover-link').popover().on 'shown.bs.popover', ->
  $(this).addClass('toggled')

$('.popover-link').popover().on 'hidden.bs.popover', ->
  $(this).removeClass('toggled')

$("body").on "click", (e) ->
  $openedPopoverLink = $(".popover-link.toggled")
  if $openedPopoverLink.has(e.target).length == 0
    $openedPopoverLink.popover "toggle"
    $openedPopoverLink.removeClass "toggled"

0

ฉันพยายามหาวิธีแก้ปัญหาง่ายๆสำหรับปัญหาง่ายๆ โพสต์ด้านบนนั้นดี แต่ก็ซับซ้อนสำหรับปัญหาง่ายๆ ดังนั้นฉันจึงทำสิ่งที่ง่าย เพิ่งเพิ่มปุ่มปิด มันสมบูรณ์แบบสำหรับฉัน

            $(".popover-link").click(function(){
                $(".mypopover").hide();
                $(this).parent().find(".mypopover").show();
        })
        $('.close').click(function(){
    $(this).parents('.mypopover').css('display','none');
});



          <div class="popover-content">
        <i class="fa fa-times close"></i>
    <h3 class="popover-title">Title here</h3>
your other content here
        </div>


   .popover-content {
    position:relative;
    }
    .close {
        position:absolute;
        color:#CCC;
        right:5px;
        top:5px;
        cursor:pointer;
    }

0

ฉันชอบสิ่งนี้เรียบง่าย แต่มีประสิทธิภาพ ..

var openPopup;

$('[data-toggle="popover"]').on('click',function(){
    if(openPopup){
        $(openPopup).popover('hide');

    }
    openPopup=this;
});

0

เพิ่มbtn-popoverคลาสให้กับปุ่ม / ลิงก์ของคุณที่เปิดขึ้นมา รหัสนี้จะปิดป๊อปอัปเมื่อคลิกด้านนอก

$('body').on('click', function(event) {
  if (!$(event.target).closest('.btn-popover, .popover').length) {
    $('.popover').popover('hide');
  }
});

0

วิธีการแก้ปัญหาที่ง่ายยิ่งขึ้นเพียงย้ำผ่าน popovers thisและหากไม่ได้ซ่อน

$(document).on('click', '.popup-marker', function() {
    $(this).popover('toggle')
})

$(document).bind('click touchstart', function(e) {
    var target = $(e.target)[0];
    $('.popup-marker').each(function () {
        // hide any open popovers except for the one we've clicked
        if (!$(this).is(target)) {
            $(this).popover('hide');
        }
    });
});

0
$('.popForm').popover();

$('.conteneurPopForm').on("click",".fermePopover",function(){
    $(".popForm").trigger("click");
});

เพื่อให้ชัดเจนเพียงแค่เรียกป๊อปโอเวอร์


0

สิ่งนี้จะทำงานใน Bootstrap 4:

$("#my-popover-trigger").popover({
  template: '<div class="popover my-popover-content" role="tooltip"><div class="arrow"></div><div class="popover-body"></div></div>',
  trigger: "manual"
})

$(document).click(function(e) {
  if ($(e.target).closest($("#my-popover-trigger")).length > 0) {
    $("#my-popover-trigger").popover("toggle")
  } else if (!$(e.target).closest($(".my-popover-content")).length > 0) {
    $("#my-popover-trigger").popover("hide")
  }
})

คำอธิบาย:

  • ส่วนแรกจะแสดงป๊อปโอเวอร์ตามเอกสาร: https://getbootstrap.com/docs/4.0/components/popovers/
  • "if" ตัวแรกในส่วนที่สองตรวจสอบว่าองค์ประกอบที่ถูกคลิกนั้นเป็นลูกหลานของ # my-popover-trigger หรือไม่ หากเป็นเช่นนั้นจริงมันจะสลับป็อปโอเวอร์ (จัดการกับการคลิกที่ทริกเกอร์)
  • "if" อันที่สองในส่วนที่สองตรวจสอบว่าอิลิเมนต์ที่ถูกคลิกเป็นผู้สืบทอดของคลาสเนื้อหา popover ซึ่งกำหนดไว้ในเทมเพลต init หรือไม่ หากไม่เป็นเช่นนี้หมายความว่าการคลิกไม่ได้อยู่ในเนื้อหาของป๊อปโอเวอร์และสามารถซ่อนป๊อปอัปได้

คุณช่วยอธิบายเกี่ยวกับรหัสของคุณได้ไหม? เพิ่มคำอธิบายให้กับสิ่งที่คุณทำหรือไม่
Death Waltz

@DeathWaltz ฉันเพิ่งเพิ่มคำอธิบายในคำตอบ
Bart Blast

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.