简体   繁体   中英

in jQuery, mouse events trigger wrong element. How can I fix this?

I am working on a Bootstrap navbar in a Wordpress website with this HTML code ->

<nav id="menu" class="navbar navbar-expand-md navbar-light bg-faded">
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#bs4navbar"
            aria-controls="bs4navbar" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>
    <div id="bs4navbar" class="collapse navbar-collapse">
        <ul id="menu-main" class="navbar-nav mr-auto">

            <li id="menu-item-61"
                class="menu-item menu-item-type-taxonomy menu-item-object-product_cat menu-item-61 nav-item"><a
                    href="#"
                    class="nav-link">ITEM 61</a></li>

            <li id="menu-item-59"
                class="menu-item menu-item-type-taxonomy menu-item-object-product_cat menu-item-59 nav-item"><a
                    href="#"
                    class="nav-link">ITEM 59</a></li>

            <li id="menu-item-56"
                class="menu-item menu-item-type-taxonomy menu-item-object-product_cat menu-item-has-children menu-item-56 nav-item dropdown">
                <a href="#"
                   class="nav-link dropdown-toggle" data-toggle="dropdown">ITEM 56</a>
                <div class="dropdown-menu">
                    <a href="#"
                       class=" dropdown-item">ITEM 56 - A</a><a
                        href="#"
                        class=" dropdown-item">ITEM 56 - B</a></div>
            </li>
            <li id="menu-item-48"
                class="menu-item menu-item-type-taxonomy menu-item-object-product_cat menu-item-has-children menu-item-48 nav-item dropdown">
                <a href="#"
                   class="nav-link dropdown-toggle" data-toggle="dropdown">ITEM 48</a>
                <div class="dropdown-menu">
                    <a href="#"
                       class=" dropdown-item">ITEM 48 - A</a><a
                        href="#"
                        class=" dropdown-item">ITEM 48 - B</a><a
                        href="#"
                        class=" dropdown-item">ITEM 48 - C</a><a
                        href="#"
                        class=" dropdown-item">ITEM 48 - D</a></div>
            </li>

            <li id="menu-item-53"
                class="menu-item menu-item-type-taxonomy menu-item-object-product_cat menu-item-has-children menu-item-53 nav-item dropdown">
                <a href="#"
                   class="nav-link dropdown-toggle" data-toggle="dropdown">ITEM 53</a>
                <div class="dropdown-menu" style="display: none;">
                    <a href="#"
                       class=" dropdown-item">ITEM 53 - A</a><a
                        href="#"
                        class=" dropdown-item">ITEM 53 - B</a></div>
            </li>

        </ul>
    </div>
</nav>

The items 56 , 48 and 53 have .dropdown-menu , basically when I clic on one of them I expect to see the submenu; its native bootstrap.js script doesn't work (I don't know the reason).

To fix this, I can trigger a mouse event with this code ->

<script>

            $(function ($) {

                $nav = $('nav#menu');

                $('.dropdown', $nav).each(function () {

                    console.log('.dropdown ->');
                    console.log($(this));

                    $subMenu = $('.dropdown-menu', $(this));

                    console.log('$subMenu ->');
                    console.log($subMenu);

                    $(this).mouseenter(function () {

                        console.log('mouseenter ->');
                        console.log($(this));

                        $subMenu.show();

                        console.log('$subMenu ->');
                        console.log($subMenu);

                    }).mouseleave(function () {

                        console.log('mouseleave ->');
                        console.log($(this));

                        $subMenu.hide();

                        console.log('$subMenu ->');
                        console.log($subMenu);
                    });

                });

            });

        </script>

 $(function($) { $nav = $('nav#menu'); $('.dropdown', $nav).each(function() { console.log('.dropdown ->'); console.log($(this)); $subMenu = $('.dropdown-menu', $(this)); console.log('$subMenu ->'); console.log($subMenu); $(this).mouseenter(function() { console.log('mouseenter ->'); console.log($(this)); $subMenu.show(); console.log('$subMenu ->'); console.log($subMenu); }).mouseleave(function() { console.log('mouseleave ->'); console.log($(this)); $subMenu.hide(); console.log('$subMenu ->'); console.log($subMenu); }); }); });
 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="undefined" crossorigin="anonymous"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <nav id="menu" class="navbar navbar-expand-md navbar-light bg-faded"> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#bs4navbar" aria-controls="bs4navbar" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div id="bs4navbar" class="collapse navbar-collapse"> <ul id="menu-main" class="navbar-nav mr-auto"> <li id="menu-item-61" class="menu-item menu-item-type-taxonomy menu-item-object-product_cat menu-item-61 nav-item"><a href="#" class="nav-link">ITEM 61</a></li> <li id="menu-item-59" class="menu-item menu-item-type-taxonomy menu-item-object-product_cat menu-item-59 nav-item"><a href="#" class="nav-link">ITEM 59</a></li> <li id="menu-item-56" class="menu-item menu-item-type-taxonomy menu-item-object-product_cat menu-item-has-children menu-item-56 nav-item dropdown"> <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">ITEM 56</a> <div class="dropdown-menu"> <a href="#" class=" dropdown-item">ITEM 56 - A</a><a href="#" class=" dropdown-item">ITEM 56 - B</a></div> </li> <li id="menu-item-48" class="menu-item menu-item-type-taxonomy menu-item-object-product_cat menu-item-has-children menu-item-48 nav-item dropdown"> <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">ITEM 48</a> <div class="dropdown-menu"> <a href="#" class=" dropdown-item">ITEM 48 - A</a><a href="#" class=" dropdown-item">ITEM 48 - B</a><a href="#" class=" dropdown-item">ITEM 48 - C</a><a href="#" class=" dropdown-item">ITEM 48 - D</a></div> </li> <li id="menu-item-53" class="menu-item menu-item-type-taxonomy menu-item-object-product_cat menu-item-has-children menu-item-53 nav-item dropdown"> <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">ITEM 53</a> <div class="dropdown-menu" style="display: none;"> <a href="#" class=" dropdown-item">ITEM 53 - A</a><a href="#" class=" dropdown-item">ITEM 53 - B</a></div> </li> </ul> </div> </nav>

(I left the console.log() for debugging purposes).

I expected to see the sub menu when I just move the mouse on their respective areas.

The (wrong) result is when I move the mouse in any of that 3 elements, it shows the last .dropdown-menu in the list.

The console shows the correct element in .each() , but when triggered it shows only the last .dropdown-menu element in the list.

I can't figure it out how it can be possible something like that.

Can anyone explain what's going on? and how can I fix that?

Main thing is you are missing var when declaring variables, so are creating globals.

I've tidied up your code a bit like so:

$(function ($) {
    var $nav = $('nav#menu');

    $nav.find('.dropdown').each(function () {
        var $dropdown = $(this);

        $(this).mouseenter(function () {
            var $subMenu = $dropdown.find('.dropdown-menu');
            $subMenu.show();
        }).mouseleave(function () {
            var $subMenu = $dropdown.find('.dropdown-menu');
            $subMenu.hide();
        });
    });
});

Regarding with a comment, I moved $subMenu inside the event function and it works.

Thank you skyline3000

<script>

            $(function ($) {

                $nav = $('nav#menu');

                $('.dropdown', $nav).each(function () {

                    $(this).mouseenter(function () {

                        $subMenu = $('.dropdown-menu', $(this));
                        $subMenu.show();

                    }).mouseleave(function () {

                        $subMenu = $('.dropdown-menu', $(this));
                        $subMenu.hide();

                    });

                });

            });

        </script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM