web-dev-qa-db-fra.com

Capture de l'événement "affiché" à partir de l'onglet bootstrap

J'ai du HTML 'statique' sur ma page:

<div id="DIVISIONS">
    <ul class="nav nav-tabs" id="DIVISIONTABS">
        @* <li> nodes will be injected here by javascript *@
    </ul>
    <div class="tab-content" id="DIVISIONTABPANES">
        @* <div class="tab-pane"> nodes will be injected here by javascript *@
    </div>
</div>

Au chargement de la page, je crée un onglet 'framework', c’est-à-dire les onglets d’amorçage et les conteneurs de contenu d’onglets.

Je déclenche le processus avec:

$(window).bind("load", prepareDivisionTabs);

Et "prepareDivisionTabs" fait ceci:

function prepareDivisionTabs() {
    // Retrieve basic data for creating tabs
    $.ajax({
        url: "@Url.Action("GetDivisionDataJson", "League")",
        cache: false
    }).done(function (data) {
        var $tabs = $('#DIVISIONTABS').empty();
        var $panes = $('#DIVISIONTABPANES').empty();
        for (var i = 0; i < data.length; i++) {
            var d = data[i];
            $tabs.append("<li><a href=\"#TABPANE" + d.DivisionId + "\" data-toggle=\"tab\">" + NMWhtmlEncode(d.Name) + "</a></li>");
            $panes.append("<div id=\"TABPANE" + d.DivisionId + "\" class=\"tab-pane\"></div>")
        }
        renderDivisionTabPaneContents(data);
    }).fail(function (err) {
        alert("AJAX error in request: " + JSON.stringify(err, null, 2));
    });
}

Pour info, le "renderDivisionTabPaneContents" ci-dessus fait ceci:

function renderDivisionTabPaneContents(data) {
    for (var i = 0; i < data.length; i++) {
        var d = data[i];
        renderDivisionTabPaneContent(d.DivisionId);
    }
}

function renderDivisionTabPaneContent(id) {
    var $tabPane = $('#TABPANE' + id);
    $tabPane.addClass("loader")
    $.ajax({
        url: "/League/GetDivisionPartialView?divisionId=" + id,
        cache: false
    }).done(function (html) {
        $tabPane.html(html);
    }).fail(function (err) {
        alert("AJAX error in request: " + JSON.stringify(err, null, 2));
    }).always(function () {
        $tabPane.removeClass("loader")
    });
}

Tout va bien jusqu'à présent. Ma page se charge, le contenu de mes onglets est rendu et lorsque je clique sur les différents onglets, le contenu correspondant s’affiche.

Maintenant, plutôt que de charger tout le contenu au début, je veux charger le contenu des onglets juste à temps en utilisant l'événement 'affiché' des onglets. Pour tester cela, je voulais simplement m'assurer que je pouvais obtenir une alerte javascript lorsque l'onglet était affiché. Donc, je crée ce qui suit pour déclencher l'attachement des événements de l'onglet montré:

$(function () {
    attachTabShownEvents();
})

qui appelle:

function attachTabShownEvents() {
    $(document).on('shown', 'a[data-toggle="tab"]', function (e) {
        alert('TAB CHANGED');
    })
}

Je m'attendrais donc à voir l'alerte "ONGLET CHANGÉ" après le changement d'onglet. Mais ... je ne vois aucune alerte. 

Quelqu'un pourrait-il m'aider ici?

24
Neil W

La liaison d'événement correcte pour le changement de tabulation est shown.bs.tab.

$(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
    alert('TAB CHANGED');
})
76
azz
$(document).ready(function(){
    $(".nav-tabs a").click(function(){
        $(this).tab('show');
    });
    $('.nav-tabs a').on('shown.bs.tab', function(event){
        alert('tab shown');
    });
});
0
Stnfordly
<a data-toggle="tab" href="#some_special_tab_anchor">

<div id="some_special_tab_anchor" class="tab-pane fade">
    special tab content
</div>

            $( 'a[data-toggle="tab"]' ).on( 'shown.bs.tab', function( evt ) {

                var anchor = $( evt.target ).attr( 'href' );
                alert("TAB SHOWN = "+anchor);

                // take action based on what tab was shown
               if(anchor === "some_special_tab_anchor"){
                  // do my special thing :)
               }

            });
0
Stnfordly

Utilisez mon paquet Nuget pour les onglets d’amorçage lazyloading ici. C’est très simple, Ajoutez simplement la classe "lazyload" à l’élément "ul" des onglets d’amorçage, puis ajoutez "data-url" égal à l’URL pour charger l’ancre de n'importe quel onglet élément (a). c'est tout.

https://www.nuget.org/packages/MT.BootstrapTabsLazyLoader.js/

0
mesut

Les événements 'show' et 'shown' n'ont pas fonctionné pour moi. Ma solution n'est pas exactement la situation d'OP, mais les concepts généraux sont là.

J'ai eu le même problème avec bootstrap forçant ses propres événements onclick Sur des onglets (boutons de menu et panneaux de contenu). Je voulais charger paresseux des éléments dans un panneau en fonction du bouton de menu sur lequel l'utilisateur avait cliqué. Certains boutons affichent un panneau sur la page actuelle, d'autres devaient charger une page dans un iframe.

Au début, j'ai inséré des données dans une balise de champ de formulaire masqué, ce qui posait le même problème. Le truc est de détecter une sorte de changement et d'agir en conséquence. J'ai résolu le problème en forçant un changement et en utilisant un autre événement en écoutant les boutons sans avoir à toucher bootstrap.

1) cachent la cible d'iframe dans le bouton en tant qu'attribut de données:

$('#btn_for_iframe').attr('data-url',iframeurl);

2) lier un événement alternatif à un élément déclencheur, Et à l’intérieur, échanger la source iframe

$('#btn_for_iframe').on('mouseup',function(){
   console.log(this+' was activated');
   $('#iframe').attr('src',$('#btn_for_iframe').attr('data-url'));
});

3) forcer l'événement 'changer' sur le panneau, puis charger iframe src

$('#iframe_panel_wrapper').show().trigger('change');

ou vous pouvez mettre le déclencheur de changement dans la souris ci-dessus.

0
user3056442