Làm cách nào tôi có thể đóng cửa sổ bật lên Twitter Bootstrap bằng một cú nhấp chuột từ bất kỳ đâu (khác) trên trang?


154

Tôi hiện đang sử dụng popovers với Twitter Bootstrap, được bắt đầu như thế này:

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

Như bạn có thể thấy, chúng được kích hoạt theo cách thủ công và nhấp vào .popup-Marker (là một div có hình nền) để bật một popover. Điều này hoạt động rất tốt, nhưng tôi cũng muốn có thể đóng cửa sổ bật lên bằng một cú nhấp chuột ở bất kỳ nơi nào khác trên trang (nhưng không phải trên chính cửa sổ bật lên!).

Tôi đã thử một vài thứ khác nhau, bao gồm những thứ sau đây, nhưng không có kết quả nào cho thấy:

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

Làm cách nào tôi có thể đóng cửa sổ bật lên bằng một nhấp chuột ở bất kỳ nơi nào khác trên trang, nhưng không phải với một nhấp chuột onthe chính nó?


Hừm, tôi sẽ nghĩ rằng nó sẽ hoạt động ... bạn có liên kết đến trực tuyến này không?
thatryan

Câu trả lời:


102

Giả sử rằng chỉ có thể nhìn thấy một cửa sổ bật lên bất cứ lúc nào, bạn có thể sử dụng một bộ cờ để đánh dấu khi có một cửa sổ bật lên hiển thị và chỉ sau đó ẩn chúng.

Nếu bạn đặt trình nghe sự kiện trên thân tài liệu, nó sẽ kích hoạt khi bạn nhấp vào phần tử được đánh dấu bằng 'cửa sổ bật lên'. Vì vậy, bạn sẽ phải gọi stopPropagation()đối tượng sự kiện. Và áp dụng thủ thuật tương tự khi nhấp vào chính popover.

Dưới đây là một mã JavaScript hoạt động để làm điều này. Nó sử dụng 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/

Nhắc nhở duy nhất là bạn sẽ không thể mở 2 cửa sổ bật lên cùng một lúc. Nhưng tôi nghĩ rằng điều đó sẽ gây nhầm lẫn cho người dùng, dù sao :-)


1
Nhấp vào chính popover trong jsfiddle đó làm cho popover ẩn - không hoàn toàn những gì tnorthcutt yêu cầu.
Đồi Jonathon

1
@RaduCugut đó là một giải pháp tuyệt vời. Nhưng nó có một lỗi. Nhấp một lần vào zzzzz và cửa sổ bật lên xuất hiện. Bây giờ bấm một lần trên nền trắng. Cửa sổ bật lên biến mất. Bây giờ bấm lại trên nền trắng. Và bây giờ bấm lại vào zzzz và nó không hoạt động. : - |
Houman

1
@ Hãy nói đúng, tôi đã sửa đổi câu đố và câu trả lời để sửa lỗi này. jsfiddle.net/AFffL/177
Radu Cugut

3
Tại sao không chỉ chạy $ ('. Cửa sổ bật lên')
Nathan Hangen

1
Giải pháp này đã cho tôi một số vấn đề (nhấp vào yếu tố '.popup-Marker' của cửa sổ bật lên đã mở khiến cho các cửa sổ bật lên không hoạt động sau đó). Tôi đã đưa ra một giải pháp khác (được đăng dưới đây) có hiệu quả với tôi và có vẻ đơn giản hơn (tôi đang sử dụng Bootstrap 2.3.1).
RayOnAir

76

Điều này thậm chí còn dễ dàng hơn:

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

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

Đã đồng ý. Và ít nhất với tôi, đó là cách đúng đắn để làm điều đó. Tùy chọn đầu tiên dường như là một "sửa chữa nhanh".
Denis Lins

