英文:
How to highlight username in html table with JavaScript(almost there)
问题
我正在使用以下的JavaScript代码来在HTML表格中突出显示一个名字。使用mark标签和背景颜色来突出显示名字。它可以突出显示名字,但会破坏表格的格式,并只显示一长串文本,其中包括正确的名字突出显示。
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
document.addEventListener("DOMContentLoaded", () => {
table = document.getElementById("myTable");
let input = "Sally Jones";
if (input !== "") {
let regExp = new RegExp(input, 'gi')
table.innerHTML = table.textContent.replace(regExp, "<mark>$&</mark>");
}
});
<!-- language: lang-html -->
<table id="myTable" class="sLeague-table">
<thead>
<tr>
<th>Pos</th>
<th>Name</th>
<th>Branch</th>
<th>Units</th>
<th>Profit</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Roger Smith</td>
<td>Ripon</td>
<td>12</td>
<td>£13,000</td>
</tr>
<tr>
<td>2</td>
<td>Charles Strange</td>
<td>Ely</td>
<td>12</td>
<td>£11,500</td>
</tr>
<tr>
<td>3</td>
<td>Sally Jones</td>
<td>Bangor</td>
<td>11</td>
<td>£10,450</td>
</tr>
<tr>
<td>4</td>
<td>Carol Smythe</td>
<td>Chichester</td>
<td>10</td>
<td>£9,849</td>
</tr>
<tr>
<td>5</td>
<td>Any Beatty</td>
<td>Exeter</td>
<td>8</td>
<td>£9,175</td>
</tr>
<tr>
<td>6</td>
<td>Jill Smithson</td>
<td>Stevenage</td>
<td>8</td>
<td>£8,964</td>
</tr>
<tr>
<td>7</td>
<td>Peter Cousins</td>
<td>Derby</td>
<td>8</td>
<td>£7,834</td>
</tr>
<tr>
<td>8</td>
<td>Andrea Peterson</td>
<td>Leicester</td>
<td>7</td>
<td>£7,320</td>
</tr>
<tr>
<td>9</td>
<td>Jon Wales</td>
<td>Rochdale</td>
<td>6</td>
<td>£5,940</td>
</tr>
<tr>
<td>10</td>
<td>James Cameron</td>
<td>Grantham</td>
<td>5</td>
<td>£5,480</td>
</tr>
</tbody>
</table>
<!-- end snippet -->
英文:
I am using the following JavaScript code to highlight one name in a html table. Using the mark tag with a background colour to highlight the name. It works to highlight the name but breaks the format of the table and just displays a long list of text along with the correct name highlighted.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
document.addEventListener("DOMContentLoaded", () => {
table = document.getElementById("myTable");
let input = "Sally Jones";
if (input !== "") {
let regExp = new RegExp(input, 'gi')
table.innerHTML = table.textContent.replace(regExp, "<mark>$&</mark>");
}
});
<!-- language: lang-html -->
<table id="myTable" class="sLeague-table">
<thead>
<tr>
<th>Pos</th>
<th>Name</th>
<th>Branch</th>
<th>Units</th>
<th>Profit</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Roger Smith</td>
<td>Ripon</td>
<td>12</td>
<td>£13,000</td>
</tr>
<tr>
<td>2</td>
<td>Charles Strange</td>
<td>Ely</td>
<td>12</td>
<td>£11,500</td>
</tr>
<tr>
<td>3</td>
<td>Sally Jones</td>
<td>Bangor</td>
<td>11</td>
<td>£10,450</td>
</tr>
<tr>
<td>4</td>
<td>Carol Smythe</td>
<td>Chichester</td>
<td>10</td>
<td>£9,849</td>
</tr>
<tr>
<td>5</td>
<td>Any Beatty</td>
<td>Exeter</td>
<td>8</td>
<td>£9,175</td>
</tr>
<tr>
<td>6</td>
<td>Jill Smithson</td>
<td>Stevenage</td>
<td>8</td>
<td>£8,964</td>
</tr>
<tr>
<td>7</td>
<td>Peter Cousins</td>
<td>Derby</td>
<td>8</td>
<td>£7,834</td>
</tr>
<tr>
<td>8</td>
<td>Andrea Peterson</td>
<td>Leicester</td>
<td>7</td>
<td>£7,320</td>
</tr>
<tr>
<td>9</td>
<td>Jon Wales</td>
<td>Rochdale</td>
<td>6</td>
<td>£5,940</td>
</tr>
<tr>
<td>10</td>
<td>James Cameron</td>
<td>Grantham</td>
<td>5</td>
<td>£5,480</td>
</tr>
</tbody>
</table>
<!-- end snippet -->
答案1
得分: 2
你正在使用innerContent
覆盖HTML内容,导致以下结果:
<table id="myTable" class="sLeague-table">
Pos
Name
Branch
Units
Profit
1
Roger Smith
Ripon
12
£13,000
2
Charles Strange
Ely
12
£11,500
3
<mark>Sally Jones</mark>
Bangor
11
£10,450
4
Carol Smythe
Chichester
10
£9,849
5
Any Beatty
Exeter
8
£9,175
6
Jill Smithson
Stevenage
8
£8,964
7
Peter Cousins
Derby
8
£7,834
8
Andrea Peterson
Leicester
7
£7,320
9
Jon Wales
Rochdale
6
£5,940
10
James Cameron
Grantham
5
£5,480
</table>
也许你需要替换innerHTML
中的文本,可以使用以下代码:
document.addEventListener("DOMContentLoaded", () => {
table = document.getElementById("myTable");
let input = "Sally Jones";
if (input !== "") {
let regExp = new RegExp(input, 'gi');
table.innerHTML = table.innerHTML.replace(regExp, "<mark>$&</mark>");
}
});
另一种方法是仅选择<td>
元素,循环遍历它们,如果内容与搜索查询匹配,然后插入<mark>
标签。
英文:
You are overriding your HTML content with the innerContent
, which produces:
<table id="myTable" class="sLeague-table">
Pos
Name
Branch
Units
Profit
1
Roger Smith
Ripon
12
£13,000
2
Charles Strange
Ely
12
£11,500
3
<mark>Sally Jones</mark>
Bangor
11
£10,450
4
Carol Smythe
Chichester
10
£9,849
5
Any Beatty
Exeter
8
£9,175
6
Jill Smithson
Stevenage
8
£8,964
7
Peter Cousins
Derby
8
£7,834
8
Andrea Peterson
Leicester
7
£7,320
9
Jon Wales
Rochdale
6
£5,940
10
James Cameron
Grantham
5
£5,480
</table>
What you might need is to replace your text inside the innerHTML
:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
document.addEventListener("DOMContentLoaded", () => {
table = document.getElementById("myTable");
let input = "Sally Jones";
if (input !== "") {
let regExp = new RegExp(input, 'gi')
table.innerHTML = table.innerHTML.replace(regExp, "<mark>$&</mark>");
}
});
<!-- language: lang-html -->
<table id="myTable" class="sLeague-table">
<thead>
<tr>
<th>Pos</th>
<th>Name</th>
<th>Branch</th>
<th>Units</th>
<th>Profit</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Roger Smith</td>
<td>Ripon</td>
<td>12</td>
<td>£13,000</td>
</tr>
<tr>
<td>2</td>
<td>Charles Strange</td>
<td>Ely</td>
<td>12</td>
<td>£11,500</td>
</tr>
<tr>
<td>3</td>
<td>Sally Jones</td>
<td>Bangor</td>
<td>11</td>
<td>£10,450</td>
</tr>
<tr>
<td>4</td>
<td>Carol Smythe</td>
<td>Chichester</td>
<td>10</td>
<td>£9,849</td>
</tr>
<tr>
<td>5</td>
<td>Any Beatty</td>
<td>Exeter</td>
<td>8</td>
<td>£9,175</td>
</tr>
<tr>
<td>6</td>
<td>Jill Smithson</td>
<td>Stevenage</td>
<td>8</td>
<td>£8,964</td>
</tr>
<tr>
<td>7</td>
<td>Peter Cousins</td>
<td>Derby</td>
<td>8</td>
<td>£7,834</td>
</tr>
<tr>
<td>8</td>
<td>Andrea Peterson</td>
<td>Leicester</td>
<td>7</td>
<td>£7,320</td>
</tr>
<tr>
<td>9</td>
<td>Jon Wales</td>
<td>Rochdale</td>
<td>6</td>
<td>£5,940</td>
</tr>
<tr>
<td>10</td>
<td>James Cameron</td>
<td>Grantham</td>
<td>5</td>
<td>£5,480</td>
</tr>
</tbody>
</table>
<!-- end snippet -->
One other approach is to only select <td>
elements loop over them and insert the <mark>
tag if their content matches your search query
答案2
得分: 2
你正在获取整个表格的_text_内容,但将其应用于表格的innerHTML,因此失去了所有格式。
- 使用
querySelectorAll
来获取一个类似数组的单元格元素列表。 - 因为在这个示例中我们将使用
find
,所以需要将这个类似数组的结构强制转换为一个真正的数组,以便可以访问其所有数组方法。在这里,我使用了[...cells]
(使用 扩展语法,但你也可以使用Array.from
。 - 使用
find
查找第一个具有与输入值匹配的文本内容的单元格。find
很有用,因为它在找到第一个匹配项时会提前结束迭代,而不会继续迭代到数组的末尾。 - 将该单元格的innerHTML更改为输入值,用
<mark>
元素包裹起来。
英文:
You're picking up the text content of the whole table but applying that to the table's innerHTML so you lose all the formatting.
- Use
querySelectorAll
to get an array-like list of cell elements. - Because we'll be using
find
in this example we need to coerce this array-like structure to a proper array so you can access all its array methods. Here I've used:[...cells]
(using the spread syntax, but you could also useArray.from
. - Use
find
to find the first cell that has the text content that matches the input value.find
is useful because the iteration short-cuts when it finds the first match rather than continue the iteration til the end of the array. - Change that cell's innerHTML to the input value wrapped in a
<mark>
element.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const cells = document.querySelectorAll('table td');
const input = 'Sally Jones';
const cell = [...cells].find(cell => {
return cell.textContent === input;
});
cell.innerHTML = `<mark>${input}</mark>`;
<!-- language: lang-html -->
<table id="myTable" class="sLeague-table">
<thead>
<tr>
<th>Pos</th>
<th>Name</th>
<th>Branch</th>
<th>Units</th>
<th>Profit</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Roger Smith</td>
<td>Ripon</td>
<td>12</td>
<td>£13,000</td>
</tr>
<tr>
<td>2</td>
<td>Charles Strange</td>
<td>Ely</td>
<td>12</td>
<td>£11,500</td>
</tr>
<tr>
<td>3</td>
<td>Sally Jones</td>
<td>Bangor</td>
<td>11</td>
<td>£10,450</td>
</tr>
<tr>
<td>4</td>
<td>Carol Smythe</td>
<td>Chichester</td>
<td>10</td>
<td>£9,849</td>
</tr>
<tr>
<td>5</td>
<td>Any Beatty</td>
<td>Exeter</td>
<td>8</td>
<td>£9,175</td>
</tr>
<tr>
<td>6</td>
<td>Jill Smithson</td>
<td>Stevenage</td>
<td>8</td>
<td>£8,964</td>
</tr>
<tr>
<td>7</td>
<td>Peter Cousins</td>
<td>Derby</td>
<td>8</td>
<td>£7,834</td>
</tr>
<tr>
<td>8</td>
<td>Andrea Peterson</td>
<td>Leicester</td>
<td>7</td>
<td>£7,320</td>
</tr>
<tr>
<td>9</td>
<td>Jon Wales</td>
<td>Rochdale</td>
<td>6</td>
<td>£5,940</td>
</tr>
<tr>
<td>10</td>
<td>James Cameron</td>
<td>Grantham</td>
<td>5</td>
<td>£5,480</td>
</tr>
</tbody>
</table>
<!-- end snippet -->
答案3
得分: 1
以下是翻译好的部分:
function highlightInfo(str) {
table = document.getElementById("myTable");
let targetData = table.querySelectorAll('td');
targetData.forEach(td => td.textContent === str ? td.classList.add('highlighted') : td.classList.remove('highlighted'))
}
highlightInfo('Sally Jones');
.highlighted {
background-color: yellow;
}
<table id="myTable" class="sLeague-table">
<thead>
<tr>
<th>Pos</th>
<th>Name</th>
<th>Branch</th>
<th>Units</th>
<th>Profit</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Roger Smith</td>
<td>Ripon</td>
<td>12</td>
<td>£13,000</td>
</tr>
<tr>
<td>2</td>
<td>Charles Strange</td>
<td>Ely</td>
<td>12</td>
<td>£11,500</td>
</tr>
<tr>
<td>3</td>
<td>Sally Jones</td>
<td>Bangor</td>
<td>11</td>
<td>£10,450</td>
</tr>
<!-- 其他行省略 -->
</tbody>
</table>
英文:
A bit of a different approach using CSS background-color to define a class, then simply locate the table data element whose textContent is equal to your string, if found add the class if not remove it.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
function highlightInfo(str) {
table = document.getElementById("myTable");
let targetData = table.querySelectorAll('td');
targetData.forEach(td => td.textContent === str ? td.classList.add('highlighted') : td.classList.remove('highlighted'))
}
highlightInfo('Sally Jones');
<!-- language: lang-css -->
.highlighted {
background-color: yellow;
}
<!-- language: lang-html -->
<table id="myTable" class="sLeague-table">
<thead>
<tr>
<th>Pos</th>
<th>Name</th>
<th>Branch</th>
<th>Units</th>
<th>Profit</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Roger Smith</td>
<td>Ripon</td>
<td>12</td>
<td>£13,000</td>
</tr>
<tr>
<td>2</td>
<td>Charles Strange</td>
<td>Ely</td>
<td>12</td>
<td>£11,500</td>
</tr>
<tr>
<td>3</td>
<td>Sally Jones</td>
<td>Bangor</td>
<td>11</td>
<td>£10,450</td>
</tr>
<tr>
<td>4</td>
<td>Carol Smythe</td>
<td>Chichester</td>
<td>10</td>
<td>£9,849</td>
</tr>
<tr>
<td>5</td>
<td>Any Beatty</td>
<td>Exeter</td>
<td>8</td>
<td>£9,175</td>
</tr>
<tr>
<td>6</td>
<td>Jill Smithson</td>
<td>Stevenage</td>
<td>8</td>
<td>£8,964</td>
</tr>
<tr>
<td>7</td>
<td>Peter Cousins</td>
<td>Derby</td>
<td>8</td>
<td>£7,834</td>
</tr>
<tr>
<td>8</td>
<td>Andrea Peterson</td>
<td>Leicester</td>
<td>7</td>
<td>£7,320</td>
</tr>
<tr>
<td>9</td>
<td>Jon Wales</td>
<td>Rochdale</td>
<td>6</td>
<td>£5,940</td>
</tr>
<tr>
<td>10</td>
<td>James Cameron</td>
<td>Grantham</td>
<td>5</td>
<td>£5,480</td>
</tr>
</tbody>
</table>
<!-- end snippet -->
答案4
得分: 1
你实际上正在做的是,确切地说,是这一行 table.innerHTML = table.textContent.replace(regExp, "<mark>$&</mark>")
,你正在替换表格本身的 HTML
标记,这显然会引起问题,正如你在问题中所述。
你的目标可以通过更简单的方式实现,我们需要获取所有名字为 "Sally Jones"
的名称,并通过仅替换具有所需文本的 td
上的 HTML
标记来突出显示它们,以便每个匹配的 td
元素的 HTML
变成类似于 <td><mark>Sally Jones</mark></td>
。
为此,我们可以通过只查看代表“名称列”的 td
并仅查找这些元素内部的文本来优化操作。然后,我们可以使用正则表达式来检查所需文本是否存在,并在匹配时应用高亮显示:
- 选择所有代表“名称”列的
td
(使用querySelectorAll
方法)。 - 遍历这些元素。
- 检查是否有匹配的文本。
- 如果有,应用高亮显示。
以下是一个快速演示:
table = document.getElementById("myTable");
const input = "Sally Jones",
regExp = new RegExp(input, 'gi');
/** 传递给 "querySelectorAll" 方法的选择器仅选择表格中表示 "名称" 的 "td" */
document.querySelectorAll('td:nth-child(2)')
/** 遍历这些 "td",如果需要(如果我们有匹配的文本),则应用高亮显示 */
.forEach(td => regExp.test(td.textContent) && (td.innerHTML = td.textContent.replace(regExp, "<mark>$&</mark>")));
<table id="myTable" class="sLeague-table">
<thead>
<tr>
<th>Pos</th>
<th>Name</th>
<th>Branch</th>
<th>Units</th>
<th>Profit</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Roger Smith</td>
<td>Ripon</td>
<td>12</td>
<td>£13,000</td>
</tr>
<!-- 其他行省略 -->
</tbody>
</table>
英文:
What you're actually doing here, this line to be exact table.innerHTML = table.textContent.replace(regExp, "<mark>$&</mark>")
, is that you're replacing the HTML
markup of the table itself which will obviously mess things up as you have stated in your question.
You goal can be achieved in an ease way, we need to grab all the names that are "Sally Jones"
and highlight them by replacing the HTML
markup only on the td
s hat do have the text needed so that each matched td
element's HTML
becomes something similar to <td><mark>Sally Jones</mark></td>
.
To do so, we could optimize things by only looking at the td
s that represent the name column
and to only look for the text inside of those elements only. Then we can use our regex to check whether the wanted text exists or not and apply the highlighting if we have a match:
- Select all the
name
columns (thetd
s that represent thename
column in our table) using thequerySelectorAll
method. - Loop through those elements
- Check if we have a matching text
- If yes, apply the highlighting
Here's a quick demo to illustrate:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
table = document.getElementById("myTable");
const input = "Sally Jones",
regExp = new RegExp(input, 'gi');
/** the selector passed to "querySelectorAll" method selects only the "td"s that represent a "name" in the table */
document.querySelectorAll('td:nth-child(2)')
/** loop through thoise "td"s and apply the highlighting if needed (if we have a matching text) */
.forEach(td => regExp.test(td.textContent) && (td.innerHTML = td.textContent.replace(regExp, "<mark>$&</mark>")));
<!-- language: lang-html -->
<table id="myTable" class="sLeague-table">
<thead>
<tr>
<th>Pos</th>
<th>Name</th>
<th>Branch</th>
<th>Units</th>
<th>Profit</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Roger Smith</td>
<td>Ripon</td>
<td>12</td>
<td>£13,000</td>
</tr>
<tr>
<td>2</td>
<td>Charles Strange</td>
<td>Ely</td>
<td>12</td>
<td>£11,500</td>
</tr>
<tr>
<td>3</td>
<td>Sally Jones</td>
<td>Bangor</td>
<td>11</td>
<td>£10,450</td>
</tr>
<tr>
<td>4</td>
<td>Carol Smythe</td>
<td>Chichester</td>
<td>10</td>
<td>£9,849</td>
</tr>
<tr>
<td>5</td>
<td>Any Beatty</td>
<td>Exeter</td>
<td>8</td>
<td>£9,175</td>
</tr>
<tr>
<td>6</td>
<td>Jill Smithson</td>
<td>Stevenage</td>
<td>8</td>
<td>£8,964</td>
</tr>
<tr>
<td>7</td>
<td>Peter Cousins</td>
<td>Derby</td>
<td>8</td>
<td>£7,834</td>
</tr>
<tr>
<td>8</td>
<td>Andrea Peterson</td>
<td>Leicester</td>
<td>7</td>
<td>£7,320</td>
</tr>
<tr>
<td>9</td>
<td>Jon Wales</td>
<td>Rochdale</td>
<td>6</td>
<td>£5,940</td>
</tr>
<tr>
<td>10</td>
<td>James Cameron</td>
<td>Grantham</td>
<td>5</td>
<td>£5,480</td>
</tr>
</tbody>
</table>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论