有没有办法确定

发布于 2024-08-30 08:45:21 字数 602 浏览 1 评论 0原文

我正在寻找一种方法来确定

我可以监听焦点/模糊、mouseup/mousedown 等事件,但我认为我无法可靠地从这些事件中找出菜单的状态。例如,mousedown 后跟 mouseup 可能意味着用户单击并拖动到某个选择并释放(在这种情况下,菜单现在关闭)或单击并释放以打开菜单(在这种情况下,菜单打开)。下拉菜单的具体行为似乎也取决于浏览器。

我知道如果我滚动自己的下拉菜单就可以做到这一点,但我更喜欢使用

有没有可靠的方法来确定下拉菜单是否打开?或者这是 Javascript 无法知道的事情?

结论:似乎没有任何有保证的方法来确定选择菜单是否打开,无论是通过询问对象还是通过侦听它触发的事件。

对于我自己的使用,我只是使用 onfocusonblur 跟踪选择是否具有焦点。我假设没有焦点就无法打开菜单,这在我测试过的所有浏览器中似乎都是如此。它实际上并没有告诉我菜单何时打开,但它告诉我何时无法打开,这对于我的目的来说已经足够了。

I'm looking for a way to determine if/when a <select> element's menu is open. I don't need to force it to open or close, just figure out if it's open or closed at a given time.

I can listen to events for focus/blur, mouseup/mousedown, etc., but I don't think I can reliably figure out the state of the menu from those events. For example, mousedown followed by mouseup could mean the user clicked and dragged to a selection and released (in which case the menu is now closed) or clicked and released to open the menu (in which case the menu is open). It also seems likely that the specific behavior of dropdown menus is browser-dependent.

I know I could do this if I roll my own dropdown menu, but I prefer to use <select>.

Is there a reliable way to find out if a dropdown menu is open? Or is this something that Javascript can't know?

Conclusion: There doesn't seem to be any guaranteed way to determine if a select menu is open, either by asking the object or by listening to the events it fires.

For my own use I'm just keeping track of whether the select has focus using onfocus and onblur. I'm assuming there's no way for the menu to be open without having focus, and that seems to hold true in all the browsers I've tested. It doesn't actually tell me when the menu is open, but it tells me when it can't be open, which is good enough for my purposes.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一笑百媚生 2024-09-06 08:45:21

您可以在 select 的 option 子元素中使用 mouseenter 事件,因为只有在 select 菜单打开时才可以在其中输入,或者也可以使用 click select 元素上的事件,通常在打开它时引发。

我认为要在精确的时刻测试它是否打开是不可能的。

You can play with mouseenter event in select's option child elements as you can only enter in them if select menu is open, or also with the click event on the select element, usually thrown when you open it.

To test in a precise moment if its open or not I think is not possible.

や三分注定 2024-09-06 08:45:21

在 Internet Explorer 中,选择元素是出了名的棘手。我认为没有任何方法可以可靠地确定一个是打开还是关闭。

Select elements are notoriously tricky in Internet Explorer. I don't think there is any way of reliably determining if one is open or closed.

柏拉图鍀咏恒 2024-09-06 08:45:21

我可以查看选择是否打开,然后当用户选择新选项或完全模糊选择时关闭。但是,如果您单击相同的选项,或者仅单击一次选择(关闭它但不模糊它),它仍然显示“向下”。致力于制定更完整的解决方案。所以,期望这个答案有编辑...

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.pack.js"></script>
<script type="text/javascript">
  var selected
$( document ).ready(


 function()
 { 
  $( '#test' )
      .mousedown( function(){ console.log( 'down' ); selected = $( this ).val() } )
      .blur( function(){ console.log( 'out' ) } )
      .change( function(){ console.log( 'out' ) } )
      .mouseleave( function(){ console.log( 'out' ) } )
      .mouseup( function(){ 
         if( $( this ).val() == selected ) 
           console.log( 'out' )
    }
   )
 } // function

) // ready
</script>

<select id="test">
 <option>1</option>
 <option>2</option>
</select>

编辑:添加了 mouseout

编辑2:添加了 mouseup - 现在可以使用!

I can see if the select is open, and then when it closes if the user selects a new option, or completely blurs the select. However, if you click on the same option, or just click out of the select once (closing it but not blurring it), it still shows "down". Working on a more complete solution. So, expect this answer to have edits...

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.pack.js"></script>
<script type="text/javascript">
  var selected
$( document ).ready(


 function()
 { 
  $( '#test' )
      .mousedown( function(){ console.log( 'down' ); selected = $( this ).val() } )
      .blur( function(){ console.log( 'out' ) } )
      .change( function(){ console.log( 'out' ) } )
      .mouseleave( function(){ console.log( 'out' ) } )
      .mouseup( function(){ 
         if( $( this ).val() == selected ) 
           console.log( 'out' )
    }
   )
 } // function

) // ready
</script>

<select id="test">
 <option>1</option>
 <option>2</option>
</select>

Edit: added mouseout

Edit2: added mouseup - works now!

初心 2024-09-06 08:45:21

这是您问题的完整答案。是的,它有点长,但它在所有场景中都具有魅力。

当用户在我的实验中快速选择一个选项时,上面使用 onClick 的答案不起作用,所以我为什么不给出完整的答案

