开发者

JQuery question on mouseup event

开发者 https://www.devze.com 2023-03-20 16:03 出处:网络
I have list and the elements of the list can be selected (one at a t开发者_StackOverflow中文版ime, or more with the help of Ctrl key) by mousedown event. I\'d like to deselect the selected elements by

I have list and the elements of the list can be selected (one at a t开发者_StackOverflow中文版ime, or more with the help of Ctrl key) by mousedown event. I'd like to deselect the selected elements by mouseup on anywhere in document but these list elements. I tried this but doesn't work:

$("body").delegate("body:not(.selected_li)", "mouseup", function(event) { .......

When I click anywhere on the document (but the selected li) the mouseup event dosen't take place.

Please, help me.

Thank you.


You will want to bind your event listener to the body, and examine the clicked element to see if it is a .selected_li, or one of its descendants:

$('body').mouseup(function(e) {
    if ($(e.target).closest('.selected_li').length == 0) {
        // de-select
    }
});

The real trick here is using .closest(".selected_li") because it makes sure to include instances where you are over a child of a ".selected_li".

Using .is(".selected_li") won't work if your list happens to look anything like this:

<ul>
    <li>Item 1</li>
    <li class="selected_li"><i>Item 2</i></li>
    <li>Item 3</li>
</ul>

If you release your mouse button while over Item 2, event.target will be the <i> element, not the <li>, so .is(".selected_li") will return false. So we must see if the event target or any of its ancestors are ".selected_li" by searching using .closest() and checking to see if we got a match.

Edit: Using .delegate() here is not a great idea. That will bind an event handler to every descendant element of <body>, which is very redundant, since the event will always bubble up to <body> anyway and you only need to do it once. However, it is possible, but you need to make sure to exclude enough - you'll need to exclude ".selected_li" and all of its descendants, and all of its anscestors:

$("body").delegate(":not(.selected_li, .selected_li *, :has(.selected_li))", "mouseup", function(e) {
    // de-select
});

But, this will lead to the event handler being called multiple times per click. If you release the mouse button while over the following paragraph, you'll execute your event handler 5 times. Once for each of <em>,<p>,<div class="section">,<div id="content">,<div id="wrapper">.

<body>
    <div id="wrapper">
        <div id="content">
            <div class="section">
                <p><em>Here is a paragraph</em></p>
            </div>
        </div>
    </div>
</body>

So, just bind once to body so that the event handler is called only once per click.


Try this

http://jsfiddle.net/kw7v5/

Just substitute your classes for the ul and li.


This should do what you need..

$('body').mouseup(function(e){
   if ( !$(e.target).is('.selected_li') ) {
     // do the de-selection here..
   }
});

Demo at http://jsfiddle.net/gaby/kw7v5/4/


You can't delegate to the body from the body. body is your root element, so I think what you want is something like:

$("body").delegate("li:not(.selected_li)", "mouseup", function(event) {
  /* */
});

See http://api.jquery.com/delegate

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号