4
Muốn sử dụng cái này nhưng vì lý do nào đó đã không thành công. Các sự kiện nhấp chuột không bao giờ đạt được htmle.stopPropagation();Thay vào đó, tôi đã sử dụng một cái gì đó giống như $('.popup-marker').on('show', function(event) { $('.popup-marker').filter(function(index, element) { return element != event.target; }).popover('hide'); });công việc đó cũng rất tốt (không biết có sự khác biệt về hiệu suất hay không)
Cornelis

1
Đây là câu trả lời tốt nhất IMO.
Loolooii

1
Việc tổng hợp các câu trả lời của @pbaron và @Cornelis hoạt động tốt nhất. Những gì tôi đã thêm là mã Cornelis bên trong chức năng 'nhấp chuột' thứ hai (ngay trước $(this).popover('toggle');phần. Sau đó, nếu bạn có nhiều đối tượng 'cửa sổ bật lên', nhấp vào từng đối tượng sẽ đóng các đối tượng khác.
alekwisnia

2
Một vấn đề với điều này là popover vẫn còn đó, chỉ là ẩn. Vì vậy, ví dụ nếu bạn có các liên kết trong cửa sổ bật lên, bạn có thể di con trỏ của mình đến nơi nó đã từng và vẫn nhận được thay đổi con trỏ trên các liên kết đó.
Glacials

48

Tôi có một nhu cầu tương tự, và tìm thấy phần mở rộng nhỏ tuyệt vời này của Twitter Bootstrap Popover của Lee Carmichael, được gọi là BootstrapX - clickover . Ông cũng có một số ví dụ sử dụng ở đây . Về cơ bản, nó sẽ thay đổi cửa sổ bật lên thành một thành phần tương tác sẽ đóng khi bạn nhấp vào nơi khác trên trang hoặc trên nút đóng trong cửa sổ bật lên. Điều này cũng sẽ cho phép nhiều cửa sổ mở cùng một lúc và một loạt các tính năng hay khác.

Plugin có thể được tìm thấy ở đây .

Ví dụ sử dụng

<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
Điều này thực sự tuyệt vời. Siêu dễ.
Doug

Plugin tuyệt vời! Cảm ơn các liên kết.
Matt Wilson

1
Chỉ cần cho nó một shot và nó hoạt động tuyệt vời. Dễ dàng như việc thay đổi rel của popover hiện tại từ "popover" thành "clickover".
Dmase05

Chạy trên Bootstrap v2.3.1, không có vấn đề gì.
Kevin Dewalt

37

Giải pháp được chấp nhận đã cho tôi một số vấn đề (nhấp vào yếu tố '.popup-Marker' của cửa sổ bật lên đã mở khiến cho cửa sổ bật lên không hoạt động sau đó). Tôi đã đưa ra giải pháp khác phù hợp với tôi và nó khá đơn giản (Tôi đang sử dụng 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');
    }
});

CẬP NHẬT: Mã này cũng hoạt động với Bootstrap 3!


1
Đây là một giải pháp tuyệt vời. Cảm ơn bạn.
Gavin

1
Giải pháp tốt. Tại sao bạn không sử dụng if (!$(e.target).is('.popup-marker') && !$(e.target).parents('.popover').length > 0)theo cách đó, cửa sổ bật lên sẽ không đóng ngay cả khi nó có nội dung html
ykay nói Rebstate Monica

2
Hoặc tốt hơnif (!$(e.target).is('.popup-marker') && $(e.target).closest('.popover').length === 0)
fabdoumund 8/11/2016

19

đọc "Loại bỏ lần nhấp tiếp theo" tại đây http://getbootstrap.com/javascript/#popovers

Bạn có thể sử dụng trình kích hoạt tiêu điểm để loại bỏ cửa sổ bật lên ở lần nhấp tiếp theo, nhưng bạn phải sử dụng <a>thẻ chứ không phải <button>thẻ và bạn cũng phải bao gồm một tabindexthuộc tính ...

