javascript - tutorial - bootstrap>;




如何通過點擊頁面上的任何位置(其他位置)來關閉Twitter Bootstrap彈出窗口? (20)

@RayOnAir,我有與以前的解決方案相同的問題。 我也接近@RayOnAir解決方案。 有一點改進就是當點擊其他popover標記時已經接近已經打開的popover。 所以我的代碼是:

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

我目前正在使用Twitter Bootstrap彈出,如下所示:

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

正如你所看到的,它們是手動觸發的,然後點擊.popup-marker(這是一個帶有背景圖片的div)來切換popover。 這很好,但我想也可以通過點擊頁面上的其他任何地方(但不是彈出窗口本身!)來關閉彈出窗口。

我嘗試了一些不同的東西,包括以下內容,但沒有結果顯示它:

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

如何在頁面上的其他任何地方點擊關閉彈出窗口,但不能單擊彈出窗口本身?



假定在任何時候只有一個彈出窗口可見,您可以使用一組標記來標記何時彈出窗口可見,然後才能隱藏它們。

如果您在文檔正文上設置事件偵聽器,當您單擊標有'popup-marker'的元素時,它將觸發。 所以你必須在事件對像上調用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個popovers。 但我認為這會讓用戶感到困惑,無論如何:-)


出於某種原因,這裡沒有其他的解決方案為我工作。 然而,經過很多故障排除之後,我終於到達了這個完美工作的方法(至少對我來說)。

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

在我的例子中,我將一個popover添加到表格中,並且絕對將它定位在被點擊的td上方/下方。 表選擇是由jQuery-UI選擇的,所以我不確定這是乾擾。 然而,無論何時點擊彈出窗口內的目標$('.popover')點擊處理程序都無法工作,並且事件處理總是被委託給$(html)點擊處理程序。 我對JS相當陌生,所以也許我只是錯過了一些東西?

無論如何,我希望這可以幫助別人!


嘗試使用data-trigger="focus"而不是"click"

這解決了我的問題。


如果您嘗試使用pjax的twitter bootstrap popover,這對我有用:

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

微調@David Wolever解決方案:

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

我也有類似的需求,並且發現了Lee Carmichael推出的Twitter Bootstrap Popover的一個很棒的擴展,名為BootstrapX - clickover 。 他here也有一些用法示例。 基本上,它會將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();

我想出了這個:

我的場景在同一頁面上包含更多的彈出窗口,並且隱藏它們只是使它們不可見,因此點擊彈出窗口後面的項目是不可能的。 這個想法是將特定的popover-link標記為“active”,然後您可以簡單地“切換”活動的popover。 這樣做會完全關閉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"

我會將焦點設置為新創建的彈出窗口並將其移除。 這樣就不需要檢查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');
    });

我發現這是上面pbaron的建議的一個修改的解決方案,因為他的解決方案激活了pop'標記'類的所有元素上的彈出窗口('隱藏')。 但是,當你使用popover()代替數據內容的html內容時,正如我在下面所做的那樣,那個html彈出窗口內的任何點擊實際上都會激活popover('hide'),它會立即關閉窗口。 下面的這個方法遍歷每個.popup-marker元素,並首先發現父級是否與被點擊的.popup-marker的id相關,如果是,則不會隱藏它。 所有其他divs被隱藏...

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

我給我的所有popovers錨定了類activate_popover 。 我一下子激活它們

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

獲取我使用的點擊功能(在咖啡腳本中):

$(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可以很好地工作


我這樣做如下

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

希望這可以幫助!


所有現有的答案都相當薄弱,因為它們依賴於捕獲所有文檔事件,然後查找活動彈出窗口,或者將調用修改為.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個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();
});

這個問題也在這裡提出,我的答案不僅提供了一種理解jQuery DOM遍歷方法的方法,還提供了兩種通過單擊外部來處理關閉popovers的選項。

一次打開多個彈出窗口或一次打開一個彈出窗口。

再加上這些小代碼片段可以處理關閉包含圖標的按鈕!

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


這是我的解決方案,它的價值在於:

// 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");
    }

  });
});

這更容易:

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

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

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

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

要清楚,只需觸發popover即可


jQuery(':not(.popup-marker)').once().click(function(){
   jQuery('.popup-marker').hide(); 
});




twitter-bootstrap