2013-05-20 6 views
4

Javascript 기반 탐색 모음 (나는 모바일 친화적 인 곳을 가리키지 않고 클릭하기를 원합니다)에 호 메럴했습니다. HTML, CSS 및 Javascript를 가능한 한 간단하게 만들려고 노력했습니다.jQuery가 일치하지 않는 이유는 무엇입니까? : not (#menu *) "

웹 사이트의 다른 곳을 클릭하면 메뉴 모음을 닫을 때 수신기에 바디를 놓습니다. 나는 당신이 메뉴 막대의 어떤 부분을 클릭하면 그것이 발생하지 않도록 수신기를 필터링하려고합니다. 이는 드롭 다운에서 요소를 클릭 할 때 드롭 다운이 롤백되는 것을 방지하기위한 것입니다.

필자는 아래 matcher가 최상위 메뉴 요소의 자손 인 항목 만 일치시킬 것으로 기대합니다. 왜 이것이 작동하지 않는지에 대한 조언은 대단히 감사하겠습니다.

EDIT : 임의의 함수를 사용하여 거품 발생을 평가하고 이에 대한 조치를 취할 것인지 결정할 수 있음을 이해합니다. 그러나 아래의 .on() 선택자가 아닌 이유에 대해 더 관심이 있습니다. 내가 기대하는대로 일하고있다.

$("body").on("click", ":not(#menu *)", function (e) { 
      $("#menu a").next().slideUp(DROP_DOWN_TIME); 
     }); 

http://jsfiddle.net/auKzt/16/

HTML

<body> 
    <div>HEADER</div> 
    <ul id="menu" class="cf"> 
     <li><a href="#">FooafsdasiuhfauhfuahsdfFooaf sdasiuhfauhfuahsdfFooafsdasiuhfauhfuahsdf</a> 

      <ul> 
       <li><a href="#">Subitem asdasdasd 1 sadad</a> 

       </li> 
       <li>Subitem 2</li> 
       <li>Subitem 3</li> 
      </ul> 
     </li> 
     <li><a href="#">Bar</a> 

      <ul> 
       <li>Subitem 1</li> 
       <li>Subitem 2</li> 
       <li>Subitem 3</li> 
      </ul> 
     </li> 
     <li>Qux</li> 
    </ul> 
    <div>CONTENT</div> 
    <div>FOOTER</div> 
</body> 

JAVASCRIPT

$(document).ready(function() { 
    var DROP_DOWN_TIME = 200; 
    //Setup hidden dropdowns 
    $("#menu > li > a").next().toggle(); 
    //Hide or unhide dropdowns onclick 
    $("#menu > li > a").click(function (e) { 
     $("#menu a").next().not($(e.target).next()).slideUp(DROP_DOWN_TIME); 
     $(e.target).next().slideToggle(DROP_DOWN_TIME); 
     e.stopPropagation(); 
    }); 
    $("body").on("click", ":not(#menu *)", function (e) { 
     $("#menu a").next().slideUp(DROP_DOWN_TIME); 
    }); 
}); 

CSS

#menu { 
    width: 900px; 
    padding: 0; 
    margin: 0; 
} 
/* Top level menu container */ 
#menu li { 
    background-color: aqua; 
    border: 1px solid black; 
    padding: 2px; 
} 
/* Top level menu items */ 
#menu > li { 
    display: inline-block; 
    float: left; 
    position: relative; 
} 
/* Submenu container */ 
#menu > li > ul { 
    position:absolute; 
    padding: 0; 
    margin: 0; 
    top: 100%; 
    left: -1px; 
} 
/* Submenu Items */ 
#menu > li > ul > li { 
    display: block; 
    float: none; 
    white-space: nowrap; 
} 
.cf:before, .cf:after { 
    content:" "; 
    /* 1 */ 
    display: table; 
    /* 2 */ 
} 
.cf:after { 
    clear: both; 
} 
+0

을 추가해야합니다 : 그래서 당신은 '이 무엇을 기대 할 만 필터입니다하지 :하지 (#menu을 *) ' –

+0

@wirey 셀렉터입니다. 내부에있는 것과 일치하지 않는 모든 요소를 ​​반환합니다. @api.jquery.com/not-selector/ – Jazzepi

+0

@Jazzepi -하지만 위와 같은 위임 된 이벤트 핸들러의 필터로 사용할 수 없습니다. – adeneo

답변

3

클릭이 메뉴 요소에 걸리므로 실패합니다. 내부의 콘텐츠가 발견되었습니다.

당신은 또한 당신이 .. 선택기를 지정하지 않고 메뉴 요소를

$("body").on("click", ":not(#menu, #menu *)", function (e) { 
          ^^^^^^ 
+0

우승자 우승자 닭고기 만찬. 실제 질문에 대한 답변 주셔서 감사합니다 :) <3 – Jazzepi

-1

대신 사용해보세요

$("body").on("click", function (e) { 
    if(e.taget.id !== 'menu' && !$(e.target).closest('#menu').length) { 
     $("#menu a").next().slideUp(DROP_DOWN_TIME); 
    } 
}); 
+1

나는 매끄럽게하려고 노력하고 있었고 .on()의 선택기 기능을 사용했다. 나는 실제로 그것이 기대했던 방식으로 작동하지 않는 이유를 아는 데있어서 매우 흥미 롭습니다. 버블을 필터링하기 위해 임의의 함수를 사용할 수 있다는 것을 이해하지만, 나는 "깨끗한"것을 기대하고있었습니다. – Jazzepi

관련 문제