【问题标题】:How to prevent automatic onmouseover after onfocus?如何防止onfocus后自动鼠标悬停?
【发布时间】:2016-08-08 15:15:49
【问题描述】:

我创建了一个 HTML 表格,每行包含三个链接。我的目标是在用户 (1) 将鼠标悬停在一行上或 (2) 通过按 tab 进入链接时突出​​显示一行。我还想确保一次只突出显示一行。这是我的 HTML (show.htm) 的简化版本:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <script type="text/javascript" src="show.js"></script>
    <link rel="stylesheet" type="text/css" href="show.css"/>
  </head>
  <body>
  <h2>Basic Information:</h2>
  <table>
    <tr class="data">
      <td>London:</td>
      <td><a href="http://example.com/london_001.htm">Part 1</a></td>
      <td><a href="http://example.com/london_002.htm">Part 2</a></td>
      <td><a href="http://example.com/london_003.htm">Part 3</a></td>
    </tr>
    <tr class="data">
      <td>New York:</td>
      <td><a href="http://example.com/newyork_001.htm">Part 1</a></td>
      <td><a href="http://example.com/newyork_002.htm">Part 2</a></td>
      <td><a href="http://example.com/newyork_003.htm">Part 3</a></td>
    </tr>
    <tr class="data">
      <td>Tokyo:</td>
      <td><a href="http://example.com/tokyo_001.htm">Part 1</a></td>
      <td><a href="http://example.com/tokyo_002.htm">Part 2</a></td>
      <td><a href="http://example.com/tokyo_003.htm">Part 3</a></td>
    </tr>
    <tr class="data">
      <td>Rio de Janeiro:</td>
      <td><a href="http://example.com/riodejaneiro_001.htm">Part 1</a></td>
      <td><a href="http://example.com/riodejaneiro_002.htm">Part 2</a></td>
      <td><a href="http://example.com/riodejaneiro_003.htm">Part 3</a></td>
    </tr>
    <tr class="data">
      <td>Melbourne:</td>
      <td><a href="http://example.com/melbourne_001.htm">Part 1</a></td>
      <td><a href="http://example.com/melbourne_002.htm">Part 2</a></td>
      <td><a href="http://example.com/melbourne_003.htm">Part 3</a></td>
    </tr>
  </table>
  </body>
</html>

这里是 Javascript (show.js):

window.onload = function(){
  var rows = document.getElementsByClassName('data');
  var links = document.getElementsByTagName('a');
  var len = rows.length;
  var old_index = -1;
  var set_color = function(index, color){
    return function(){
      if(index !== old_index){
        if(old_index !== -1){
          rows[old_index].style.backgroundColor = null;
        }
        rows[index].style.backgroundColor = color;
        old_index = index;
      }
    }
  }
  var i, j;
  for(i = 0; i < len; i++){
    rows[i].onmouseover = set_color(i, '#FFFFBB');
    rows[i].onmouseout = set_color(i, null);
    for(j = 0; j < 3; j++){
      links[i*3+j].onfocus = set_color(i, '#FFFFBB');
      links[i*3+j].onblur = set_color(i, null);
    }
  }
}

最后,这里是 CSS (show.css):

table{
  margin:auto;
  width:98%;
  border-collapse:collapse;
  border:none;
}
td{
  border-top:1px solid gray;
  border-bottom:1px solid gray;
  border-left:none;
  border-right:none;
  vertical-align:center;
  font-weight:bold;
}
.data{
  background-color:rgba(120, 120, 240, 0.4);
  font-family:Tahoma;
  font-size:16px;
}
.data>td{
    padding:6px 16px;
}

每当加载页面并按下 tab 时,第一个链接都会获得焦点,但鼠标指针所在的行(不一定是第一行)会突出显示。似乎onmouseover 事件在onfocus 之后立即触发,即使实际上没有进行鼠标移动。如何解决这个问题(不使用任何外部库,如 JQuery)?任何帮助将不胜感激。


更新:

我已经修改了我的 Javascript 代码以检测实际的鼠标移动(从 Nick Bull 的回答中借用了这个想法)。但问题仍然存在。我需要进一步的帮助。

window.onload = function(){
  var rows = document.getElementsByClassName('data');
  var links = document.getElementsByTagName('a');
  var len = rows.length;
  var old_index = -1;
  var old_coords = {X:event.screenX, Y:event.screenY};
  var set_color = function(index, color, keyboard_event){
    return function(){
      if(keyboard_event || event.screenX !== old_coords.X || event.screenY !== old_coords.Y){
        if(index !== old_index){
          if(old_index !== -1){
            rows[old_index].style.backgroundColor = null;
          }
          rows[index].style.backgroundColor = color;
          old_index = index;
          if(!keyboard_event){
            old_coords.X = event.screenX;
            old_coords.Y = event.screenY;
          }
        }
      }
    }
  }
  var i, j;
  for(i = 0; i < len; i++){
    rows[i].onmouseover = set_color(i, '#FFFFBB', false);
    rows[i].onmouseout = set_color(i, null, false);
    for(j = 0; j < 3; j++){
      links[i*3+j].onfocus = set_color(i, '#FFFFBB', true);
      links[i*3+j].onblur = set_color(i, null, true);
    }
  }
}

