我创建了一个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);
}
}
}
文档加载:
按下第一个标签:
答案 0 :(得分:2)
测试鼠标是否真正移动到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);
答案 1 :(得分:0)
这就是我最终杀死恶魔的方式(丑陋,但仍有效):
(1)我为最后一个悬停指数和最后一个聚焦指数创建了两个不同的变量
(2)我为onmouseover
,onmouseout
,onfocus
和onblur
创建了四个不同的函数
(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);
}
}
}