单词搜索游戏。如何搜索网格并突出显示结果?
Word search game. How to search the grid and highlight the result?
我是编程新手,没有使用 JavaScript 的经验,我有一项作业要为我的学校完成。我需要创建一个词搜索游戏,它有一个 form/button 搜索,可以找到一个词并在网格中突出显示它。我已经创建了 HTML/CSS 布局,但我无法将其链接到 JavaScript。我希望能够搜索词 "BANGKOK"、"LONDON"、"SINGAPORE"、"HAVANA" 和 "KYOTO",但我只能 search/highlight 一个 letter/cell 的网格,我不知道如何用网格中的字母制作一个字符串,这样我才能找到这些词。我被困在这里了。真的很想了解。有人可以帮我 me/guide/explain 它是如何工作的?我读了很多东西,但似乎找不到我要找的东西。我真的很感激。
我还需要突出显示的单词在找到时保持突出显示。
这是我目前的情况:https://jsfiddle.net/fwg8hequ/10/
function search() {
var text = document.getElementById("query").value;
var query = new RegExp("(\b" + text + "\b)", "gim");
var e = document.getElementById("searchtext").innerHTML;
var enew = e.replace(/(<span>|<\/span>)/igm, "");
document.getElementById("searchtext").innerHTML = enew;
var newe = enew.replace(query, "<span></span>");
document.getElementById("searchtext").innerHTML = newe;
}
@charset "UTF-8";
/* CSS Document */
@font-face {
font-family: 'RobotoSlab';
src: url('RobotoSlab-bold.ttf');
}
@font-face {
font-family: 'RobotoMono';
src: url('RobotoMono-Regular.ttf');
}
.container {
position: relative;
width: 1000px;
height: 800px;
background: #ffcc78;
}
.header {
position: absolute;
left: 24.7%;
right: 26%;
top: 5.25%;
bottom: 86.75%;
overflow: auto;
}
.header img {
width: 58px;
height: 58px;
left: 247px;
top: 46px;
float: left;
}
.header h1 {
left: 33.8%;
right: 28.4%;
width: 378px;
height: 64px;
font-family: RobotoSlab;
font-style: normal;
line-height: normal;
font-size: 48px;
letter-spacing: -1px;
color: #E25C5C;
line-height: 5.28%;
float: right;
}
form {
position: absolute;
left: 24.7%;
right: 26%;
top: 18.75%;
bottom: 75%;
}
input[type=text] {
float: left;
left: 24.7%;
right: 35.8%;
top: 18.75%;
bottom: 75%;
width: 410px;
height: 50px;
background: #FFFFFF;
border: 1px solid #417505;
box-sizing: border-box;
border-radius: 5px;
}
button {
position: absolute;
left: 66.5%;
right: 27.3%;
top: 18.75%;
bottom: 75%;
background: linear-gradient(180deg, #76AD0C 0%, #417505 100%);
border-radius: 5px;
font-family: RobotoSlab;
font-style: normal;
line-height: normal;
font-size: 15px;
color: #FFFFFF;
float: right;
}
.grid-container {
display: grid;
grid-template-columns: auto auto auto auto auto auto auto auto auto auto;
background-color: #E25C5C;
position: absolute;
left: 24.7%;
right: 26%;
top: 30.5%;
bottom: 7.88%;
padding: 2px;
border-radius: 5px;
}
.grid-item {
background-color: #ffcc78;
border: 2px solid #E25C5C;
left: 26.2%;
right: 27.2%;
font-family: RobotoMono;
line-height: 36px;
font-size: 36px;
letter-spacing: 2.9px;
font-style: normal;
font-weight: normal;
text-align: center;
padding: 2px;
}
#searchtext span {
background-color: #F5A623;
}
<div class="container">
<div class="header">
<img src="icon.png" alt="Icon" height="58" width="58">
<h1>WORD SEARCH</h1>
</div>
<form>
<input name="query" id="query" type="text">
</form>
<button type="button" onClick="search();">SEARCH</button>
<div class="grid-container" id="searchtext">
<div class="grid-item">W</div>
<div class="grid-item">S</div>
<div class="grid-item">I</div>
<div class="grid-item">A</div>
<div class="grid-item">L</div>
<div class="grid-item">C</div>
<div class="grid-item">E</div>
<div class="grid-item">O</div>
<div class="grid-item">I</div>
<div class="grid-item">V</div>
<div class="grid-item">V</div>
<div class="grid-item">A</div>
<div class="grid-item">L</div>
<div class="grid-item">B</div>
<div class="grid-item">A</div>
<div class="grid-item">N</div>
<div class="grid-item">G</div>
<div class="grid-item">K</div>
<div class="grid-item">O</div>
<div class="grid-item">K</div>
<div class="grid-item">U</div>
<div class="grid-item">T</div>
<div class="grid-item">L</div>
<div class="grid-item">O</div>
<div class="grid-item">N</div>
<div class="grid-item">D</div>
<div class="grid-item">O</div>
<div class="grid-item">N</div>
<div class="grid-item">O</div>
<div class="grid-item">I</div>
<div class="grid-item">U</div>
<div class="grid-item">S</div>
<div class="grid-item">I</div>
<div class="grid-item">N</div>
<div class="grid-item">G</div>
<div class="grid-item">A</div>
<div class="grid-item">P</div>
<div class="grid-item">O</div>
<div class="grid-item">R</div>
<div class="grid-item">E</div>
<div class="grid-item">A</div>
<div class="grid-item">L</div>
<div class="grid-item">C</div>
<div class="grid-item">O</div>
<div class="grid-item">G</div>
<div class="grid-item">E</div>
<div class="grid-item">E</div>
<div class="grid-item">U</div>
<div class="grid-item">V</div>
<div class="grid-item">R</div>
<div class="grid-item">H</div>
<div class="grid-item">A</div>
<div class="grid-item">V</div>
<div class="grid-item">A</div>
<div class="grid-item">N</div>
<div class="grid-item">A</div>
<div class="grid-item">T</div>
<div class="grid-item">L</div>
<div class="grid-item">A</div>
<div class="grid-item">A</div>
<div class="grid-item">A</div>
<div class="grid-item">B</div>
<div class="grid-item">I</div>
<div class="grid-item">S</div>
<div class="grid-item">S</div>
<div class="grid-item">N</div>
<div class="grid-item">O</div>
<div class="grid-item">R</div>
<div class="grid-item">I</div>
<div class="grid-item">S</div>
<div class="grid-item">N</div>
<div class="grid-item">K</div>
<div class="grid-item">Y</div>
<div class="grid-item">O</div>
<div class="grid-item">T</div>
<div class="grid-item">O</div>
<div class="grid-item">A</div>
<div class="grid-item">H</div>
<div class="grid-item">B</div>
<div class="grid-item">E</div>
<div class="grid-item">Z</div>
<div class="grid-item">M</div>
<div class="grid-item">P</div>
<div class="grid-item">T</div>
<div class="grid-item">R</div>
<div class="grid-item">E</div>
<div class="grid-item">S</div>
<div class="grid-item">J</div>
<div class="grid-item">R</div>
<div class="grid-item">L</div>
<div class="grid-item">F</div>
<div class="grid-item">P</div>
<div class="grid-item">E</div>
<div class="grid-item">K</div>
<div class="grid-item">T</div>
<div class="grid-item">A</div>
<div class="grid-item">M</div>
<div class="grid-item">L</div>
<div class="grid-item">O</div>
<div class="grid-item">J</div>
</div>
</div>
让我们尝试分解搜索功能的作用:
function search() {
// get the searched text OK
var text = document.getElementById("query").value;
// make a regexp out of the searched text OK
var query = new RegExp("(\b" + text + "\b)", "gim");
// retrieve the html content of the grid items's container OK
var e = document.getElementById("searchtext").innerHTML;
// remove all the spans tags from this html content (span tags in #searchtext are red)
var enew = e.replace(/(<span>|<\/span>)/igm, "");
// set the html stripped from the span tags as the content of #searchtext
document.getElementById("searchtext").innerHTML = enew;
// in the html stripped from span, wrap with spans all contents matching the search string
var newe = enew.replace(query, "<span></span>");
// set the final html as the content of #searchtext
document.getElementById("searchtext").innerHTML = newe;
}
因此,您首先要提取 html 代码并尝试在此 html 代码中查找文本。
但是由于您保留了大部分标签(您只删除了 span),您将无法仅在 div 的内容中找到文本(您的搜索将被 div 标签本身污染) .
我们可以用替换来做复杂的事情,但必须有另一种方法。
现在让我们分解手头的问题:
我们想写一个函数,根据这个搜索文字游戏的规则(水平,垂直对角线)在网格中突出显示搜索到的单词。
`function highlightSearchedWord() {....}`
没有内置的 javascript 函数可以做到这一点,所以我们必须拆分问题。
function highlightSearchedWord() {
var text = getSearchedWord();
highlightText(text);
}
我们可以解决getSearchedWord:
function getSearchedWord() {
var text = document.getElementById("query").value;
return text;
}
现在在 highlightText 中我们需要找到一个单词,它能够读取网格中给定位置的字母,将它们与搜索到的文本进行比较,如果找到单词则保留位置列表并突出显示这些位置.
网格中的位置可以看作是坐标 x(字母列的索引)和 y(字母行的索引)。
在javascript中,我们可以用大括号{}
定义结构化对象,例如位置0,0(网格第一行的第一个字母)将是{ x: 0, y: 0}
您的网格的第一个字母在您的网格的第一个 div (.grid-item) 中。
Javascript 为您提供了根据 class 名称检索元素的方法。
`document.getElementsByClassName()`
Documentation of getElementsByClassName
因此我们可以通过编写 var items= document.getElementsByClassName('grid-item');
列出所有网格元素
让我们定义函数 getItems
:
function getItems() {
var items= document.getElementsByClassName('grid-item');
return items;
}
由此我们很容易推导出一个新函数:
function getLetterAtPos(pos) {
var items = getItems();
// items is an array so we have to convert position {x, y} to index
return items[posToIndex(pos)].innerHTML;
}
posToIndex 为:
function posToIndex(pos) {
// if the grid is 10x10 the first element of first row is index 0 (0 * 10 + 0)
// !remember first indice is 0!
// the first item of second row is index 10 (1 * 10 + 0)
// the second item of the third row is index 21 (1 * 10 + 1)
return pos.y * 10 + pos.x;
}
我会在这里加快速度以限制答案的大小,但评论应该会有所帮助。
突出显示位置的方法也可能有帮助:
首先定义一个 css class 做高亮显示(从一个元素中添加或删除一个 class 比 wrap/unwrap 它的内容在一个跨度中更容易) :
css:
.highlight {
background-color:#F5A623;
}
然后 javascript 辅助函数
js:
function addClass(elem, className) {
// HTMLElement.className is a string with one or several class names separated by a space
var classNames = elem.className.split(" ");
// we search the array classNames with indexOf to check if the class needs to be added
if (classNames.indexOf(className) == -1) {
// the class name is not found in the existing class names of this element so we just concatenate className to t elem.className
elem.className += " " + className;
}
}
function removeClass(elem, className) {
// same as above we split elem.className into an array of classNames
var classNames = elem.className.split(" ");
// we search for index of the className we want to remove
// index === -1 means not found, otherwise the index is the position of className in classNames
var index = classNames.indexOf(className);
if (index !== -1) {
// javascript's version of remove at, splice(index, 1) means remove one item at index
classNames.splice(index, 1);
// join(' ') re concatenate classNames into a string of space separated class names
elem.className = classNames.join(' ');
}
}
function highlightPos(pos) {
var item = getItems()[posToIndex(pos)];
addClass(item, 'highlight');
}
// to reset highlights between searches
function clearHighlights() {
var items = getGridItems();
for (var i = 0; i < items.length; i++) {
removeClass(items[i], 'sel');
}
}
参考文献:
现在要阅读网格中的单词,我们必须至少找到搜索文本首字母的位置,然后尝试匹配搜索文本的每个字母:
function findLetterPositions(letter) {
// we define a new array to receive our results
var positions = [];
// there are 10 columns x 10 rows of items
var itemCount = 10 * 10;
for (let i = 0; i < itemCount; i++) {
var pos = indexToPos(i);
// we compare letters lowercased
if (getLetterAtPos(pos).toLowerCase() === letter.toLowerCase()) {
// we have found letter at pos, so we add it to our array of positions (push)
positions.push(pos);
}
}
return positions;
}
indexToPos 被定义为 posToIndex 的反向操作(取一个索引,returns 一个 pos):
function indexToPos(index) {
var y = Math.floor(index / columnCount);
var x = index - y * columnCount;
return { x: x, y: y };
}
对于每个找到的位置,我们需要尝试从该位置开始并沿指定方向匹配搜索文本的每个字母。例如右边(给定第一个字母的初始位置):
function tryAndMatchRight(text,initialPos) {
var x = initialPos.x;
var y = initialPos.y;
var columnCount = 10;
// we need to check that we are far enough from the edge of the grid for the whole word to fit, otherwise give up by returning
if (x + text.length > columnCount) {
return;
}
// word found == true by default, the for loop below will try to prove otherwise
var wholeWordFound = true;
// we will keep track of the letter positions we're trying
var wordPositions = [];
// obviously
wordPositions.push(initialPos);
// we will try each letter of text starting from the second (index 1) to the end of text (index length-1)
for (var x2 = 1; x2 < text.length; x2++) {
// building the position object for the current letter
var pos = { x: x + x2, y: y};
// if the comparaison fails we can stop
if (text[x2].toLowerCase() !== getLetterAtPos(pos).toLowerCase()) {
wholeWordFound = false;
break;
}
wordPositions.push(pos);
}
if (wholeWordFound) {
highLightPositions(wordPositions);
}
}
function hightlightPositions(positions) {
for(var i = 0; i < positions.length; i++) {
highlightPos(positions[i]);
}
}
总而言之,单击搜索按钮时调用的函数可能是:
function search() {
clearHighlights();
var text = getSearchedText();
var firstLetterPositions = findLetterPositions(text[0]);
for (var i = 0; i < firstLetterPositions.length; i++) {
var initialPos = firstLetterPositions[i];
tryAndMatchRight(text,initialPos);
// we only did it rightward, but other directions need their own functions
// tryAndMatchDown(text,initialPos);
// tryAndMatchDownRight(text,initialPos);
// tryAndMatchUpRight(text,initialPos);
}
}
Fully working solution as a fiddle here
如果你确实想了解编程,我希望你会喜欢这个答案,它展示了编程主要是如何将大问题拆分成小问题,直到问题可以通过语言本身提供的工具轻松解决(和理解) .
无论如何,这对我来说很有趣!干杯
(PS:正如 Evochrome 在下面的评论中所述,两个辅助函数 addClass 和 removeClass 已经通过普通 js 以这种方式解决 element.classList.add("mystyle")
和 element.classList.remove("mystyle")
)
我是编程新手,没有使用 JavaScript 的经验,我有一项作业要为我的学校完成。我需要创建一个词搜索游戏,它有一个 form/button 搜索,可以找到一个词并在网格中突出显示它。我已经创建了 HTML/CSS 布局,但我无法将其链接到 JavaScript。我希望能够搜索词 "BANGKOK"、"LONDON"、"SINGAPORE"、"HAVANA" 和 "KYOTO",但我只能 search/highlight 一个 letter/cell 的网格,我不知道如何用网格中的字母制作一个字符串,这样我才能找到这些词。我被困在这里了。真的很想了解。有人可以帮我 me/guide/explain 它是如何工作的?我读了很多东西,但似乎找不到我要找的东西。我真的很感激。 我还需要突出显示的单词在找到时保持突出显示。
这是我目前的情况:https://jsfiddle.net/fwg8hequ/10/
function search() {
var text = document.getElementById("query").value;
var query = new RegExp("(\b" + text + "\b)", "gim");
var e = document.getElementById("searchtext").innerHTML;
var enew = e.replace(/(<span>|<\/span>)/igm, "");
document.getElementById("searchtext").innerHTML = enew;
var newe = enew.replace(query, "<span></span>");
document.getElementById("searchtext").innerHTML = newe;
}
@charset "UTF-8";
/* CSS Document */
@font-face {
font-family: 'RobotoSlab';
src: url('RobotoSlab-bold.ttf');
}
@font-face {
font-family: 'RobotoMono';
src: url('RobotoMono-Regular.ttf');
}
.container {
position: relative;
width: 1000px;
height: 800px;
background: #ffcc78;
}
.header {
position: absolute;
left: 24.7%;
right: 26%;
top: 5.25%;
bottom: 86.75%;
overflow: auto;
}
.header img {
width: 58px;
height: 58px;
left: 247px;
top: 46px;
float: left;
}
.header h1 {
left: 33.8%;
right: 28.4%;
width: 378px;
height: 64px;
font-family: RobotoSlab;
font-style: normal;
line-height: normal;
font-size: 48px;
letter-spacing: -1px;
color: #E25C5C;
line-height: 5.28%;
float: right;
}
form {
position: absolute;
left: 24.7%;
right: 26%;
top: 18.75%;
bottom: 75%;
}
input[type=text] {
float: left;
left: 24.7%;
right: 35.8%;
top: 18.75%;
bottom: 75%;
width: 410px;
height: 50px;
background: #FFFFFF;
border: 1px solid #417505;
box-sizing: border-box;
border-radius: 5px;
}
button {
position: absolute;
left: 66.5%;
right: 27.3%;
top: 18.75%;
bottom: 75%;
background: linear-gradient(180deg, #76AD0C 0%, #417505 100%);
border-radius: 5px;
font-family: RobotoSlab;
font-style: normal;
line-height: normal;
font-size: 15px;
color: #FFFFFF;
float: right;
}
.grid-container {
display: grid;
grid-template-columns: auto auto auto auto auto auto auto auto auto auto;
background-color: #E25C5C;
position: absolute;
left: 24.7%;
right: 26%;
top: 30.5%;
bottom: 7.88%;
padding: 2px;
border-radius: 5px;
}
.grid-item {
background-color: #ffcc78;
border: 2px solid #E25C5C;
left: 26.2%;
right: 27.2%;
font-family: RobotoMono;
line-height: 36px;
font-size: 36px;
letter-spacing: 2.9px;
font-style: normal;
font-weight: normal;
text-align: center;
padding: 2px;
}
#searchtext span {
background-color: #F5A623;
}
<div class="container">
<div class="header">
<img src="icon.png" alt="Icon" height="58" width="58">
<h1>WORD SEARCH</h1>
</div>
<form>
<input name="query" id="query" type="text">
</form>
<button type="button" onClick="search();">SEARCH</button>
<div class="grid-container" id="searchtext">
<div class="grid-item">W</div>
<div class="grid-item">S</div>
<div class="grid-item">I</div>
<div class="grid-item">A</div>
<div class="grid-item">L</div>
<div class="grid-item">C</div>
<div class="grid-item">E</div>
<div class="grid-item">O</div>
<div class="grid-item">I</div>
<div class="grid-item">V</div>
<div class="grid-item">V</div>
<div class="grid-item">A</div>
<div class="grid-item">L</div>
<div class="grid-item">B</div>
<div class="grid-item">A</div>
<div class="grid-item">N</div>
<div class="grid-item">G</div>
<div class="grid-item">K</div>
<div class="grid-item">O</div>
<div class="grid-item">K</div>
<div class="grid-item">U</div>
<div class="grid-item">T</div>
<div class="grid-item">L</div>
<div class="grid-item">O</div>
<div class="grid-item">N</div>
<div class="grid-item">D</div>
<div class="grid-item">O</div>
<div class="grid-item">N</div>
<div class="grid-item">O</div>
<div class="grid-item">I</div>
<div class="grid-item">U</div>
<div class="grid-item">S</div>
<div class="grid-item">I</div>
<div class="grid-item">N</div>
<div class="grid-item">G</div>
<div class="grid-item">A</div>
<div class="grid-item">P</div>
<div class="grid-item">O</div>
<div class="grid-item">R</div>
<div class="grid-item">E</div>
<div class="grid-item">A</div>
<div class="grid-item">L</div>
<div class="grid-item">C</div>
<div class="grid-item">O</div>
<div class="grid-item">G</div>
<div class="grid-item">E</div>
<div class="grid-item">E</div>
<div class="grid-item">U</div>
<div class="grid-item">V</div>
<div class="grid-item">R</div>
<div class="grid-item">H</div>
<div class="grid-item">A</div>
<div class="grid-item">V</div>
<div class="grid-item">A</div>
<div class="grid-item">N</div>
<div class="grid-item">A</div>
<div class="grid-item">T</div>
<div class="grid-item">L</div>
<div class="grid-item">A</div>
<div class="grid-item">A</div>
<div class="grid-item">A</div>
<div class="grid-item">B</div>
<div class="grid-item">I</div>
<div class="grid-item">S</div>
<div class="grid-item">S</div>
<div class="grid-item">N</div>
<div class="grid-item">O</div>
<div class="grid-item">R</div>
<div class="grid-item">I</div>
<div class="grid-item">S</div>
<div class="grid-item">N</div>
<div class="grid-item">K</div>
<div class="grid-item">Y</div>
<div class="grid-item">O</div>
<div class="grid-item">T</div>
<div class="grid-item">O</div>
<div class="grid-item">A</div>
<div class="grid-item">H</div>
<div class="grid-item">B</div>
<div class="grid-item">E</div>
<div class="grid-item">Z</div>
<div class="grid-item">M</div>
<div class="grid-item">P</div>
<div class="grid-item">T</div>
<div class="grid-item">R</div>
<div class="grid-item">E</div>
<div class="grid-item">S</div>
<div class="grid-item">J</div>
<div class="grid-item">R</div>
<div class="grid-item">L</div>
<div class="grid-item">F</div>
<div class="grid-item">P</div>
<div class="grid-item">E</div>
<div class="grid-item">K</div>
<div class="grid-item">T</div>
<div class="grid-item">A</div>
<div class="grid-item">M</div>
<div class="grid-item">L</div>
<div class="grid-item">O</div>
<div class="grid-item">J</div>
</div>
</div>
让我们尝试分解搜索功能的作用:
function search() {
// get the searched text OK
var text = document.getElementById("query").value;
// make a regexp out of the searched text OK
var query = new RegExp("(\b" + text + "\b)", "gim");
// retrieve the html content of the grid items's container OK
var e = document.getElementById("searchtext").innerHTML;
// remove all the spans tags from this html content (span tags in #searchtext are red)
var enew = e.replace(/(<span>|<\/span>)/igm, "");
// set the html stripped from the span tags as the content of #searchtext
document.getElementById("searchtext").innerHTML = enew;
// in the html stripped from span, wrap with spans all contents matching the search string
var newe = enew.replace(query, "<span></span>");
// set the final html as the content of #searchtext
document.getElementById("searchtext").innerHTML = newe;
}
因此,您首先要提取 html 代码并尝试在此 html 代码中查找文本。 但是由于您保留了大部分标签(您只删除了 span),您将无法仅在 div 的内容中找到文本(您的搜索将被 div 标签本身污染) .
我们可以用替换来做复杂的事情,但必须有另一种方法。
现在让我们分解手头的问题: 我们想写一个函数,根据这个搜索文字游戏的规则(水平,垂直对角线)在网格中突出显示搜索到的单词。
`function highlightSearchedWord() {....}`
没有内置的 javascript 函数可以做到这一点,所以我们必须拆分问题。
function highlightSearchedWord() {
var text = getSearchedWord();
highlightText(text);
}
我们可以解决getSearchedWord:
function getSearchedWord() {
var text = document.getElementById("query").value;
return text;
}
现在在 highlightText 中我们需要找到一个单词,它能够读取网格中给定位置的字母,将它们与搜索到的文本进行比较,如果找到单词则保留位置列表并突出显示这些位置.
网格中的位置可以看作是坐标 x(字母列的索引)和 y(字母行的索引)。
在javascript中,我们可以用大括号{}
定义结构化对象,例如位置0,0(网格第一行的第一个字母)将是{ x: 0, y: 0}
您的网格的第一个字母在您的网格的第一个 div (.grid-item) 中。 Javascript 为您提供了根据 class 名称检索元素的方法。
`document.getElementsByClassName()`
Documentation of getElementsByClassName
因此我们可以通过编写 var items= document.getElementsByClassName('grid-item');
让我们定义函数 getItems
:
function getItems() {
var items= document.getElementsByClassName('grid-item');
return items;
}
由此我们很容易推导出一个新函数:
function getLetterAtPos(pos) {
var items = getItems();
// items is an array so we have to convert position {x, y} to index
return items[posToIndex(pos)].innerHTML;
}
posToIndex 为:
function posToIndex(pos) {
// if the grid is 10x10 the first element of first row is index 0 (0 * 10 + 0)
// !remember first indice is 0!
// the first item of second row is index 10 (1 * 10 + 0)
// the second item of the third row is index 21 (1 * 10 + 1)
return pos.y * 10 + pos.x;
}
我会在这里加快速度以限制答案的大小,但评论应该会有所帮助。
突出显示位置的方法也可能有帮助:
首先定义一个 css class 做高亮显示(从一个元素中添加或删除一个 class 比 wrap/unwrap 它的内容在一个跨度中更容易) :
css:
.highlight {
background-color:#F5A623;
}
然后 javascript 辅助函数
js:
function addClass(elem, className) {
// HTMLElement.className is a string with one or several class names separated by a space
var classNames = elem.className.split(" ");
// we search the array classNames with indexOf to check if the class needs to be added
if (classNames.indexOf(className) == -1) {
// the class name is not found in the existing class names of this element so we just concatenate className to t elem.className
elem.className += " " + className;
}
}
function removeClass(elem, className) {
// same as above we split elem.className into an array of classNames
var classNames = elem.className.split(" ");
// we search for index of the className we want to remove
// index === -1 means not found, otherwise the index is the position of className in classNames
var index = classNames.indexOf(className);
if (index !== -1) {
// javascript's version of remove at, splice(index, 1) means remove one item at index
classNames.splice(index, 1);
// join(' ') re concatenate classNames into a string of space separated class names
elem.className = classNames.join(' ');
}
}
function highlightPos(pos) {
var item = getItems()[posToIndex(pos)];
addClass(item, 'highlight');
}
// to reset highlights between searches
function clearHighlights() {
var items = getGridItems();
for (var i = 0; i < items.length; i++) {
removeClass(items[i], 'sel');
}
}
参考文献:
现在要阅读网格中的单词,我们必须至少找到搜索文本首字母的位置,然后尝试匹配搜索文本的每个字母:
function findLetterPositions(letter) {
// we define a new array to receive our results
var positions = [];
// there are 10 columns x 10 rows of items
var itemCount = 10 * 10;
for (let i = 0; i < itemCount; i++) {
var pos = indexToPos(i);
// we compare letters lowercased
if (getLetterAtPos(pos).toLowerCase() === letter.toLowerCase()) {
// we have found letter at pos, so we add it to our array of positions (push)
positions.push(pos);
}
}
return positions;
}
indexToPos 被定义为 posToIndex 的反向操作(取一个索引,returns 一个 pos):
function indexToPos(index) {
var y = Math.floor(index / columnCount);
var x = index - y * columnCount;
return { x: x, y: y };
}
对于每个找到的位置,我们需要尝试从该位置开始并沿指定方向匹配搜索文本的每个字母。例如右边(给定第一个字母的初始位置):
function tryAndMatchRight(text,initialPos) {
var x = initialPos.x;
var y = initialPos.y;
var columnCount = 10;
// we need to check that we are far enough from the edge of the grid for the whole word to fit, otherwise give up by returning
if (x + text.length > columnCount) {
return;
}
// word found == true by default, the for loop below will try to prove otherwise
var wholeWordFound = true;
// we will keep track of the letter positions we're trying
var wordPositions = [];
// obviously
wordPositions.push(initialPos);
// we will try each letter of text starting from the second (index 1) to the end of text (index length-1)
for (var x2 = 1; x2 < text.length; x2++) {
// building the position object for the current letter
var pos = { x: x + x2, y: y};
// if the comparaison fails we can stop
if (text[x2].toLowerCase() !== getLetterAtPos(pos).toLowerCase()) {
wholeWordFound = false;
break;
}
wordPositions.push(pos);
}
if (wholeWordFound) {
highLightPositions(wordPositions);
}
}
function hightlightPositions(positions) {
for(var i = 0; i < positions.length; i++) {
highlightPos(positions[i]);
}
}
总而言之,单击搜索按钮时调用的函数可能是:
function search() {
clearHighlights();
var text = getSearchedText();
var firstLetterPositions = findLetterPositions(text[0]);
for (var i = 0; i < firstLetterPositions.length; i++) {
var initialPos = firstLetterPositions[i];
tryAndMatchRight(text,initialPos);
// we only did it rightward, but other directions need their own functions
// tryAndMatchDown(text,initialPos);
// tryAndMatchDownRight(text,initialPos);
// tryAndMatchUpRight(text,initialPos);
}
}
Fully working solution as a fiddle here
如果你确实想了解编程,我希望你会喜欢这个答案,它展示了编程主要是如何将大问题拆分成小问题,直到问题可以通过语言本身提供的工具轻松解决(和理解) .
无论如何,这对我来说很有趣!干杯
(PS:正如 Evochrome 在下面的评论中所述,两个辅助函数 addClass 和 removeClass 已经通过普通 js 以这种方式解决 element.classList.add("mystyle")
和 element.classList.remove("mystyle")
)