文档加载:

第一个标签被按下:

【问题讨论】:

    标签: javascript html css onmouseover onfocus


    【解决方案1】:

    onmouseover 事件中测试鼠标是否真的移动了?

    所以:

    rows[i].onmouseover = set_color(i, '#FFFFBB');
    

    变成

    var lastEventCoords = {};
    
    document.getElementById("id").addEventListener("mouseover", function( event ) {   
      // If coords match, go home
      if (lastEventCoords.X == event.screenX && 
          lastEventCoords.Y == event.screenY) {
        return;
      }
      // If they don't match (i.e., mouse actually moved), this function will run
      else {
        alert('#FFFFBB')
      }
    
      lastEventCoords = { X: event.screenX, Y: event.screenY };
    }, false);
    

    编辑:工作jsFiddle

    编辑:对于更新后的问题,仍在编辑中,请稍等:

    首先是一个选项卡按键事件:

    function checkTabPress(e) {
      if (e.keyCode === 9) {
        var rows = document.getElementsByClassName("data");
    
        if (var i = 0; i < rows.length; i++) {
          rows[i].style.backgroundColor = null;
        }
    
        document.getActiveElement().style.backgroundColor = "#123456";
      }
    }
    
    document.addEventListener('keyup', function (e) {
      checkTabPress(e);
    }, false);
    

    【讨论】:

    • 如果我这样做,onmouseover 没有达到预期的效果,即改变悬停行的背景颜色。
    • 为什么不呢?如果最后一个 onmouseover 事件的坐标与前一个 ommouseover 事件的坐标不同,它会。
    • @SharanyaDutta 在 JS 中添加了一条注释,以帮助您了解该决定发生在哪里。
    • 是的,我能理解你的代码。但不知何故,它不起作用。我什至在else 块中添加了alert('Mouse moved!');。但是在实际的鼠标移动过程中没有弹出警告框。
    • @SharanyaDutta 当然,没有冒犯的意思,很多人不明白!很奇怪……让我想想。
    【解决方案2】:

    这就是我最终杀死恶魔的方式(够丑,但仍然有效):
    (1) 我为最后一个悬停索引和最后一个聚焦索引创建了两个不同的变量
    (2) 我为onmouseoveronmouseoutonfocusonblur创建了四个不同的函数
    (3) 我添加了一个超时来确保onmouseover 不会在onfocus 之后立即触发。

    这是修改后的 Javascript 代码:

    window.onload = function(){
      var rows = document.getElementsByClassName('data');
      var links = document.getElementsByTagName('a');
      var len = rows.length;
      var color = '#FFFFBB';
      var hovered_index = -1;
      var focused_index = -1;
      var mouseover_allowed = true;
      var set_color_onmouseover = function(index){
        return function(){
          if(mouseover_allowed){
            if(focused_index !== -1){
              rows[focused_index].style.backgroundColor = null;
            }
            rows[index].style.backgroundColor = color;
            hovered_index = index;
          }
        }
      }
      var set_color_onmouseout = function(index){
        return function(){
          if(hovered_index !== -1){
            rows[index].style.backgroundColor = null;
            hovered_index = -1;
          }
        }
      }
      var set_color_onfocus = function(index){
        return function(){
          if(hovered_index !== -1){
            rows[hovered_index].style.backgroundColor = null;
          }
          rows[index].style.backgroundColor = color;
          focused_index = index;
          // disable onmouseover for the next 100 milliseconds
          mouseover_allowed = false;
          setTimeout(function(){ mouseover_allowed = true; }, 100);
        }
      }
      var set_color_onblur = function(index){
        return function(){
          if(focused_index !== -1){
            rows[index].style.backgroundColor = null;
            focused_index = -1;
          }
        }
      }
      var i, j;
      for(i = 0; i < len; i++){
        rows[i].onmouseover = set_color_onmouseover(i);
        rows[i].onmouseout = set_color_onmouseout(i);
        for(j = 0; j < 3; j++){
          links[i*3+j].onfocus = set_color_onfocus(i);
          links[i*3+j].onblur = set_color_onblur(i);
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-04-23
      • 2010-12-25
      • 1970-01-01
      • 2011-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多