[javascript] 내부 클릭시 드롭 다운 메뉴 닫기를 피하십시오

Twitter Bootstrap 드롭 다운 메뉴가 있습니다. 모든 Twitter Bootstrap 사용자가 알고 있듯이 클릭하면 드롭 다운 메뉴가 닫힙니다 (내부 클릭하더라도).

이를 피하기 위해 드롭 다운 메뉴에서 클릭 이벤트 핸들러를 쉽게 첨부하고 유명한을 추가 할 수 event.stopPropagation()있습니다.

<ul class="nav navbar-nav">
  <li class="dropdown mega-dropdown">
    <a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown">
      <i class="fa fa-list-alt"></i> Menu item 1
      <span class="fa fa-chevron-down pull-right"></span>
    </a>
    <ul class="dropdown-menu mega-dropdown-menu">
      <li>
        <div id="carousel" class="carousel slide" data-ride="carousel">
          <ol class="carousel-indicators">
            <li data-slide-to="0" data-target="#carousel"></li>
            <li class="active" data-slide-to="1" data-target="#carousel"></li>
          </ol>
          <div class="carousel-inner">
            <div class="item">
              <img alt="" class="img-rounded" src="img1.jpg">
            </div>
            <div class="item active">
              <img alt="" class="img-rounded" src="img2.jpg">
            </div>
          </div>
          <a data-slide="prev" role="button" href="#carousel"
             class="left carousel-control">
            <span class="glyphicon glyphicon-chevron-left"></span>
          </a>
          <a data-slide="next" role="button" href="#carousel"
             class="right carousel-control">
            <span class="glyphicon glyphicon-chevron-right"></span>
          </a>
        </div>
      </li>
    </ul>
  </li>
</ul>

이 모습 쉽고 매우 일반적인 행동하지만, 이후 carousel-controls(뿐만 아니라 carousel indicators) 이벤트 핸들러가에 위임하는 document객체는 click이러한 요소에 이벤트 ( 이전은 / 다음 컨트롤은 …) “무시”됩니다.

$('ul.dropdown-menu.mega-dropdown-menu').on('click', function(event){
    // The event won't be propagated up to the document NODE and 
    // therefore delegated events won't be fired
    event.stopPropagation();
});

트위터 부트 스트랩 드롭 다운 hide/ hidden이벤트 에 의존하는 것은 다음과 같은 이유로 해결책이 아닙니다.

  • 두 이벤트 핸들러 모두에 대해 제공된 이벤트 오브젝트가 클릭 한 요소에 대한 참조를 제공하지 않습니다.
  • 드롭 다운 메뉴 내용을 제어 할 수 없으므로 flag클래스 또는 속성을 추가 할 수 없습니다

이 바이올린 은 정상적인 동작 이며이 바이올린 에는 event.stopPropagation()추가 된 기능이 있습니다.

최신 정보

그의 답변에 대한 로마 감사합니다 . 또한 아래에서 찾을 수 있는 답변을 찾았습니다 .



답변

데이터 속성을 제거하고 data-toggle="dropdown"드롭 다운 열기 / 닫기를 구현하는 것이 해결책이 될 수 있습니다.

먼저 링크를 클릭하여 다음과 같이 드롭 다운을 열고 닫으십시오.

$('li.dropdown.mega-dropdown a').on('click', function (event) {
    $(this).parent().toggleClass('open');
});

드롭 다운 외부의 클릭을 듣고 다음과 같이 닫으십시오.

$('body').on('click', function (e) {
    if (!$('li.dropdown.mega-dropdown').is(e.target)
        && $('li.dropdown.mega-dropdown').has(e.target).length === 0
        && $('.open').has(e.target).length === 0
    ) {
        $('li.dropdown.mega-dropdown').removeClass('open');
    }
});

데모는 다음과 같습니다.
http://jsfiddle.net/RomaLefrancois/hh81rhcm/2/


답변

이것도 도움이 될 것입니다

$(document).on('click', 'someyourContainer .dropdown-menu', function (e) {
  e.stopPropagation();
});


답변

부트 스트랩은 다음 기능을 제공합니다.

                 | 이 이벤트는 인스턴스 숨기기 메소드가 발생하면 즉시 시작됩니다.
hide.bs.dropdown | 호출되었습니다. 토글 앵커 요소는
                 | 이벤트의 relatedTarget 속성입니다.

따라서이 기능을 구현하면 드롭 다운을 닫을 수 없습니다.

$('#myDropdown').on('hide.bs.dropdown', function (e) {
    var target = $(e.target);
    if(target.hasClass("keepopen") || target.parents(".keepopen").length){
        return false; // returning false should stop the dropdown from hiding.
    }else{
        return true;
    }
});


답변

가장 좋은 대답은 클래스 드롭 다운 메뉴 뒤에 양식 태그를 넣는 것입니다.

그래서 당신의 코드는

<ul class="dropdown-menu">
  <form>
    <li>
      <div class="menu-item">bla bla bla</div>
    </li>
  </form>
</ul>


답변

나는 또한 해결책을 찾았다.

Twitter Bootstrap Components관련 이벤트 처리기가 document객체에 위임 되었다고 가정하면 연결된 처리기를 반복하고 현재 클릭 한 요소 (또는 부모 중 하나)가 위임 된 이벤트와 관련이 있는지 확인합니다.

$('ul.dropdown-menu.mega-dropdown-menu').on('click', function(event){
    var events = $._data(document, 'events') || {};
    events = events.click || [];
    for(var i = 0; i < events.length; i++) {
        if(events[i].selector) {

            //Check if the clicked element matches the event selector
            if($(event.target).is(events[i].selector)) {
                events[i].handler.call(event.target, event);
            }

            // Check if any of the clicked element parents matches the 
            // delegated event selector (Emulating propagation)
            $(event.target).parents(events[i].selector).each(function(){
                events[i].handler.call(this, event);
            });
        }
    }
    event.stopPropagation(); //Always stop propagation
});

그것이 비슷한 솔루션을 찾는 사람에게 도움이되기를 바랍니다.

도와 주셔서 감사합니다.


답변

도움이 될 수 있습니다.

$("dropdownmenuname").click(function(e){
   e.stopPropagation();
})


답변

$('body').on("click", ".dropdown-menu", function (e) {
    $(this).parent().is(".open") && e.stopPropagation();
});

이것은 모든 조건에서 작동 할 수 있습니다.