views:

17

answers:

1

I have a tab (called firsttab) with in his content another tab (called childtab). We bind the tabshow-event to the firsttab.

if we click to one of the tabs in "firsttab" all work fine (Tab 1 - Tab 5) if we click to one of the "childtab" tabs (Tab 1.1 - Tab 1.3) the tabshow-event who are bind to the "firsttab" is triggerd.

Testcase: http://jsfiddle.net/bM8Wh/

HTML:

<div id="firsttab">
    <ul>
        <li><a href="#firsttab_1">Tab 1</a></li>
        <li><a href="#firsttab_2">Tab 2</a></li>
        <li><a href="#firsttab_3">Tab 3</a></li>
        <li><a href="#firsttab_4">Tab 4</a></li>
        <li><a href="#firsttab_5">Tab 5</a></li>
    </ul>

    <div id="firsttab_1">
        <div id="childtab">
            <ul>
                <li><a href="#childtab_1">Tab 1.1</a></li>
                <li><a href="#childtab_2">Tab 1.2</a></li>
                <li><a href="#childtab_3">Tab 1.3</a></li>
            </ul>

            <div id="childtab_1">Tab 1.1</div>            
            <div id="childtab_2">Tab 1.2</div>
            <div id="childtab_3">Tab 1.3</div>
        </div>
    </div>
    <div id="firsttab_2">Tab 2</div>
    <div id="firsttab_3">Tab 3</div>
    <div id="firsttab_4">Tab 4</div>
    <div id="firsttab_5">Tab 5</div>
</div>

JavaScript:

$("#firsttab, #childtab").tabs();
$("#firsttab").bind('tabsshow', function(event, ui) { funcX(ui.index); });

function funcX(idx){
    alert('triggerd - index: ' + idx);
}

I down't understande why the tabsshow-event is triggerd by the childtab because i bind this event to the firsttab.

The answer of my jquery-ticked was: "Events bubble; check the target." but i down understand what he means.

i handle the problem by change my tabsshow-event-handler to:

$("#tabs").bind('tabsshow',
  function(event, ui) {
    if ((/#(.*?)$/im).exec(ui.tab.hash)[1] == this.id)
      funcX(ui.index);
  });

but i will understand where are the problem.

+1  A: 

By default, event's bubble, meaning that an event in a child element goes up to all parent elements unless you stop it. So for example a click anywhere on the page is a click event on that element, it's parent, and so on up until document. This behavior also happens with any custom jQuery events like tabsshow, but if you don't want it you can stop the event from bubbling using event.stopPropagation(), like this:

$("#childtab").bind('tabsshow', function(event, ui) { 
  event.stopPropagation(); 
});

This stops the event from firing on #firsttab because it just doesn't bubble up there anymore. You can try your sample with this fix here.

Nick Craver
ok i think i understand. the tabsshow-event form the childtab are not handled so it will be goes up to the parent element until the tabsshow-event is handled by the firsttab-eventhandler.but is it not "stupid" by jquery to fire events to an eventhandler wo has not bind to this? wouldt not jquery handel this mistake? i bind my eventhandler to firsttab.tabshow-event not to firsttab_and_all_childs.tabshow.event and in my opinion jquery should only fire the event if his referer the target excpect i bind the eventhandler with an "takeallchildevent"-option.
Floyd
a second question: in your solution you bind a second eventhandler to the childtab. but is it not a better solution to bind it to all tabs like:$("DIV.ui-tabs").bind('tabsshow', function(event, ui) { event.stopPropagation(); });
Floyd
@floyddotnet - *All* events bubble, even if they're handled they continue to bubble, unless you `return false` or `.stopPropagation()`, this is just how the DOM is *expected* to work (with or without jQuery). For your second comment yes that's a perfectly valid approach, just make sure to run that *after* creating the tabs, otherwise they don't have the `ui-tabs` class added to them yet. Any selector that finds the element and binds a handler to stop propagation will work :)
Nick Craver