Thí dụ:

<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
Câu hỏi nói rằng anh ta không muốn loại bỏ nếu nhấp chuột vào cửa sổ bật lên. Điều này loại bỏ nó trên bất kỳ nhấp chuột bất cứ nơi nào.
Fred

1
Việc thêm data-trigger = "tập trung" đã ngăn các cửa sổ bật lên của tôi khởi chạy cho đến khi tôi đọc bài đăng này và thêm thuộc tính tabindex. Bây giờ nó hoạt động!
PixelGraph

2
Đối với thông tin, điều này cũng hoạt động với tooltip, ngay cả khi nó không được đề cập rõ ràng trên tài liệu thực tế.
AlexB

7

Tất cả các câu trả lời hiện có đều khá yếu, vì chúng dựa vào việc nắm bắt tất cả các sự kiện tài liệu sau đó tìm các cửa sổ bật lên hoạt động hoặc sửa đổi cuộc gọi thành .popover().

Cách tiếp cận tốt hơn nhiều là lắng nghe các show.bs.popoversự kiện trên cơ thể của tài liệu sau đó phản ứng tương ứng. Dưới đây là mã sẽ đóng cửa sổ bật lên khi tài liệu được nhấp hoặc escđược nhấn, chỉ ràng buộc người nghe sự kiện khi cửa sổ bật lên được hiển thị:

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 Đây là giải pháp sạch nhất và có thể mở rộng nhất. Nếu bạn cũng đang sử dụng một khung như xương sống, chỉ cần bỏ mã này vào mã khởi tạo của bạn và nó sẽ đảm nhiệm việc xử lý các cửa sổ bật lên.
JohnP

Câu trả lời này cũng thêm mối quan tâm về hiệu suất và nó cho phép xử lý HTML phức tạp hơn trong cửa sổ bật lên.
Ricardo

Giải pháp tuyệt vời; đã có thể thả nó vào một phương pháp phản ứng khá dễ dàng. Một đề xuất, thêm $(event.target).data("bs.popover").inState.click = false;vào chức năng onPopoverHide để bạn không cần nhấp hai lần để mở lại sau khi đóng.
sco_tt

Tò mò nếu bạn có thể thực hiện một điều thú vị về điều này với hai cửa sổ bật lên. Trong ứng dụng của tôi khi tôi triển khai mã của bạn, tôi có thể nhấp vào cửa sổ bật lên để bật lên và nhiều lần xuất hiện, sau đó nhấp vào 'cơ thể' chỉ xóa cái cuối cùng được hiển thị.
Terry


2

Vì một số lý do, không có giải pháp nào khác ở đây làm việc cho tôi. Tuy nhiên, sau rất nhiều lần khắc phục sự cố, cuối cùng tôi đã tìm ra phương pháp này hoạt động hoàn hảo (ít nhất là đối với tôi).

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

Trong trường hợp của tôi, tôi đã thêm một popover vào một bảng và hoàn toàn định vị nó ở trên / bên dưới tdcái được nhấp. Việc lựa chọn bảng được xử lý bởi jQuery-UI Có thể chọn vì vậy tôi không chắc liệu điều đó có gây nhiễu hay không. Tuy nhiên, bất cứ khi nào tôi nhấp vào bên trong cửa sổ bật lên, trình xử lý nhấp chuột của tôi nhắm mục tiêu $('.popover')không bao giờ hoạt động và việc xử lý sự kiện luôn được ủy quyền cho $(html)trình xử lý nhấp chuột. Tôi khá mới với JS nên có lẽ tôi chỉ thiếu một cái gì đó?

Dù sao tôi hy vọng điều này sẽ giúp ai đó!


BTW Tôi không chắc nó có vấn đề gì không, nhưng tôi đã sử dụng phương pháp này cho Bootstrap 2. Tôi cho rằng nó sẽ hoạt động cho Bootstrap 3, nhưng chưa được xác nhận.
moollaza

