[javascript] 페이지의 아무 곳이나 클릭하여 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');
});

페이지의 다른 곳을 클릭하면 팝 오버를 닫을 수 있지만 팝 오버 자체를 클릭하면 어떻게됩니까?



답변

언제든지 하나의 팝 오버 만 표시 될 수 있다고 가정하면 플래그 세트를 사용하여 팝 오버가 표시 될 때 표시 한 다음 숨길 수 있습니다.

문서 본문에서 이벤트 리스너를 설정하면 ‘팝업 마커’로 표시된 요소를 클릭 할 때 트리거됩니다. 따라서 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 개의 팝 오버를 열 수 없다는 것입니다. 그러나 어쨌든 그것은 사용자에게 혼란 스러울 것이라고 생각합니다 🙂


답변

이것은 훨씬 쉽다 :

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

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


답변

비슷한 요구가 있었고 Lee Carmichael의 BootstrapX-clickover라는 Twitter Bootstrap Popover의 작은 확장 기능을 발견했습니다 . 또한 여기에 몇 가지 사용 예가 있습니다 . 기본적으로 팝업은 대화 형 구성 요소로 변경되어 페이지의 다른 곳을 클릭하거나 팝업 내 닫기 버튼을 클릭하면 닫힙니다. 또한 여러 팝 오버가 한 번에 열리고 다른 멋진 기능도 많이 제공됩니다.

플러그인은 여기에서 찾을 수 있습니다 .

사용 예

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

자바 스크립트 :

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


답변

허용 된 솔루션으로 몇 가지 문제가 발생했습니다 (열린 팝 오버의 ‘.popup-marker’요소를 클릭하면 팝 오버가 나중에 작동하지 않습니다). 나는 나를 위해 완벽하게 작동하는이 다른 솔루션을 생각해 냈고 매우 간단합니다 (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');
    }
});

업데이트 :이 코드는 Bootstrap 3에서도 작동합니다!


답변

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>


답변

기존의 모든 답변은 모든 문서 이벤트를 캡처 한 다음 활성 팝 오버를 찾거나에 대한 호출을 수정하므로 상당히 약 합니다 .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);
}


답변

https://github.com/lecar-red/bootstrapx-clickover

그것은 트위터 부트 스트랩 팝 오버의 확장이며 문제를 매우 간단하게 해결할 것입니다.