如何允许鼠标悬停事件,无论元素位于何处?

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

How To Allow Mouse Hover Events No Matter Where An Element Is?

问题

我正在尝试制作一个登录表单,其中一个输入是用户的位置。我想在标签上使用国旗符号,因此我最终创建了一个自定义的下拉菜单,而不是使用内置的HTML option标签。我已经让下拉菜单能够打开和关闭,并选择选项,但是所有选项的包装div溢出了我的覆盖表单容器div的边缘。我使用了一些JavaScript逻辑来设置表单包装器的overflow-y属性为visible,overflow-x属性为clip,以使元素能够显示在边缘上。这对于显示下拉菜单非常有效,但是我不能与溢出到底层父容器边缘的任何对象进行交互,是否有办法使鼠标/悬停/单击事件仍然能够在元素上执行,尽管它们已经溢出到底层父容器的边缘?

在最简单的形式下,代码有点像这样:

<div class="registerStep4" id="registerStep4">
    <!--...-->
    <div class="location">
        <div class="dropdown">
            <input type="text" class="dropDownTextBox" placeholder="Select Country" readonly>
            <div class="option">
                <div onclick="show('United States')"><span class="fi fi-us"></span> United States</div>
                <div onclick="show('United Kingdom')"><span class="fi fi-gb"></span> United Kingdom</div>
                <div onclick="show('Afghanistan')"><span class="fi fi-af"></span> Afghanistan</div>
                <div onclick="show('Albania')"><span class="fi fi-al"></span> Albania</div>
                <div onclick="show('Algeria')"><span class="fi fi-dz"></span> Algeria</div>
                <div onclick="show('Andorra')"><span class="fi fi-ad"></span> Andorra</div>
                <div onclick="show('Angola')"><span class="fi fi-an"></span> Angola</div>
                <div onclick="show('Antigua and Barbuda')"><span class="fi fi-ag"></span> Antigua and Barbuda</div>
                <div onclick="show('Argentina')"><span class="fi fi-ar"></span> Argentina</div>
            </div>
        </div>
    </div>
</div>

CSS部分:

#registerStep4 {
    width: 360px;
    position: absolute;
    top: 0;
    transform: translateX(1000px);
    user-select: none;
    height: 330px;
}

/* 其他CSS样式省略 */

.dropdown .option {
    position: absolute;
    width: 200px;
    /* 其他CSS样式省略 */
}

JavaScript部分:

const dropdownSelect = document.querySelector('.dropdown');
const formWrapper = document.getElementById("formWrapper");
dropdownSelect.onclick = function() {
    dropdownSelect.classList.toggle('active');

    if(dropdownSelect.classList.contains('active')) {
        formWrapper.style.overflowY = "visible";
        formWrapper.style.overflowX = "clip";
    } else {
        formWrapper.style.overflowY = "hidden";
        formWrapper.style.overflowX = "hidden";
    }
}

在当前形式中,这可以用于显示下拉菜单,单击时会展开所有选项,并允许单击位于registerStep4 div边界内的所有选项div。

英文:

I'm trying to make a login form and one of the inputs I'm taking is the users location, I wanted to use flags symbols on the labels so I ended up making a custom dropdown menu rather than using the inbuilt HTML option tag. I got the dropdown to be able to open and close it as well as select options, however, the wrapping div of all the options overflows over the edge of my overlying form containing div. I got the elements to display over the edge with a little bit of Javascript logic setting the overflow-y property of the form wrapper to visible and the overflow-x property to clip. This works perfectly for displaying the dropdown menu, however, I can't interact with any of the objects that are over the edge of the form containing div, is there a way to allow mouse/hover/click events to still be able to be performed on the elements even though they are flooding over the edge of the underlying parent container?

In the most simplistic form, the code is a little something like this:

&lt;!--HTML--&gt;
`&lt;div class=&quot;registerStep4&quot; id=&quot;registerStep4&quot;&gt;
                &lt;!--...--&gt;
                &lt;div class=&quot;location&quot;&gt;
                &lt;div class=&quot;dropdown&quot;&gt;
                  &lt;input type=&quot;text&quot; class=&quot;dropDownTextBox&quot; placeholder=&quot;Select Country&quot; readonly&gt;
                  &lt;div class=&quot;option&quot;&gt;
                    &lt;div onclick=&quot;show(&#39;United States&#39;)&quot;&gt;&lt;span class=&quot;fi fi-us&quot;&gt;&lt;/span&gt; United States&lt;/div&gt;
                    &lt;div onclick=&quot;show(&#39;United Kingdom&#39;)&quot;&gt;&lt;span class=&quot;fi fi-gb&quot;&gt;&lt;/span&gt; United Kingdom&lt;/div&gt;
                    &lt;div onclick=&quot;show(&#39;Afghanistan&#39;)&quot;&gt;&lt;span class=&quot;fi fi-af&quot;&gt;&lt;/span&gt; Afghanistan&lt;/option&gt;&lt;/div&gt;
                    &lt;div onclick=&quot;show(&#39;Albania&#39;)&quot;&gt;&lt;span class=&quot;fi fi-al&quot;&gt;&lt;/span&gt; Albania&lt;/div&gt;
                    &lt;div onclick=&quot;show(&#39;Algeria&#39;)&quot;&gt;&lt;span class=&quot;fi fi-dz&quot;&gt;&lt;/span&gt; Algeria&lt;/div&gt;
                    &lt;div onclick=&quot;show(&#39;Andorra&#39;)&quot;&gt;&lt;span class=&quot;fi fi-ad&quot;&gt;&lt;/span&gt; Andorra&lt;/option&gt;&lt;/div&gt;
                    &lt;div onclick=&quot;show(&#39;Angola&#39;)&quot;&gt;&lt;span class=&quot;fi fi-an&quot;&gt;&lt;/span&gt; Angola&lt;/div&gt;
                    &lt;div onclick=&quot;show(&#39;Antigua and Barbuda&#39;)&quot;&gt;&lt;span class=&quot;fi fi-ag&quot;&gt;&lt;/span&gt; Antigua and Barbuda&lt;/div&gt;
                    &lt;div onclick=&quot;show(&#39;Argentina&#39;)&quot;&gt;&lt;span class=&quot;fi fi-ar&quot;&gt;&lt;/span&gt; Argentina&lt;/option&gt;&lt;/div&gt;
                  &lt;/div&gt;
                &lt;/div&gt;
                &lt;/div&gt;`
/* CSS */
#registerStep4 {
    width: 360px;
    position: absolute;
    top: 0;
    transform: translateX(1000px);
    user-select: none;
    height: 330px;
}

.dropdown {
    width: 100%;
}

.dropdown input {
    width: 85%;
    padding: 10px 30px;
    cursor: pointer;
    display: block;
    margin: auto;
    background: rgb(25, 34, 58);
    border: 0;
    outline: none;
    border-radius: 30px;
    color: white;
    transition: 0.5s;
    font-size: 13px;
    box-shadow: none;
}

.dropdown input::placeholder {
    text-align: center;
    color: white;
}

.dropdown .option {
    position: absolute;
    width: 200px;
    text-align: left;
    margin-left: 50%;
    transform: translateX(-50%);
    background-color: rgb(69, 81, 114);
    height: 0px;
    transition: 0.25s;
    z-index: 1000;
    overflow-y: scroll;
    overflow-x: hidden;
}

.dropdown .option::-webkit-scrollbar {
    width: 4px;
}

.dropdown .option::-webkit-scrollbar-thumb {
    background: white;
    border-radius: 4px;
}

.dropdown.active .option {
    height: 180px;
}

.dropdown .option div {
    padding-top: 10px;
    padding-bottom: 10px;
    cursor: pointer;
    color: white;
    font-size: 14px;
    /*pointer-events: visibleFill;????????*/
}

.dropdown .option div:hover {
    background: rgb(97, 110, 145);
}

.dropdown .option div span {
    position: relative;
    margin-left: 5px;
}

.dropdown::before {
    content: &#39;&#39;;
    position: relative;
    display: inline-block;
    right: -120px;
    top: 30px;
    z-index: 1000;
    width: 8px;
    height: 8px;
    border-top: 2px solid white;
    border-right: 2px solid white;
    transform: rotate(-45deg);
    transition: 0.25s;
    pointer-events: none;
}