2

Tôi cung cấp cho tất cả các popovers neo của tôi lớp activate_popover. Tôi kích hoạt tất cả chúng cùng một lúc

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

để có được chức năng nhấp đi, tôi sử dụng (trong tập lệnh cà phê):

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

Hoạt động hoàn toàn tốt với bootstrap 2.3.1


Điều này làm việc cho tôi, ngoại trừ việc tôi phải loại bỏ .prev()trong ifmệnh đề đầu tiên . Tôi đang sử dụng Bootstrap 3.2.0.2, có lẽ có sự khác biệt? Ngoài ra, bạn chỉ có thể bỏ qua toàn bộ ifmệnh đề thứ hai nếu bạn muốn có thể mở nhiều cửa sổ bật lên cùng một lúc. Chỉ cần nhấp vào bất cứ nơi nào không phải là phần tử kích hoạt popover (lớp 'kích hoạt-popover' trong ví dụ này) để đóng tất cả các popovers mở. Hoạt động tuyệt vời!
Andrew Swihart

2

Mặc dù có rất nhiều giải pháp ở đây, tôi cũng muốn đề xuất giải pháp của mình, tôi không biết liệu có giải pháp nào trên đó giải quyết được tất cả không, nhưng tôi đã thử 3 trong số chúng và chúng có vấn đề, như nhấp chuột trên cửa sổ bật lên, nó tự làm cho nó ẩn đi, một số khác rằng nếu tôi có một nút bật khác được nhấp cả hai / nhiều cửa sổ bật lên sẽ vẫn xuất hiện (như trong giải pháp đã chọn), Bao giờ, Cái này đã sửa tất cả

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

Tôi sẽ đặt tiêu điểm cho cửa sổ bật lên mới được tạo và xóa nó trên mờ. Bằng cách đó, không cần thiết phải kiểm tra phần tử nào của DOM đã được nhấp và cửa sổ bật lên có thể được nhấp và cũng được chọn: nó sẽ không mất tiêu điểm và sẽ không biến mất.