function App() {
const [isOpen, setIsOpen] = useState(false);
  
  const componentRef = useRef(null);
  
    const selectClickHandle = (event) => {
  
      if (componentRef.current) {
        const rect = componentRef.current.getBoundingClientRect();
        const { clientX, clientY } = event;
  
        const isInComponent =
          clientX >= rect.left &&
          clientX <= rect.right &&
          clientY >= rect.top &&
          clientY <= rect.bottom;
  
        console.log(isInComponent);
        if (isInComponent == false) {
          setIsOpen(false);
        }
      }
    }
  
    const selectBlurHandle = () => {
      console.log("blur");
      setIsOpen(false);
    }
  
    const selectkeyHandle = (event) => {
      console.log("key");
      if (event.key === 'Enter' || event.keyCode === 13 || event.key === ' ' || event.keyCode === 32) {
        setIsOpen(true);
      }
    };
  
    const selectMousePress = (event) => {
      console.log("mouse");
      setIsOpen(!isOpen);
    }
    return (
      <div className="App">    
<h1 style={{ paddingTop: "200px" }}>currently closed {isOpen ? "true" : "false"}</h1>
      <div id="outer-container"
      >
        <select id="fruit" name="fruit"
          ref={componentRef}
          onMouseDown={selectMousePress}
          onClick={selectClickHandle}
          onBlur={selectBlurHandle}
          onKeyDown={selectkeyHandle}
        >
          <option value="apple" >Apple</option>
          <option value="banana">Banana</option>
          <option value="grape">Grape</option>
        </select>
      </div>
  );

}
export default App;

我还在媒体上写了一篇关于它的文章,如果需要更多说明,请访问。

https://medium .com/@ijlal.tanveer294/how-to-know-if-a-select-dropdown-is-open-555a304e7dda

Here is a full answer to your question. Yes its a bit long but it works like a charm in all scenarios.

Above answers which uses onClick don't work when user selects a option fast in my exp, so i though why not give a full answer

function App() {
const [isOpen, setIsOpen] = useState(false);
  
  const componentRef = useRef(null);
  
    const selectClickHandle = (event) => {
  
      if (componentRef.current) {
        const rect = componentRef.current.getBoundingClientRect();
        const { clientX, clientY } = event;
  
        const isInComponent =
          clientX >= rect.left &&
          clientX <= rect.right &&
          clientY >= rect.top &&
          clientY <= rect.bottom;
  
        console.log(isInComponent);
        if (isInComponent == false) {
          setIsOpen(false);
        }
      }
    }
  
    const selectBlurHandle = () => {
      console.log("blur");
      setIsOpen(false);
    }
  
    const selectkeyHandle = (event) => {
      console.log("key");
      if (event.key === 'Enter' || event.keyCode === 13 || event.key === ' ' || event.keyCode === 32) {
        setIsOpen(true);
      }
    };
  
    const selectMousePress = (event) => {
      console.log("mouse");
      setIsOpen(!isOpen);
    }
    return (
      <div className="App">    
<h1 style={{ paddingTop: "200px" }}>currently closed {isOpen ? "true" : "false"}</h1>
      <div id="outer-container"
      >
        <select id="fruit" name="fruit"
          ref={componentRef}
          onMouseDown={selectMousePress}
          onClick={selectClickHandle}
          onBlur={selectBlurHandle}
          onKeyDown={selectkeyHandle}
        >
          <option value="apple" >Apple</option>
          <option value="banana">Banana</option>
          <option value="grape">Grape</option>
        </select>
      </div>
  );

}
export default App;

Also I wrote an article on medium about it, do visit if need more clarification.

https://medium.com/@ijlal.tanveer294/how-to-know-if-a-select-dropdown-is-open-555a304e7dda

苦笑流年记忆 2024-09-06 08:45:21

更完整的解决方案是:

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.pack.js"></script>
<script type="text/javascript">
var selected,selected2
$( document ).ready(


 function()
 { 
  $( 'select[id$="test"]' )
      .mousedown( function(){ 
        console.log( 'predown' );
        if( $( this ).val() != selected ) {
          console.log( 'down' ); 
          selected = $( this ).val();
          selected2=null;} 
        else  
          selected=null;} )
      .blur( function(){ if (selected2==selected) {
        console.log( 'outb' );
        selected=null;
        selected2=null;} } )
      .mouseup( function(){ console.log( 'preoutu' );
         if( $( this ).val() != selected || $( this ).val() == selected2 ) {
            console.log( 'outu' );
            selected=null;
            selected2=null;
         }
         else
           selected2=$( this ).val();   
    }
   )
 } // function

) // ready
</script>


<select id="1test">
 <option>1</option>
 <option>2</option>
</select>
<select id="2test">
 <option>1</option>
 <option>2</option>
</select>

A more complete solution would be:

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.pack.js"></script>
<script type="text/javascript">
var selected,selected2
$( document ).ready(


 function()
 { 
  $( 'select[id$="test"]' )
      .mousedown( function(){ 
        console.log( 'predown' );
        if( $( this ).val() != selected ) {
          console.log( 'down' ); 
          selected = $( this ).val();
          selected2=null;} 
        else  
          selected=null;} )
      .blur( function(){ if (selected2==selected) {
        console.log( 'outb' );
        selected=null;
        selected2=null;} } )
      .mouseup( function(){ console.log( 'preoutu' );
         if( $( this ).val() != selected || $( this ).val() == selected2 ) {
            console.log( 'outu' );
            selected=null;
            selected2=null;
         }
         else
           selected2=$( this ).val();   
    }
   )
 } // function

) // ready
</script>


<select id="1test">
 <option>1</option>
 <option>2</option>
</select>
<select id="2test">
 <option>1</option>
 <option>2</option>
</select>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文