This should work when the same character occurs more than once.
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">
<title>table stuff</title>
<!--<link rel="stylesheet" href="screen.css" media="screen">-->
<style media="screen">
body {
background-color: #f9f9f9;
font: normal 1em / 1.5em BlinkMacSystemFont, -apple-system, 'Segoe UI', roboto, helvetica, arial, sans-serif;
}
table {
border-collapse: collapse;
background-color: #fff;
}
td {
padding: 0.4em;
border: 1px solid #999;
cursor:pointer
}
.highlight {
background-color: #fc9;
}
.selected{
background-color: #9ce;
}
</style>
</head>
<body>
<h2>Table One</h2>
<table id="table1">
<tbody>
<tr>
<td>a</td><td>b</td><td>c</td><td>d</td><td>e</td><td>f</td><td>g</td><td>h</td><td>i</td><td>a</td>
</tr>
<tr>
<td>k</td><td>l</td><td>m</td><td>n</td><td>o</td><td>p</td><td>q</td><td>r</td><td>s</td><td>t</td>
</tr>
<tr>
<td>u</td><td>v</td><td>w</td><td>x</td><td>y</td><td>z</td><td>1</td><td>2</td><td>3</td><td>4</td>
</tr>
<tr>
<td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>0</td><td>!</td><td>@</td><td>£</td>
</tr>
<tr>
<td>$</td><td>%</td><td>^</td><td>&</td><td>*</td><td>(</td><td>)</td><td>!</td><td>-</td><td>+</td>
</tr>
</tbody>
</table>
<h2>Table two</h2>
<table id="table2">
<tbody>
<tr>
<td>a</td><td>%</td><td>e</td><td>&</td><td>*</td><td>(</td><td>)</td><td>a</td><td>-</td><td>+</td>
</tr>
<tr>
<td>5</td><td>6</td><td>p</td><td>8</td><td>n</td><td>0</td><td>!</td><td>z</td><td>£</td><td>?</td>
</tr>
<tr>
<td>k</td><td>4</td><td>m</td><td>9</td><td>o</td><td>7</td><td>q</td><td>r</td><td>s</td><td>w</td>
</tr>
<tr>
<td>u</td><td>v</td><td>t</td><td>x</td><td>y</td><td>@</td><td>1</td><td>2</td><td>3</td><td>l</td>
</tr>
<tr>
<td>$</td><td>b</td><td>c</td><td>d</td><td>^</td><td>f</td><td>g</td><td>!</td><td>i</td><td>j</td>
</tr>
</tbody>
</table>
<script>
(function() {
"use strict";
var onlyPairs = true,
t1 = document.getElementById('table1'),
t2 = document.getElementById('table2');
var arr1 = ArrayFromTable(t1),
arr2 = ArrayFromTable(t2);
t1.addEventListener('mouseover', highlight.bind(t1, t2, arr1, arr2, true));
t2.addEventListener('mouseover', highlight.bind(t2, t1, arr2, arr1, true));
t1.addEventListener('mouseout', highlight.bind(t1, t2, arr1, arr2, false));
t2.addEventListener('mouseout', highlight.bind(t2, t1, arr2, arr1, false));
t1.addEventListener('click', select);
t2.addEventListener('click', select);
function ArrayFromTable(tbl) {
return Array.from(tbl.rows).map(function(row) {
return Array.from(row.cells).map(function(cell) {
return cell.textContent;
});
});
};
function highlight(tbl, arrA, arrB, mode, event) {
if(event.target.tagName != 'TD') {
return;
}
var r = event.target.parentNode.rowIndex,
c,
char = event.target.textContent;
for(c=0; c<arrA[r].length; c++) {
if(arrA[r][c] == char) {
this.rows[r].cells[c].classList.toggle('highlight', mode);
}
if(arrB[r][c] == char) {
tbl.rows[r].cells[c].classList.toggle('highlight', mode);
}
}
};
function select(event) {
if(event.target.tagName != 'TD') {
return;
}
var r = event.target.parentNode.rowIndex,
a = t1.rows[r].querySelectorAll('.selected'),
A = t1.rows[r].querySelectorAll('.highlight'),
b = t2.rows[r].querySelectorAll('.selected'),
B = t2.rows[r].querySelectorAll('.highlight');
function toggleClass(node) {
node.classList.toggle(this.class, this.mode);
};
function hasClass(node, className) {
return node != null && node.classList.contains(className);
};
a.forEach(toggleClass, {class: 'selected', mode: false});
b.forEach(toggleClass, {class: 'selected', mode: false});
if((!onlyPairs || A.length && B.length) && !(hasClass(a[0], 'highlight') || hasClass(b[0], 'highlight'))) {
A.forEach(toggleClass, {class: 'selected', mode: true});
B.forEach(toggleClass, {class: 'selected', mode: true});
}
};
}());
</script>
</body>
</html>