子元素的点击事件被父元素的 event.stopPropagation 阻止了。

huangapple go评论71阅读模式
英文:

Child element's click event prevented by parent's event.stopPropagation

问题

在我的[线上网站][1]上,我使用了 'nice-select' 库创建了一个选择元素。这个选择元素嵌套在一个下拉菜单中,该菜单有自己的JavaScript文件。

function singleMenu(targetId, menuId, show = false) {
    const targetElement = document.getElementById(targetId);
    const menuElement = document.getElementById(menuId);

    // 初始状态
    if (show) {
        // 显示下拉菜单
        menuElement.style.display = "block";
        targetElement.classList.add("active");
    } else {
        // 隐藏下拉菜单
        menuElement.style.display = "none";
        targetElement.classList.remove("active");
    }

    // 当点击目标元素时切换菜单可见性
    targetElement.addEventListener("click", () => {
        show = !show;

        if (show) {
            // 显示下拉菜单
            menuElement.style.display = "block";
            targetElement.classList.add("active");
        } else {
            // 隐藏下拉菜单
            menuElement.style.display = "none";
            targetElement.classList.remove("active");
        }
    });

    // 如果在容器外部点击,关闭菜单
    document.addEventListener("click", (event) => {
        if (!targetElement.contains(event.target)) {
            show = false;
            menuElement.style.display = "none";
            targetElement.classList.remove("active");
        }
    });

    // 防止点击菜单元素内部时关闭菜单
    menuElement.addEventListener("click", function (event) {
        event.stopPropagation();
    });

    // 计算目标元素宽度的一半
    const targetHalfWidth = targetElement.offsetWidth / 2;

    // 使用一半宽度值设置CSS变量
    targetElement.style.setProperty(
        "--target-half-width",
        targetHalfWidth + "px"
    );
}

目前,我面临一个问题,即当单击选择元素时,它不会打开,但使用回车键和上/下箭头按钮时它可以正常工作。

我怀疑问题可能与 event.stopPropagation() 函数有关,因为当我删除该行时,选择元素的 'open' 类会添加(在检查工具中可见)。然而,删除 event.stopPropagation() 行也会导致下拉菜单立即关闭。

我的目标是找到一种解决方案,允许我打开选择元素而不关闭下拉菜单。非常感谢您对如何实现这一目标的任何见解或建议。

以下是相关的HTML代码(HTML文件代码)以供参考。谢谢您的帮助!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link
        rel="stylesheet"
        id="hello-elementor-child-style-css"
        href="https://fs.codelinden.com/wp-content/themes/hello-child/style.css?ver=3"
        media="all"
    />
    <link rel="stylesheet" href="header.css" />
    <script src="header.js" defer></script>

    <!-- single-menu dropdown style -->
    <link rel="stylesheet" href="single-menu-dropdown.css" />

    <!-- custom form element style (nice-select) -->
    <link rel="stylesheet" href="form.css" />

    <!-- nice-select style-->
    <link
        rel="stylesheet"
        href="https://cdnjs.cloudflare.com/ajax/libs/jquery-nice-select/1.1.0/css/nice-select.min.css"
        integrity="sha512-CruCP+TD3yXzlvvijET8wV5WxxEh5H8P4cmz0RFbKK6FlZ2sYl3AEsKlLPHbniXKSrDdFewhbmBK5skbdsASbQ=="
        crossorigin="anonymous"
        referrerpolicy="no-referrer"
    />

    <title>Header</title>
