source

페이지의 다른 곳에서 클릭하여 트위터 부트스트랩 팝업을 닫으려면 어떻게 해야 합니까?

factcode 2023. 8. 2. 09:26
반응형

페이지의 다른 곳에서 클릭하여 트위터 부트스트랩 팝업을 닫으려면 어떻게 해야 합니까?

나는 현재 다음과 같이 시작된 트위터 부트스트랩과 함께 팝오버를 사용하고 있습니다.

$('.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()이벤트 개체에 있습니다.그리고 팝업 자체를 클릭할 때도 동일한 트릭을 적용합니다.

아래는 이를 수행하는 작동 중인 자바스크립트 코드입니다.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/

단 한 가지 주의할 점은 두 개의 팝오버를 동시에 열 수 없다는 것입니다.하지만 그건 어쨌든 사용자에게 혼란을 줄 거라고 생각해요 :-)

이것은 훨씬 쉽습니다.

$('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의 트위터 부트스트랩 팝오버의 아주 작은 확장판인 부트스트랩 X - 클릭오버를 발견했습니다.그는 또한 여기에 몇 가지 사용 를 가지고 있습니다.기본적으로 페이지의 다른 곳을 클릭하거나 팝업 내의 닫기 버튼을 클릭하면 닫히는 대화형 구성 요소로 팝업이 변경됩니다.이렇게 하면 여러 개의 팝업이 동시에 열리며 여러 가지 다른 멋진 기능을 사용할 수 있습니다.

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

사용 예

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

수락된 솔루션은 저에게 몇 가지 문제를 주었습니다(열린 팝업의 '.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');
    }
});

업데이트: 이 코드는 부트스트랩 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그러면 문서 본문의 이벤트가 그에 따라 반응합니다.다음은 문서를 클릭하거나 누를 때 팝업을 닫고 팝업이 표시될 때 이벤트 수신기만 바인딩하는 코드입니다.

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

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

어떤 이유에서인지 여기 있는 다른 해결책들은 저에게 효과가 없었습니다.하지만 많은 문제를 해결한 후에 (적어도 저에게는) 완벽하게 작동하는 이 방법에 도달했습니다.

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

제 경우에는 테이블에 팝업을 추가하고 테이블 위/아래에 완전히 배치했습니다.td클릭했습니다.테이블 선택은 jQuery-UI Selectable에서 처리했기 때문에 방해가 되었는지 모르겠습니다.가 클릭 를 대상으로 한 핸들러 마다 클릭합니다.$('.popover')작동하지 않았고 이벤트 처리는 항상 다음과 같이 위임되었습니다.$(html)클릭 핸들러.저는 JS가 꽤 생소한데, 혹시 제가 뭔가를 놓치고 있는 것은 아닐까요?

아무튼 이게 누군가에게 도움이 되길 바랍니다!

앵커를 맡깁니다.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')
)

부트스트랩 2.3.1에서 완벽하게 작동합니다.

여기에 많은 해결책이 있음에도 불구하고, 저도 제 해결책을 제안하고 싶습니다. 모든 것을 해결할 수 있는 해결책이 있는지 모르겠지만, 저는 그 중 3개를 시도했고 그들은 팝업을 클릭하면 자체가 숨겨지는 등의 문제가 있었습니다. 다른 팝업 버튼을 클릭하면 두 개 모두/여러 팝업이 계속 나타납니다.솔루션 선택), 그러나솔루션이 모든 것을 해결했습니다.

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

새로 만든 팝업에 포커스를 맞추고 블러에서 제거합니다.그런 식으로 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');
    });

다음은 저에게 매우 잘 작동한 솔루션입니다. 도움이 된다면:

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

다음은 제 솔루션입니다.

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

  });
});

부트스트랩 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
    });
});

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

이 질문도 여기서 질문했고 제 답변은 jQuery DOM 통과 방법을 이해하는 방법뿐만 아니라 외부를 클릭하여 팝업 닫기를 처리하는 두 가지 옵션을 제공합니다.

한 번에 여러 개의 팝업을 열거나 한 번에 하나의 팝업을 엽니다.

또한 이 작은 코드 조각들은 아이콘이 포함된 버튼의 닫기를 처리할 수 있습니다!

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

이것은 부적처럼 작동하고 저는 그것을 사용합니다.

클릭하면 팝업이 열리고 다시 클릭하면 팝업이 닫힙니다. 또한 팝업 외부를 클릭하면 팝업이 닫힙니다.

이것은 또한 하나 이상의 팝업에서도 작동합니다.

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

또 다른 해결책은 팝업의 하위 항목을 클릭할 때 발생하는 문제를 다루었습니다.

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

아래와 같이 합니다.

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

이것이 도움이 되길 바랍니다!

만약 당신이 pjax와 함께 twitter 부트스트랩 팝오버를 사용하려고 한다면, 이것은 나에게 효과가 있었습니다.

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

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

나는 이것이 위의 pbaron 제안의 수정된 해결책이라는 것을 발견했는데, 그의 해결책이 클래스 '팝업 마커'가 있는 모든 요소에서 popover('숨기기')를 활성화했기 때문입니다.그러나 아래와 같이 데이터 콘텐츠 대신 html 콘텐츠에 popover()를 사용할 때 해당 html 팝업 내의 클릭은 실제로 popover('숨기기')를 활성화하여 창을 즉시 닫습니다.아래의 이 방법은 각 .popup-marker 요소를 반복하여 부모가 클릭한 .popup-marker의 ID와 관련이 있는지 먼저 검색하고, 관련이 있으면 숨기지 않습니다.다른 모든 디브들은 숨겨져 있습니다...

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

제가 생각해낸 것은 다음과 같습니다.

제 시나리오에는 같은 페이지에 더 많은 팝업이 포함되어 있었고, 이를 숨기기만 하면 보이지 않게 되어 팝업 뒤에 있는 항목을 클릭할 수 없었습니다.이 개념은 특정 팝오버 링크를 '활성'으로 표시한 다음 활성 팝오버를 간단히 '전환'할 수 있습니다.그러면 팝업이 완전히 닫힙니다.

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

저는 간단한 문제에 대한 간단한 해결책을 만들려고 했습니다.위의 게시물들은 좋지만 간단한 문제로는 너무 복잡합니다.그래서 간단한 것을 만들었습니다.닫기 단추를 추가했습니다.저한테 딱 맞습니다.

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

단순하면서도 효과적인 이것이 좋습니다.

var openPopup;

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

    }
    openPopup=this;
});

더하다btn-popover팝업 단추/팝오버를 여는 링크로 클래스를 지정합니다.이 코드는 외부를 클릭할 때 팝업을 닫습니다.

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

더 은 모든 만 하면 .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');
        }
    });
});
$('.popForm').popover();

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

확실하게 말하자면, 그냥 팝업을 트리거합니다.

이것은 부트스트랩 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"는 클릭한 요소가 init 템플릿에 정의된 Popover 컨텐츠 클래스의 하위 요소인지 확인합니다.그렇지 않으면 클릭이 팝업 내용 내부에 없었으므로 팝업이 숨겨질 수 있습니다.

ㅠㅠdata-trigger="focus""click".

이것으로 저는 문제를 해결했습니다.

언급URL : https://stackoverflow.com/questions/8947749/how-can-i-close-a-twitter-bootstrap-popover-with-a-click-from-anywhere-else-on

반응형