.dropdown.active::before {
    top: 25px;
    transform:rotate(135deg);
}
//Javascript
const dropdownSelect = document.querySelector(&#39;.dropdown&#39;);
const formWrapper = document.getElementById(&quot;formWrapper&quot;);
dropdownSelect.onclick = function() {
    dropdownSelect.classList.toggle(&#39;active&#39;);

    if(dropdownSelect.classList.contains(&#39;active&#39;)) {
        formWrapper.style.overflowY = &quot;visible&quot;;
        formWrapper.style.overflowX = &quot;clip&quot;;
    } else {
        formWrapper.style.overflowY = &quot;hidden&quot;;
        formWrapper.style.overflowX = &quot;hidden&quot;;
    }
}

In the current form, this works to display the dropdown, on click it drops down all the options, and allows click on all the option divs that are within the bounds of the registerStep4 div

答案1

得分: 0

我对您的代码进行了一些更改以复制问题。我在您的HTML中删除了一些杂散的&lt;option&gt;&lt;div&gt;标签,将JS中的#formWrapper更改为#registerStep4(因为我认为这是您的本意),并将#registerStep4元素的高度调整为100px以确实让下拉框溢出。这样,我无法与#registerStep4之外的下拉框交互,就像您描述的那样。

我认为这种行为不符合规范。很可能,这是Chrome的问题,因为我无法在Firefox中复制这种行为。问题似乎是由于#registerStep4上的transform: translateX(1000px)属性引起的。如果您移除此属性,问题将得到解决。

我不太了解您的具体情况,但我建议两个选项:

  1. 您是否真的需要将#registerStep4的内容在水平方向上隐藏?如果您在#registerStep4上移除所有溢出属性,下拉框应该按预期工作。
  2. 如果您确实需要将内容在水平方向上隐藏,是否真的需要将div平移1000px?如果需要,是否必须使用变换?由于#registerStep4已经绝对定位,您可以使用left: 1000px;属性来实现相同的效果。

以下是使用left: 1000px;而不是变换的代码片段。结果相同,但问题已经解决(至少在我这里)。我无法提供更多帮助,但希望这对您有用。

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

<!-- language: lang-js -->
const dropdownSelect = document.querySelector('.dropdown');
const formWrapper = document.getElementById("registerStep4");

dropdownSelect.onclick = function() {
    dropdownSelect.classList.toggle('active');

    if(dropdownSelect.classList.contains('active')) {
        formWrapper.style.overflowY = "visible";
        formWrapper.style.overflowX = "clip";
    } else {
        formWrapper.style overflowY = "hidden";
        formWrapper.style overflowX = "hidden";
    }
}

<!-- language: lang-css -->
#registerStep4 {
    width: 360px;
    position: absolute;
    top: 0;
    left: 1000px;
    user-select: none;
    height: 100px;
}

.dropdown {
    width: 100%;
}

/* ...(其余CSS样式)... */

<!-- language: lang-html -->

<div class="registerStep4" id="registerStep4">
  <div class="location">
    <div class="dropdown">
      <input type="text" class="dropDownTextBox" placeholder="Select Country" readonly>
      <div class="option">
        <div onclick="show('United States')"><span class="fi fi-us"></span> United States</div>
        <div onclick="show('United Kingdom')"><span class="fi fi-gb"></span> United Kingdom</div>
        <div onclick="show('Afghanistan')"><span class="fi fi-af"></span> Afghanistan</div>
        <div onclick="show('Albania')"><span class="fi fi-al"></span> Albania</div>
        <div onclick="show('Algeria')"><span class="fi fi-dz"></span> Algeria</div>
        <div onclick="show('Andorra')"><span class="fi fi-ad"></span> Andorra</div>
        <div onclick="show('Angola')"><span class="fi fi-an"></span> Angola</div>
        <div onclick="show('Antigua and Barbuda')"><span class="fi fi-ag"></span> Antigua and Barbuda</div>
        <div onclick="show('Argentina')"><span class="fi fi-ar"></span> Argentina</div>
      </div>
    </div>
  </div>
</div>

<!-- end snippet -->
英文:

I had to make some changes to your code to replicate the issue. I removed some stray &lt;option&gt; and &lt;div&gt; tags in your HTML, changed the #formWrapper in your JS to #registerStep4 (as I presume you intended), and adjusted the height of the #registerStep4 element to 100px to actually get the dropdown to overflow. This way, I can't interact with the dropdown beyond the edge of #registerStep4 as you described.

I don't believe this behavior is by spec. Most likely, this is an issue with Chrome, as I could not replicate the behavior in Firefox. The issue seems to be caused by the transform: translateX(1000px) property on #registerStep4. If you remove the property, the issue resolves itself.

I am not familiar with your case exactly, but I would suggest two options:

  1. Do you really need the content of #registerStep4 to be hidden in x? If you remove all overflow properties on #registerStep4, the dropdown should work as expected.
  2. If you really need the content to be hidden in x, do you need really need for the div to be translated by 1000px? If you do, does it have to be with a transform? As #registerStep4 is already absolutely positioned, you can use the left: 1000px; property to achieve the same result.

Below is your snipped using left: 1000px; instead of a transform. The result is the same, but the issue is resolved (at least by me). I can't offer more help as I, but I hope this was useful.

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

<!-- language: lang-js -->

const dropdownSelect = document.querySelector(&#39;.dropdown&#39;);
const formWrapper = document.getElementById(&quot;registerStep4&quot;);
dropdownSelect.onclick = function() {
dropdownSelect.classList.toggle(&#39;active&#39;);
if(dropdownSelect.classList.contains(&#39;active&#39;)) {
formWrapper.style.overflowY = &quot;visible&quot;;
formWrapper.style.overflowX = &quot;clip&quot;;
} else {
formWrapper.style.overflowY = &quot;hidden&quot;;
formWrapper.style.overflowX = &quot;hidden&quot;;
}
}

<!-- language: lang-css -->

#registerStep4 {
width: 360px;
position: absolute;
top: 0;
left: 1000px;
user-select: none;
height: 100px;
}
.dropdown {
width: 100%;
}
.dropdown input {
width: 85%;
padding: 10px 30px;
cursor: pointer;
display: block;
margin: auto;
background: rgb(25, 34, 58);
border: 0;
outline: none;
border-radius: 30px;
color: white;
transition: 0.5s;
font-size: 13px;
box-shadow: none;
}
.dropdown input::placeholder {
text-align: center;
color: white;
}
.dropdown .option {
position: absolute;
width: 200px;
text-align: left;
margin-left: 50%;
transform: translateX(-50%);
background-color: rgb(69, 81, 114);
height: 0px;
transition: 0.25s;
z-index: 1000;
overflow-y: scroll;
overflow-x: hidden;
}
.dropdown .option::-webkit-scrollbar {
width: 4px;
}
.dropdown .option::-webkit-scrollbar-thumb {
background: white;
border-radius: 4px;
}
.dropdown.active .option {
height: 180px;
}
.dropdown .option div {
padding-top: 10px;
padding-bottom: 10px;
cursor: pointer;
color: white;
font-size: 14px;
/*pointer-events: visibleFill;????????*/
}
.dropdown .option div:hover {
background: rgb(97, 110, 145);
}
.dropdown .option div span {
position: relative;
margin-left: 5px;
}
.dropdown::before {
content: &#39;&#39;;
position: relative;
display: inline-block;
right: -120px;
top: 30px;
z-index: 1000;
width: 8px;
height: 8px;
border-top: 2px solid white;
border-right: 2px solid white;
transform: rotate(-45deg);
transition: 0.25s;
pointer-events: none;
}
.dropdown.active::before {
top: 25px;
transform: rotate(135deg);
}

<!-- language: lang-html -->

&lt;div class=&quot;registerStep4&quot; id=&quot;registerStep4&quot;&gt;
&lt;div class=&quot;location&quot;&gt;
&lt;div class=&quot;dropdown&quot;&gt;
&lt;input type=&quot;text&quot; class=&quot;dropDownTextBox&quot; placeholder=&quot;Select Country&quot; readonly&gt;
&lt;div class=&quot;option&quot;&gt;
&lt;div onclick=&quot;show(&#39;United States&#39;)&quot;&gt;&lt;span class=&quot;fi fi-us&quot;&gt;&lt;/span&gt; United States&lt;/div&gt;
&lt;div onclick=&quot;show(&#39;United Kingdom&#39;)&quot;&gt;&lt;span class=&quot;fi fi-gb&quot;&gt;&lt;/span&gt; United Kingdom&lt;/div&gt;
&lt;div onclick=&quot;show(&#39;Afghanistan&#39;)&quot;&gt;&lt;span class=&quot;fi fi-af&quot;&gt;&lt;/span&gt; Afghanistan&lt;/div&gt;
&lt;div onclick=&quot;show(&#39;Albania&#39;)&quot;&gt;&lt;span class=&quot;fi fi-al&quot;&gt;&lt;/span&gt; Albania&lt;/div&gt;
&lt;div onclick=&quot;show(&#39;Algeria&#39;)&quot;&gt;&lt;span class=&quot;fi fi-dz&quot;&gt;&lt;/span&gt; Algeria&lt;/div&gt;
&lt;div onclick=&quot;show(&#39;Andorra&#39;)&quot;&gt;&lt;span class=&quot;fi fi-ad&quot;&gt;&lt;/span&gt; Andorra&lt;/div&gt;
&lt;div onclick=&quot;show(&#39;Angola&#39;)&quot;&gt;&lt;span class=&quot;fi fi-an&quot;&gt;&lt;/span&gt; Angola&lt;/div&gt;
&lt;div onclick=&quot;show(&#39;Antigua and Barbuda&#39;)&quot;&gt;&lt;span class=&quot;fi fi-ag&quot;&gt;&lt;/span&gt; Antigua and Barbuda&lt;/div&gt;
&lt;div onclick=&quot;show(&#39;Argentina&#39;)&quot;&gt;&lt;span class=&quot;fi fi-ar&quot;&gt;&lt;/span&gt; Argentina&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年4月4日 09:49:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/75924923.html
匿名

发表评论

匿名网友

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

确定