Mật mã:

    $('.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

Đây là giải pháp hiệu quả với tôi, nếu nó có thể giúp:

/**
* 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

Đây là giải pháp của tôi, cho những gì đáng giá:

// 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

Tôi đã có một số vấn đề để làm cho nó hoạt động trên bootstrap 2.3.2. Nhưng tôi đã làm nó theo cách này:

$(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

tinh chỉnh giải pháp WolD @David một chút:

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

Câu hỏi này cũng đã được hỏi ở đây và câu trả lời của tôi không chỉ cung cấp một cách để hiểu các phương thức truyền tải DOM DOM mà còn có 2 tùy chọn để xử lý việc đóng cửa sổ bật lên bằng cách nhấp vào bên ngoài.

Mở nhiều cửa sổ bật lên cùng một lúc hoặc một cửa sổ bật lên cùng một lúc.

Ngoài ra, các đoạn mã nhỏ này có thể xử lý việc đóng các nút chứa các biểu tượng!

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


1

Cái này hoạt động như một lá bùa và tôi sử dụng nó.

Nó sẽ mở cửa sổ bật lên khi bạn nhấp và nếu bạn nhấp lại, nó sẽ đóng lại, nếu bạn nhấp vào bên ngoài cửa sổ bật lên, cửa sổ bật lên sẽ bị đóng.

Điều này cũng hoạt động với hơn 1 popover.

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

Đây là người duy nhất làm việc cho tôi. Bootstrap 3.20. Cảm ơn bạn.
Telegard

1

Một giải pháp khác, nó bao gồm vấn đề tôi gặp phải khi nhấp vào hậu duệ của 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

Tôi làm như dưới đây

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

Hi vọng điêu nay co ich!


0

Nếu bạn đang cố gắng sử dụng twitter bootstrap popover với pjax, thì điều này hiệu quả với tôi:

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, tôi có vấn đề tương tự với các giải pháp trước đây. Tôi cũng đến gần với giải pháp @RayOnAir. Một điều được cải thiện là đóng popover đã mở khi nhấp vào điểm đánh dấu popover khác. Vì vậy, mã của tôi là:

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

Tôi thấy đây là một giải pháp đã được sửa đổi của đề xuất của pbaron ở trên, bởi vì giải pháp của anh ấy đã kích hoạt cửa sổ bật lên ('ẩn') trên tất cả các thành phần có lớp 'cửa sổ bật lên'. Tuy nhiên, khi bạn đang sử dụng popover () cho nội dung html thay vì nội dung dữ liệu, như tôi đang làm bên dưới, bất kỳ nhấp chuột nào trong cửa sổ bật lên html đó thực sự kích hoạt cửa sổ bật lên ('ẩn'), sẽ đóng cửa sổ ngay lập tức. Phương thức này bên dưới lặp lại qua từng phần tử .popup-mark và phát hiện ra đầu tiên nếu cha mẹ có liên quan đến id .popup-marker đã được nhấp và nếu vậy thì không ẩn nó. Tất cả các div khác đều bị ẩn ...

        $(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

Tôi nghĩ ra cái này:

Kịch bản của tôi bao gồm nhiều cửa sổ bật lên trên cùng một trang và việc ẩn chúng chỉ khiến chúng trở nên vô hình và vì thế, việc nhấp vào các mục phía sau cửa sổ bật lên là không thể. Ý tưởng là đánh dấu liên kết popover cụ thể là 'hoạt động' và sau đó bạn có thể chỉ cần 'chuyển đổi' cửa sổ bật lên đang hoạt động. Làm như vậy sẽ đóng cửa popover hoàn toàn.

$('.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

Tôi đã cố gắng thực hiện một giải pháp đơn giản cho một vấn đề đơn giản. Trên bài viết là tốt nhưng rất phức tạp cho một vấn đề đơn giản. Vì vậy, tôi đã làm một điều đơn giản. Chỉ cần thêm một nút đóng. Nó hoàn hảo cho tôi.

            $(".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

Tôi thích điều này, đơn giản nhưng hiệu quả ..

var openPopup;

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

    }
    openPopup=this;
});

0

Thêm btn-popoverlớp vào nút / liên kết popover của bạn để mở popover. Mã này sẽ đóng cửa sổ bật lên khi nhấp vào bên ngoài nó.

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

0

Một giải pháp thậm chí còn dễ dàng hơn, chỉ cần lặp qua tất cả các cửa sổ bật lên và ẩn nếu không 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");
});

Để rõ ràng, chỉ cần kích hoạt popover


0

Điều này sẽ hoạt động trong 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")
  }
})

Giải trình:

  • Phần đầu tiên nhập vào popover theo tài liệu: https://getbootstrap.com/docs/4.0/components/popovers/
  • "Nếu" đầu tiên trong phần thứ hai kiểm tra xem phần tử được nhấp có phải là hậu duệ của # my-popover-trigger hay không. Nếu đó là sự thật, nó sẽ bật tắt popover (nó xử lý nhấp chuột vào trình kích hoạt).
  • "Nếu" thứ hai trong phần thứ hai kiểm tra xem phần tử được nhấp có phải là hậu duệ của lớp nội dung popover được xác định trong mẫu init không. Nếu không, điều này có nghĩa là nhấp chuột không nằm trong nội dung popover và popover có thể bị ẩn.

Bạn có thể vui lòng giải thích về mã của bạn? Thêm một số lời giải thích cho những gì bạn đang làm?
Death Waltz

@DeathWaltz Tôi vừa thêm lời giải thích trong câu trả lời.
Bart Blast

-1

Hãy thử data-trigger="focus"thay vì "click".

Điều này giải quyết các vấn đề đối với tôi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.