web-dev-qa-db-fra.com

Comment ajouter une classe active sur un clic spécifique de l'utilisateur avec jQuery

J'ai un menu avec certains éléments et je veux quand un utilisateur clique sur un li que seule sa classe devient une classe active. J'ai un élément de menu comme suit:

<ul class="nav">
    <li class="dropdown active">
        <asp:HyperLink ID="hlHome" runat="server" href="Default.aspx">Home</asp:HyperLink>
    </li>
    <li class="dropdown">
        <asp:HyperLink runat="Server" cssClass="dropdown-toggle" data-toggle="dropdown" data-hover="dropdown" data-delay="0" data-close-others="false" href="#">
            Register
            <i class="icon-angle-down"></i>
        </asp:HyperLink>
        <ul class="dropdown-menu">
            <li><asp:HyperLink runat="server" ID="hlCreateAccount" href="register.aspx">Create Account</asp:HyperLink></li>
            <li><asp:HyperLink runat="Server" href="forgot.aspx" ID="hlForgot">Forgot Credentials ?</asp:HyperLink></li>
            <li><asp:HyperLink runat="server" href="blocked.aspx" ID="hlBlockedAccount">Blocked Account</asp:HyperLink></li>
            <li><asp:HyperLink ID="hlUnblockAccount" href="unblock.aspx" runat="server">Unblock Account</asp:HyperLink></li>
        </ul>
    </li>
    <li><asp:HyperLink  ID="hlBug" runat="server" href="bug.aspx">Report A Bug</asp:HyperLink></li>
    <li><asp:HyperLink ID="hlContact" runat="server" href="contact.aspx">Contact Us</asp:HyperLink></li>
</ul>

Et j'ai essayé le code suivant avec jQuery:

<script type="text/javascript">
    function pageLoad() {
        var loc = window.location.href.split('/');
        var page = loc[loc.length - 1];
        $('ul.nav a').each(function (i) {
            var href = $(this).attr('href');
            if (href.indexOf(page) !== -1) {
                $('ul.nav li.active').removeClass('active');
                $(this).parent().addClass('active');
            }
        });
    }
</script>

Son ne fonctionne pas avec les menus déroulants tout en fonctionnant parfaitement avec tous les autres menus n'ayant pas d'éléments déroulants. Comment puis-je changer le code qu'il fonctionne aussi avec un élément de menu ayant une liste déroulante d'éléments. J'utilise également le panneau de mise à jour dans ma page.

12
Afnan Ahmad

Vous avez spécifié jQuery et Javascript dans les balises. Voici les deux approches.

jQuery

var selector = '.nav li';

$(selector).on('click', function(){
    $(selector).removeClass('active');
    $(this).addClass('active');
});

Fiddle: http://jsfiddle.net/bvf9u/


Pure Javascript:

var selector, elems, makeActive;

selector = '.nav li';

elems = document.querySelectorAll(selector);

makeActive = function () {
    for (var i = 0; i < elems.length; i++)
        elems[i].classList.remove('active');

    this.classList.add('active');
};

for (var i = 0; i < elems.length; i++)
    elems[i].addEventListener('mousedown', makeActive);

Fiddle: http://jsfiddle.net/rn3nc/1


jQuery avec délégation d'événement:

Veuillez noter que dans l'approche 1, le gestionnaire est directement lié à cet élément. Si vous attendez que le DOM soit mis à jour et que la nouvelle lis soit injectée, il est préférable d'utiliser la délégation d'événements et la délégation au prochain élément qui restera statique, dans ce cas le .nav:

$('.nav').on('click', 'li', function(){
    $('.nav li').removeClass('active');
    $(this).addClass('active');
});

Fiddle: http://jsfiddle.net/bvf9u/1/

La différence subtile est que le gestionnaire est lié au .nav maintenant. Ainsi, lorsque vous cliquez sur li, l'événement bulles augmente le DOM jusqu'au .nav qui appelle le gestionnaire si l'élément sur lequel vous cliquez correspond à votre argument selector. Cela signifie que les nouveaux éléments n'auront pas besoin d'un nouveau gestionnaire lié à eux, car ils sont déjà liés à un ancêtre.

C'est vraiment très intéressant. En savoir plus à ce sujet ici: http://api.jquery.com/on/

45
Matt Harrison
 $(document).ready(function () {
    $('.dates li a').click(function (e) {

        $('.dates li a').removeClass('active');

        var $parent = $(this);
        if (!$parent.hasClass('active')) {
            $parent.addClass('active');
        }
        e.preventDefault();
    });
});
2
Rajesh Kumar

// Écrire une méthode javascript pour lier l'événement click de chaque élément "li"

    function BindClickEvent()
    {
    var selector = '.nav li';
    //Removes click event of each li
    $(selector ).unbind('click');
    //Add click event
    $(selector ).bind('click', function()
    {
        $(selector).removeClass('active');
        $(this).addClass('active');
    });

    }

// premier appel de cette méthode lors du premier chargement de la page

    $( document ).ready(function() {
         BindClickEvent();
    });

// Appelez la méthode BindClickEvent du côté serveur 

    protected void Page_Load(object sender, EventArgs e)
    {
        ScriptManager.RegisterStartupScript(Page,GetType(), Guid.NewGuid().ToString(),"BindClickEvent();",true);
    }
1
Rahul
        // Remove active for all items.
        $('.sidebar-menu li').removeClass('active');
        // highlight submenu item
        $('li a[href="' + this.location.pathname + '"]').parent().addClass('active');
        // Highlight parent menu item.
        $('ul a[href="' + this.location.pathname + '"]').parents('li').addClass('active')
0
Gowthaman

Un peu hors sujet, mais étant arrivé ici en développant une application Angular2, je voudrais dire que Angular2 ajoute automatiquement la classe "router-link-active" aux liens de routeur actifs tels que celui-ci:

<li><a [routerLink]="['Dashboard']">Dashboard</a></li>

Vous pouvez donc facilement styler de tels liens en utilisant CSS: 

.router-link-active {
    color: red;
}
0
Brice