2016-08-07 8 views
1

Я создал таблицу HTML с тремя ссылками в каждой из строк. Моя цель - выделить строку всякий раз, когда пользователь (1) нависает над ней или (2) входит в ссылку, нажав вкладку. Я также хотел бы убедиться, что только одна строка подсвечивается за раз. Вот упрощенная версия моего HTML (show.htm):Как предотвратить автоматическое onmouseover после onfocus?

<!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; 
} 

Всякий раз, когда страница загружается и жму вкладка, первая ссылка получает фокус, но строка, на которой лежит указатель мыши (не обязательно первая строка), подсвечивается. Похоже, что событие onmouseover срабатывает сразу же после onfocus, хотя фактически движение мыши не производится. Как решить эту проблему (без использования какой-либо внешней библиотеки, такой как JQuery)? Любая помощь будет оценена по достоинству.


Update:

Я изменил свой код Javascript для того, чтобы обнаружить фактическое движение мыши (заимствуя идею от ответа Ник Быка). Но проблема осталась. Мне нужна дополнительная помощь.

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); 
    } 
    } 
} 

Нагрузка документа:

screenshot

Первая вкладка нажата:

screenshot

ответ

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); 
    } 
    } 
} 
2

тест, если мышь действительно переехавшая в вас r 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); 

EDIT: Рабочая jsFiddle.

EDIT: Для обновленного вопроса, все еще редактируется так держись:

Первое событие для нажатия кнопки на вкладке:

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); 
+0

Если я сделать это, 'onmouseover' не имеет свой желаемый эффект, т.е. изменение цвета фона наведен строки. –

+0

Почему бы и нет? Это будет, если последние координаты события 'onmouseover' не совпадают с предыдущим событием' ommouseover'. –

+0

@SharanyaDutta Добавил комментарий к JS, чтобы помочь вам понять, где это решение. –