Check if the radio button is changed by the keyboard or mouse

后端 未结 6 1997
遇见更好的自我
遇见更好的自我 2021-01-15 08:14

Is possible to tell how a radio button was selected, i.e. if the user used the keyboard or the mouse to click the radio button?

相关标签:
6条回答
  • 2021-01-15 08:55
     <input type="radio" id="radiobtn">
    
     $("#radiobtn").keyup(function(e) {
        var code = e.keyCode || e.which;
        if (code == 32) { 
           alert("Space bar was pressed");
        }
        else {
           alert("mouse click");
        }
     }); 
    
    0 讨论(0)
  • 2021-01-15 08:58

    event.detail is another possible indicator if click is caused by keyboard, indicating click number. That gives better cross-browser solution, compared to event.x/y.

    <input name="letter" type="radio" value="a"> a
    <input name="letter" type="radio" value="b"> b
    <input name="letter" type="radio" value="c"> c
    
    <script>
    document.addEventListener('click', e => {
      if (!e.detail) console.log('Keyboard click')
      else console.log('Mouseclick')
    })
    </script>
    
    0 讨论(0)
  • 2021-01-15 09:05

    Seems that is not doable with a change event. I resolved in this way, If someone knows a more elegant way let me know:

    <input name="text" type="input">
    <input name="radioButton" type="radio" value="1"> 1
    <input name="radioButton" type="radio" value="2"> 2
    <input name="radioButton" type="radio" value="3"> 3
    
    var radioButtonValue;
    $('input[name="radioButton"]').on("click", function(e) {
        var value = $(this).val();
        if (value !== radioButtonValue) {
            if (e.clientX === 0 && e.clientY === 0) {
                console.log("keyboard");
            } else {
                console.log("mouse");
            };
            radioButtonValue = value;        
        }    
    });
    

    http://jsfiddle.net/gy59n3u6/1/

    0 讨论(0)
  • 2021-01-15 09:08

    There is no cross-browser solution for detecting a 'real mouse click' vs 'a click event triggered by the keyboard'.

    Ideally, we would check the MouseEvent.button value. Unfortunately only IE11 & Edge will properly record a value of '-1' for a keyboard click. At this time, all other browsers will record a value of '0' for any type of click.

    Another option is to check the MouseEvent.pageX & MouseEvent.pageY values. In Chrome, keyboard clicks will have a value of 0 for both these values. Firefox will also have a value of 0 but it will also factor in the $(window).scrollLeft() & $(window).scrollTop() values. Unfortunately Safari will not record consistent pageX/pageY values for keyboard events and IE will record the exact location of the mouse when the keyboard click event was fired.

    The best cross browser solution is to add a mouseup event listener to your radio inputs and their associated labels and set a flag when it is triggered. When a keyboard toggles a radio button the click event is fired but the mouseup event is not. So if you set a flag on mouseup and check this flag on click, you should be able to detect if the mouse clicked the radio button.

    var clickedByMouse = false;
    $('label, input[type="radio"]').mouseup(function(e) {
        clickedByMouse = true;
    });
    $('input[type="radio"]').click(function() {
        if(clickedByMouse){
            console.log("mouse");
            //Reset flag
            clickedByMouse = false;
        }else{
            console.log("keyboard");
        }
    });
    

    This solution worked cross-browser, including Safari and older IE versions. You may notice I included the label tag with the mouseup event, this is because label tags can toggle a radio input. They either can be wrapped around a radio input or linked to a radio input using the for attribute.

    Above I mentioned that there is no cross-browser solution. This is because I began testing this solution with screen readers, specifically JAWS, and discovered another issue.

    JAWS by default will not let you use the arrow keys to toggle between radio buttons of the same group. You have to press the enter key to enter a special 'forms mode' and then you can use the arrow keys as intended. Pressing the enter key will however toggle the radio button and JAWS will trigger a mouseup & click event on the radio button. So the above code will not work effectively.

    var clickedByMouse = false;
    $('label, input[type="radio"]').mouseup(function(e) {
        var keyboardPageX = (e.pageX === 0 || e.pageX === $(window).scrollLeft()) ? true : false,
            keyboardPageY = (e.pageY === 0 || e.pageY === $(window).scrollTop()) ? true : false;
    
        if((keyboardPageX && keyboardPageY) || (e.button === -1)){
           console.log("keyboard mouseup");
        }else{
           clickedByMouse = true;
        }
    });
    $('input[type="radio"]').click(function() {
        if(clickedByMouse){
            console.log("mouse");
            //Reset flag
            clickedByMouse = false;
        }else{
            console.log("keyboard");
        }
    });
    

    The solution above also uses the MouseEvent's pageX, pageY and button values to double check for a keyboard click event. Depending on the browser being used, it will work with JAWS.

    0 讨论(0)
  • 2021-01-15 09:18

    You could do a listener for when the user presses space bar (I assume that's the keyboard command you are listening to)

    $(document).keypress(function(e){
        if(e.which == 32){
            $("input[name=someRadioGroup]:radio").change(function () {
                console.log("Space bar was pressed to change the radio button"); 
            });
        }
    });  
    

    http://jsfiddle.net/4pjnrcoz/1/

    Thanks to @Mysteryos, he added the HTML to this fiddle: http://jsfiddle.net/4pjnrcoz/3

    0 讨论(0)
  • 2021-01-15 09:20

    Here is a pretty good discussion on the Radio buttons Click and Change events.

    One thing you can do is, create a click event handler and set a flag, use it later on a different (callback maybe!) function to identify if the change has been triggered by Keyboard or Mouse Click!

    0 讨论(0)
提交回复
热议问题