</head>
<body>
    <header class="header HruDj">
        <div class="nav-dropdown target-id DeYlt" id="target_id1">
            <p>toggle dropdown</p>

            <!-- single-menu dropdown container -->
            <div id="menu_id1" class="menu-id">
                <div class="form-field full-width">
                    <input
                        type="hidden"
                        name="form_my_contact_form"
                        value="1"
                    />
                    <label for="product_type">Product Type</label>
                    <select
                        name="product_type"
                        id="product_type"
                        required=""
                    >
                        <option value="book">Book</option>
                        <option value="movie">Movie</option>
                        <option value="music">Music</option>
                        <option value="" disabled="">
                            Select a product type
                        </option>
                    </select>
                </div>
            </div>
        </div>
        <div class="nav-dropdown target-id DeYlt" id="target_id2">
            <p>toggle dropdown</p>

            <!-- single-menu dropdown container -->
            <div id="menu_id2" class="menu-id">
                <div class="form-field full-width">
                    <input
                        type="hidden"
                        name="form_my_contact_form"
                        value="1"
                    />
                    <label for="product_type">Product Type</label>
                    <select
                        name="product_type"
                        id="product_type"
                        required=""
                    >
                        <option value="book">Book</option>
                        <option value="movie">Movie</option>
                        <option value="music">Music</option>
                        <option value="" disabled="">
                            Select a product type
                        </option>
                    </select>
                </div>
            </div>
        </div>
    </header>

    <!-- jquery cdn -->
    <script src="popup/jquery/jquery.min.js"></script>

    <!-- single-menu dropdown script -->
    <script src="single-menu-dropdown.js"></script>

    <!-- nice-select script -->
    <script
        src="https://cdnjs.cloudflare.com/ajax/libs/jquery-nice-select/1.1.0/js/jquery.nice-select.min.js"
        integrity="sha512-NqYds8su6jivy1/WLoW8x1tZMRD7/1ZfhWG/jcRQLOzV1k1rIODCpMgoBnar5QXshKJGV7vi0LXLNXPoFsM5Zg=="
        crossorigin="anonymous"
        referrerpolicy="no-referrer"
    ></script>

    <!-- initialize dropdown and select -->
    <script>
        // 为每个菜单调用singleMenu函数
        singleMenu("target_id1", "menu_id1

<details>
<summary>英文:</summary>

On my ([live site][1]), I have a select element created using the &#39;nice-select&#39; library. This select element is nested inside a dropdown menu, which has its own JavaScript file

        function singleMenu(targetId, menuId, show = false) {
        const targetElement = document.getElementById(targetId);
        const menuElement = document.getElementById(menuId);
    
        // Initial state
        if (show) {
            // show dropdown
            menuElement.style.display = &quot;block&quot;;
            targetElement.classList.add(&quot;active&quot;);
        } else {
            // hide dropdown
            menuElement.style.display = &quot;none&quot;;
            targetElement.classList.remove(&quot;active&quot;);
        }
    
        // Toggle menu visibility when target element is clicked
        targetElement.addEventListener(&quot;click&quot;, () =&gt; {
            show = !show;
    
            if (show) {
                // show dropdown
                menuElement.style.display = &quot;block&quot;;
                targetElement.classList.add(&quot;active&quot;);
            } else {
                // hide dropdown
                menuElement.style.display = &quot;none&quot;;
                targetElement.classList.remove(&quot;active&quot;);
            }
        });
    
        // Close menu if clicked outside of container
        document.addEventListener(&quot;click&quot;, (event) =&gt; {
            if (!targetElement.contains(event.target)) {
                show = false;
                menuElement.style.display = &quot;none&quot;;
                targetElement.classList.remove(&quot;active&quot;);
            }
        });
    
        // Prevent menu from closing when clicked inside the menu element
        menuElement.addEventListener(&quot;click&quot;, function (event) {
            event.stopPropagation();
        });
    
        // Calculate half of the targetElement width
        const targetHalfWidth = targetElement.offsetWidth / 2;
    
        // Set a CSS variable with the half width value
        targetElement.style.setProperty(
            &quot;--target-half-width&quot;,
            targetHalfWidth + &quot;px&quot;
        );
    }

Currently, I&#39;m facing an issue where the select element does not open when clicked, but it does work properly when using the enter and up/down buttons.

I suspect that the problem might be related to the event.stopPropagation() function, as when I remove that line, the select element&#39;s &#39;open&#39; class gets added (as seen in the inspect tool). However, removing the event.stopPropagation() line also results in the dropdown menu closing immediately.

My goal is to find a solution that allows me to open the select elements without closing the dropdown menu. I would greatly appreciate any insights or suggestions on how to achieve this.



Here is the relevant HTML code (html file code) for reference. Thank you for your help!

    &lt;!DOCTYPE html&gt;
    &lt;html lang=&quot;en&quot;&gt;
        &lt;head&gt;
            &lt;meta charset=&quot;UTF-8&quot; /&gt;
            &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
            &lt;link
                rel=&quot;stylesheet&quot;
                id=&quot;hello-elementor-child-style-css&quot;
                href=&quot;https://fs.codelinden.com/wp-content/themes/hello-child/style.css?ver=3&quot;
                media=&quot;all&quot;
            /&gt;
            &lt;link rel=&quot;stylesheet&quot; href=&quot;header.css&quot; /&gt;
            &lt;script src=&quot;header.js&quot; defer&gt;&lt;/script&gt;
    
            &lt;!-- single-menu dropdown style --&gt;
            &lt;link rel=&quot;stylesheet&quot; href=&quot;single-menu-dropdown.css&quot; /&gt;
    
            &lt;!-- custom form element style (nice-select) --&gt;
            &lt;link rel=&quot;stylesheet&quot; href=&quot;form.css&quot; /&gt;
    
            &lt;!-- nice-select style--&gt;
            &lt;link
                rel=&quot;stylesheet&quot;
                href=&quot;https://cdnjs.cloudflare.com/ajax/libs/jquery-nice-select/1.1.0/css/nice-select.min.css&quot;
                integrity=&quot;sha512-CruCP+TD3yXzlvvijET8wV5WxxEh5H8P4cmz0RFbKK6FlZ2sYl3AEsKlLPHbniXKSrDdFewhbmBK5skbdsASbQ==&quot;
                crossorigin=&quot;anonymous&quot;
                referrerpolicy=&quot;no-referrer&quot;
            /&gt;
    
            &lt;title&gt;Header&lt;/title&gt;
        &lt;/head&gt;
        &lt;body&gt;
            &lt;header class=&quot;header HruDj&quot;&gt;
                &lt;div class=&quot;nav-dropdown target-id DeYlt&quot; id=&quot;target_id1&quot;&gt;
                    &lt;p&gt;toggle dropdown&lt;/p&gt;
    
                    &lt;!-- single-menu dropdown container --&gt;
                    &lt;div id=&quot;menu_id1&quot; class=&quot;menu-id&quot;&gt;
                        &lt;div class=&quot;form-field full-width&quot;&gt;
                            &lt;input
                                type=&quot;hidden&quot;
                                name=&quot;form_my_contact_form&quot;
                                value=&quot;1&quot;
                            /&gt;
                            &lt;label for=&quot;product_type&quot;&gt;Product Type&lt;/label&gt;
                            &lt;select
                                name=&quot;product_type&quot;
                                id=&quot;product_type&quot;
                                required=&quot;&quot;
                            &gt;
                                &lt;option value=&quot;book&quot;&gt;Book&lt;/option&gt;
                                &lt;option value=&quot;movie&quot;&gt;Movie&lt;/option&gt;
                                &lt;option value=&quot;music&quot;&gt;Music&lt;/option&gt;
                                &lt;option value=&quot;&quot; disabled=&quot;&quot;&gt;
                                    Select a product type
                                &lt;/option&gt;
                            &lt;/select&gt;
                        &lt;/div&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
                &lt;div class=&quot;nav-dropdown target-id DeYlt&quot; id=&quot;target_id2&quot;&gt;
                    &lt;p&gt;toggle dropdown&lt;/p&gt;
    
                    &lt;!-- single-menu dropdown container --&gt;
                    &lt;div id=&quot;menu_id2&quot; class=&quot;menu-id&quot;&gt;
                        &lt;div class=&quot;form-field full-width&quot;&gt;
                            &lt;input
                                type=&quot;hidden&quot;
                                name=&quot;form_my_contact_form&quot;
                                value=&quot;1&quot;
                            /&gt;
                            &lt;label for=&quot;product_type&quot;&gt;Product Type&lt;/label&gt;
                            &lt;select
                                name=&quot;product_type&quot;
                                id=&quot;product_type&quot;
                                required=&quot;&quot;
                            &gt;
                                &lt;option value=&quot;book&quot;&gt;Book&lt;/option&gt;
                                &lt;option value=&quot;movie&quot;&gt;Movie&lt;/option&gt;
                                &lt;option value=&quot;music&quot;&gt;Music&lt;/option&gt;
                                &lt;option value=&quot;&quot; disabled=&quot;&quot;&gt;
                                    Select a product type
                                &lt;/option&gt;
                            &lt;/select&gt;
                        &lt;/div&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
            &lt;/div&gt;
            &lt;/header&gt;
    
            &lt;!-- jquery cdn --&gt;
            &lt;script src=&quot;popup/jquery/jquery.min.js&quot;&gt;&lt;/script&gt;
    
            &lt;!-- single-menu dropdown script --&gt;
            &lt;script src=&quot;single-menu-dropdown.js&quot;&gt;&lt;/script&gt;
    
            &lt;!-- nice-select script --&gt;
            &lt;script
                src=&quot;https://cdnjs.cloudflare.com/ajax/libs/jquery-nice-select/1.1.0/js/jquery.nice-select.min.js&quot;
                integrity=&quot;sha512-NqYds8su6jivy1/WLoW8x1tZMRD7/1ZfhWG/jcRQLOzV1k1rIODCpMgoBnar5QXshKJGV7vi0LXLNXPoFsM5Zg==&quot;
                crossorigin=&quot;anonymous&quot;
                referrerpolicy=&quot;no-referrer&quot;
            &gt;&lt;/script&gt;
    
            &lt;!-- initialize dropdown and select --&gt;
            &lt;script&gt;
                // Call singleMenu function for each menu
                singleMenu(&quot;target_id1&quot;, &quot;menu_id1&quot;, false);
                singleMenu(&quot;target_id2&quot;, &quot;menu_id2&quot;, false);
    
                $(document).ready(function () {
                    // Apply the niceSelect plugin to all select elements
                    $(&quot;select&quot;).niceSelect();
                });
            &lt;/script&gt;
        &lt;/body&gt;
    &lt;/html&gt;


  [1]: https://drougnov.github.io/dashobard-copy/header.html

</details>


# 答案1
**得分**: 1

我相当确信这只是因为事件传播顺序而发生的。当单击 `select` 时,我看到以下事件发生:

1. 单击 `select` 触发了 `niceSelect` 函数。
2. 单击事件然后冒泡到父元素,最终到达您的 `menuElement` 并停在那里,因为您添加了 `event.stopPropagation()`。

我认为这是一个问题的原因是因为 `niceSelect` 在单击时并没有立即解决,它在执行其操作之前正在等待下一个事件循环。但由于事件在发生之前调用了 `stopPropagation()`,因此 `stopPropagation()` 阻止了这个操作的发生。

一个可能不正规的解决方法是延迟在 `stopPropagation()` 上的停止,如下所示:

```javascript
menuElement.addEventListener("click", function (event) {
  setTimeout(() => event.stopPropagation(), 0);
});

通俗地说,这告诉 JavaScript:“在事件循环完成后但在下一个事件循环开始之前运行此代码”。

英文:

I am pretty sure this is just happening because of the event propagation order. When select is clicked, this is what I am seeing is happening:

  1. The click event on select fires the niceSelect function.
  2. The click event then bubbles up to the parent elements, eventually reaching your menuElement and stopping there since you added event.stopPropagation().

I believe the reason this is an issue is because niceSelect does not immediately resolve on click, and it's waiting for the next event loop before it performs its actions. But since the event is hitting stopPropagation() before that ever happens, stopPropagation() stops this from ever happening.

A possibly unorthodox method to fix this would be to just delay your stop on stopPropagation() like so:

menuElement.addEventListener(&quot;click&quot;, function (event) {
  setTimeout(() =&gt; event.stopPropagation(), 0);
});

In layman's terms, this tells javascript "Run this code as soon as the event loop is finished but before the start of the next one".

答案2

得分: 1

所以我能够得到所需的结果,但需要进行一些小的更改。
使用event.stopPropagation()似乎没有一种方法可以始终正常工作。

你可以做的是,不要将整个菜单父元素设置为点击处理程序,而是设置它在更直接的目标上工作。

这意味着不要使用:

<div class="nav-dropdown target-id DeYlt" id="target_id1">
    <p>toggle dropdown</p>

而是希望将目标id添加到p标签内部。

<div class="nav-dropdown target-id DeYlt">
    <p id="target_id1">toggle dropdown</p>

对于menu_id2和target_id2也是一样的。

这将需要在javascript中进行小的更改。
更改关闭菜单的点击处理程序,以处理targetElement.parentElement,以便考虑目标现在位于菜单内部。

// Close menu if clicked outside of container
document.addEventListener("click", (event) => {
    if (!targetElement.parentElement.contains(event.target)) {
        show = false;
        menuElement.style.display = "none";
        targetElement.classList.remove("active");
    }
});

不再需要menu stop propagation项。

menuElement.addEventListener("click", function (event) {
    event.stopPropagation();
});

总之,以下是来自你的问题的更新后的代码,应该按预期工作:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->
function singleMenu(targetId, menuId, show = false) {
    const targetElement = document.getElementById(targetId);
    const menuElement = document.getElementById(menuId);

    // Initial state
    if (show) {
        // show dropdown
        menuElement.style.display = "block";
        targetElement.classList.add("active");
    } else {
        // hide dropdown
        menuElement.style.display = "none";
        targetElement.classList.remove("active");
    }

    // Toggle menu visibility when target element is clicked
    targetElement.addEventListener("click", () => {
        show = !show;

        if (show) {
            // show dropdown
            menuElement.style.display = "block";
            targetElement.classList.add("active");
        } else {
            // hide dropdown
            menuElement.style.display = "none";
            targetElement.classList.remove("active");
        }
    });

    // Close menu if clicked outside of container
    document.addEventListener("click", (event) => {
        if (!targetElement.parentElement.contains(event.target)) {
            show = false;
            menuElement.style.display = "none";
            targetElement.classList.remove("active");
        }
    });

    // Prevent menu from closing when clicked inside the menu element
    /* menuElement.addEventListener("click", function (event) {
        event.stopPropagation();
    }); */

    // Calculate half of the targetElement width
    const targetHalfWidth = targetElement.offsetWidth / 2;

    // Set a CSS variable with the half width value
    targetElement.style.setProperty(
        "--target-half-width",
        targetHalfWidth + "px"
    );
}

 singleMenu("target_id1", "menu_id1", false);
 singleMenu("target_id2", "menu_id2", false);
 $(document).ready(function () {
   // Apply the niceSelect plugin to all select elements
   $("select").niceSelect();
 });

<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <link
            rel="stylesheet"
            id="hello-elementor-child-style-css"
            href="https://fs.codelinden.com/wp-content/themes/hello-child/style.css?ver=3"
            media="all"
        />
        <link rel="stylesheet" href="header.css" />
        <script src="header.js" defer></script>

        <!-- single-menu dropdown style -->
        <link rel="stylesheet" href="single-menu-dropdown.css" />

        <!-- custom form element style (nice-select) -->
        <link rel="stylesheet" href="form.css" />

        <!-- nice-select style-->
        <link
            rel="stylesheet"
            href="https://cdnjs.cloudflare.com/ajax/libs/jquery-nice-select/1.1.0/css/nice-select.min.css"
            integrity="sha512-CruCP+TD3yXzlvvijET8wV5WxxEh5H8P4cmz0RFbKK6FlZ2sYl3AEsKlLPHbniXKSrDdFewhbmBK5skbdsASbQ=="
            crossorigin="anonymous"
            referrerpolicy="no-referrer"
        />

        <title>Header</title>
    </head>
    <body>
        <header class="header HruDj">
            <div class="nav-dropdown target-id DeYlt">
                <p id="target_id1">toggle dropdown</p>

                <!-- single-menu dropdown container -->
                <div id="menu_id1" class="menu-id">
                    <div class="form-field full-width">
                        <input
                            type="hidden"
                            name="form_my_contact_form"
                            value="1"
                        />
                        <label for="product_type">Product Type</label>
                        <select
                            name="product_type"
                            id="product_type"
                            required=""
                        >
                            <option value="book">Book</option>
                            <option value="movie">Movie</option>
                            <option value="music">Music</option>
                            <option value="" disabled="">
                                Select a product type
                            </option>
                        </select>
                    </div>
                </div>
            </div>
            <div class="nav-dropdown target-id DeYlt">
                <p id="target_id2">toggle dropdown</p>

                <!-- single-menu dropdown container -->
                <div id="menu_id2" class="menu-id">
                    <div class="form-field full-width">
                        <input
                            type="hidden"
                            name="form_my_contact_form"
                            value="1"
                        />
                        <label for="product_type">Product Type</label>
                        <select
                            name="product_type"
                            id="product_type"
                            required=""
                        >
                            <option value="book">Book</option>
                            <option value="movie">Movie</option>
                            <option value="music">Music</option>
                            <option value="" disabled="">
                                Select a product type
                            </option>
                        </select>
                    </div>
                </div>
            </div>
        </div>
        </header>

        <!-- jquery cdn -->
        <script src="popup/jquery/jquery.min.js"></script>

        <!-- single-menu dropdown script -->
        <script src="single-menu-dropdown.js"></script>

        <!-- nice-select script -->
        <script
            src="https://cdnjs.cloudflare

<details>
<summary>英文:</summary>

So I was able to arrive at the desired result but with some small changes.
There didn&#39;t seem to be any approach with the `event.stopPropagation()` that would work consistently. 

What you can do is that instead of setting the whole menu parent as the click handler set it to work on the more direct target instead.


This means that instead of using

     &lt;div class=&quot;nav-dropdown target-id DeYlt&quot; id=&quot;target_id1&quot;&gt;
         &lt;p&gt;toggle dropdown&lt;/p&gt;
You would want to add the target id to the p tag inside.

     &lt;div class=&quot;nav-dropdown target-id DeYlt&quot;&gt;
         &lt;p id=&quot;target_id1&quot;&gt;toggle dropdown&lt;/p&gt;

Same for the menu_id2 and target_id2.

This will require a small change in the javascript.
Change the click handler that closes the menu when clicking outside to handle `targetElement.parentElement` instead to account for the target being within the menu now.

     // Close menu if clicked outside of container
        document.addEventListener(&quot;click&quot;, (event) =&gt; {
            if (!targetElement.parentElement.contains(event.target)) {
                show = false;
                menuElement.style.display = &quot;none&quot;;
                targetElement.classList.remove(&quot;active&quot;);
            }
    });

Get rid of the menu stop propagation item as it&#39;s no longer needed.

    menuElement.addEventListener(&quot;click&quot;, function (event) {
        event.stopPropagation();


All in all, here&#39;s what an updated code from your question looks like which should work as expected.

&lt;!-- begin snippet: js hide: false console: true babel: false --&gt;

&lt;!-- language: lang-js --&gt;

    function singleMenu(targetId, menuId, show = false) {
        const targetElement = document.getElementById(targetId);
        const menuElement = document.getElementById(menuId);

        // Initial state
        if (show) {
            // show dropdown
            menuElement.style.display = &quot;block&quot;;
            targetElement.classList.add(&quot;active&quot;);
        } else {
            // hide dropdown
            menuElement.style.display = &quot;none&quot;;
            targetElement.classList.remove(&quot;active&quot;);
        }

        // Toggle menu visibility when target element is clicked
        targetElement.addEventListener(&quot;click&quot;, () =&gt; {
            show = !show;

            if (show) {
                // show dropdown
                menuElement.style.display = &quot;block&quot;;
                targetElement.classList.add(&quot;active&quot;);
            } else {
                // hide dropdown
                menuElement.style.display = &quot;none&quot;;
                targetElement.classList.remove(&quot;active&quot;);
            }
        });

        // Close menu if clicked outside of container
        document.addEventListener(&quot;click&quot;, (event) =&gt; {
            if (!targetElement.parentElement.contains(event.target)) {
                show = false;
                menuElement.style.display = &quot;none&quot;;
                targetElement.classList.remove(&quot;active&quot;);
            }
        });

        // Prevent menu from closing when clicked inside the menu element
       /* menuElement.addEventListener(&quot;click&quot;, function (event) {
            event.stopPropagation();
        });*/

        // Calculate half of the targetElement width
        const targetHalfWidth = targetElement.offsetWidth / 2;

        // Set a CSS variable with the half width value
        targetElement.style.setProperty(
            &quot;--target-half-width&quot;,
            targetHalfWidth + &quot;px&quot;
        );
    }


     singleMenu(&quot;target_id1&quot;, &quot;menu_id1&quot;, false);
     singleMenu(&quot;target_id2&quot;, &quot;menu_id2&quot;, false);
     $(document).ready(function () {
       // Apply the niceSelect plugin to all select elements
       $(&quot;select&quot;).niceSelect();
     });

&lt;!-- language: lang-html --&gt;

    &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js&quot;&gt;&lt;/script&gt;
    &lt;!DOCTYPE html&gt;
    &lt;html lang=&quot;en&quot;&gt;
        &lt;head&gt;
            &lt;meta charset=&quot;UTF-8&quot; /&gt;
            &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
            &lt;link
                rel=&quot;stylesheet&quot;
                id=&quot;hello-elementor-child-style-css&quot;
                href=&quot;https://fs.codelinden.com/wp-content/themes/hello-child/style.css?ver=3&quot;
                media=&quot;all&quot;
            /&gt;
            &lt;link rel=&quot;stylesheet&quot; href=&quot;header.css&quot; /&gt;
            &lt;script src=&quot;header.js&quot; defer&gt;&lt;/script&gt;

            &lt;!-- single-menu dropdown style --&gt;
            &lt;link rel=&quot;stylesheet&quot; href=&quot;single-menu-dropdown.css&quot; /&gt;

            &lt;!-- custom form element style (nice-select) --&gt;
            &lt;link rel=&quot;stylesheet&quot; href=&quot;form.css&quot; /&gt;

            &lt;!-- nice-select style--&gt;
            &lt;link
                rel=&quot;stylesheet&quot;
                href=&quot;https://cdnjs.cloudflare.com/ajax/libs/jquery-nice-select/1.1.0/css/nice-select.min.css&quot;
                integrity=&quot;sha512-CruCP+TD3yXzlvvijET8wV5WxxEh5H8P4cmz0RFbKK6FlZ2sYl3AEsKlLPHbniXKSrDdFewhbmBK5skbdsASbQ==&quot;
                crossorigin=&quot;anonymous&quot;
                referrerpolicy=&quot;no-referrer&quot;
            /&gt;

            &lt;title&gt;Header&lt;/title&gt;
        &lt;/head&gt;
        &lt;body&gt;
            &lt;header class=&quot;header HruDj&quot;&gt;
                &lt;div class=&quot;nav-dropdown target-id DeYlt&quot;&gt;
                    &lt;p id=&quot;target_id1&quot;&gt;toggle dropdown&lt;/p&gt;

                    &lt;!-- single-menu dropdown container --&gt;
                    &lt;div id=&quot;menu_id1&quot; class=&quot;menu-id&quot;&gt;
                        &lt;div class=&quot;form-field full-width&quot;&gt;
                            &lt;input
                                type=&quot;hidden&quot;
                                name=&quot;form_my_contact_form&quot;
                                value=&quot;1&quot;
                            /&gt;
                            &lt;label for=&quot;product_type&quot;&gt;Product Type&lt;/label&gt;
                            &lt;select
                                name=&quot;product_type&quot;
                                id=&quot;product_type&quot;
                                required=&quot;&quot;
                            &gt;
                                &lt;option value=&quot;book&quot;&gt;Book&lt;/option&gt;
                                &lt;option value=&quot;movie&quot;&gt;Movie&lt;/option&gt;
                                &lt;option value=&quot;music&quot;&gt;Music&lt;/option&gt;
                                &lt;option value=&quot;&quot; disabled=&quot;&quot;&gt;
                                    Select a product type
                                &lt;/option&gt;
                            &lt;/select&gt;
                        &lt;/div&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
                &lt;div class=&quot;nav-dropdown target-id DeYlt&quot;&gt;
                    &lt;p id=&quot;target_id2&quot;&gt;toggle dropdown&lt;/p&gt;

                    &lt;!-- single-menu dropdown container --&gt;
                    &lt;div id=&quot;menu_id2&quot; class=&quot;menu-id&quot;&gt;
                        &lt;div class=&quot;form-field full-width&quot;&gt;
                            &lt;input
                                type=&quot;hidden&quot;
                                name=&quot;form_my_contact_form&quot;
                                value=&quot;1&quot;
                            /&gt;
                            &lt;label for=&quot;product_type&quot;&gt;Product Type&lt;/label&gt;
                            &lt;select
                                name=&quot;product_type&quot;
                                id=&quot;product_type&quot;
                                required=&quot;&quot;
                            &gt;
                                &lt;option value=&quot;book&quot;&gt;Book&lt;/option&gt;
                                &lt;option value=&quot;movie&quot;&gt;Movie&lt;/option&gt;
                                &lt;option value=&quot;music&quot;&gt;Music&lt;/option&gt;
                                &lt;option value=&quot;&quot; disabled=&quot;&quot;&gt;
                                    Select a product type
                                &lt;/option&gt;
                            &lt;/select&gt;
                        &lt;/div&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
            &lt;/div&gt;
            &lt;/header&gt;

            &lt;!-- jquery cdn --&gt;
            &lt;script src=&quot;popup/jquery/jquery.min.js&quot;&gt;&lt;/script&gt;

            &lt;!-- single-menu dropdown script --&gt;
            &lt;script src=&quot;single-menu-dropdown.js&quot;&gt;&lt;/script&gt;

            &lt;!-- nice-select script --&gt;
            &lt;script
                src=&quot;https://cdnjs.cloudflare.com/ajax/libs/jquery-nice-select/1.1.0/js/jquery.nice-select.min.js&quot;
                integrity=&quot;sha512-NqYds8su6jivy1/WLoW8x1tZMRD7/1ZfhWG/jcRQLOzV1k1rIODCpMgoBnar5QXshKJGV7vi0LXLNXPoFsM5Zg==&quot;
                crossorigin=&quot;anonymous&quot;
                referrerpolicy=&quot;no-referrer&quot;
            &gt;&lt;/script&gt;

            &lt;!-- initialize dropdown and select --&gt;
            &lt;script&gt;
                // Call singleMenu function for each menu
               
            &lt;/script&gt;
        &lt;/body&gt;
    &lt;/html&gt;

&lt;!-- end snippet --&gt;



Note: moved the following code to the javascript portion only to make the code snippet runnable, that is not a required modification.

     singleMenu(&quot;target_id1&quot;, &quot;menu_id1&quot;, false);
     singleMenu(&quot;target_id2&quot;, &quot;menu_id2&quot;, false);
     $(document).ready(function () {
       // Apply the niceSelect plugin to all select elements
       $(&quot;select&quot;).niceSelect();
     });

</details>



# 答案3
**得分**: 0

添加事件监听器到 `targetElement` 时,尝试通过给第三个属性设置为 `true` 来指定 [`useCapture`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) 为 `true`。这样可以在 `menuElement` 的点击事件之前触发:

```javascript
// 当目标元素被点击时切换菜单的可见性
targetElement.addEventListener('click', () => {
	show = !show;

	if (show) {
		// 显示下拉菜单
		menuElement.style.display = 'block';
		targetElement.classList.add('active');
	} else {
		// 隐藏下拉菜单
		menuElement.style.display = 'none';
		targetElement.classList.remove('active');
	}
}, true);  // 将 useCapture 设置为 true
英文:

When adding event listener to targetElement, try specifying useCapture to true by giving a third property of true. So it triggers before menuElement's click event:

// Toggle menu visibility when target element is clicked
targetElement.addEventListener(&#39;click&#39;, () =&gt; {
	show = !show;

	if (show) {
		// show dropdown
		menuElement.style.display = &#39;block&#39;;
		targetElement.classList.add(&#39;active&#39;);
	} else {
		// hide dropdown
		menuElement.style.display = &#39;none&#39;;
		targetElement.classList.remove(&#39;active&#39;);
	}
}, true);  // set useCapture to true

huangapple
  • 本文由 发表于 2023年7月20日 14:31:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76727233.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定