我有一个带有节标题和单个项目的手风琴。我将链接到元素ID以滚动到相关部分,但想使用搜索框搜索“第1部分”等。
var acc = document.getElementByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.maxHeight){
panel.style.maxHeight = null;
} else {
panel.style.maxHeight = panel.scrollHeight + "px";
}
});
}
function myFunction() {
var input, filter, ul, li, a, i, txtValue;
input = document.getElementById("DefinitionSearch");
filter = input.value.toUpperCase();
ul = document.getElementByClassName("button");
li = ul.getElementsByTagName("button");
for (i = 0; i < li.length; i++) {
a = li[i].getElementsByTagName("a")[0];
txtValue = a.textContent || a.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "";
} else {
li[i].style.display = "none";
}
}
}
.accordion {
background-color: #1AD879;
color: #FFFFFF;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 1.6s;
}
.active, .accordion:hover {
background-color: #45F99F;
}
.panel {
padding: 0 18px;
background-color: #FFFFFF;
max-height: 0;
overflow: hidden;
transition: max-height 0.8s ease-out;
}
<!-- -->
<h1>Search the definitions</h1>
<input type="text" id="DefinitionSearch" onkeyup="myFunction()" placeholder="Search for a definition" title="Type in a name">
<h1>Section Header</h1>
<br>
<hr>
<button class="accordion">Subject 1</button>
<div class="panel">
<br>
<p class="accordiontext">Subject definition</p>
<br>
</div>
<button class="accordion">Subject 2</button>
<div class="panel">
<br>
<p class="accordiontext">Subject definition</p>
<br>
</div>
<button class="accordion">Subject 3</button>
<div class="panel">
<br>
<p class="accordiontext">Subject definition</p>
<br>
</div>
<button class="accordion">Subject 4</button>
<div class="panel">
<br>
<p class="accordiontext">Subject definition</p>
<br>
</div>
<hr>
因此,如果您在搜索框中键入“ Section 1”,它将滚动到页面上的该位置,可能会打开它。如果没有相对简单的解决方案,我只会建议用户使用ctl/cmd+f
,但这是一个不太优雅的解决方案,即使它可以满足我的要求。然后,我将仅链接到每个部分的标题ID。
答案 0 :(得分:1)
好吧,在过去的几天里,我们来回走动,我想我已经开始了解您的需求了。我已将搜索onkeydown更改为仅在按Enter时才搜索。您也可以根据需要添加搜索按钮。
我尽可能地编写了代码,但事实证明突出显示页面上的文本并不容易。因此,我找到了一个简单的JS库,可以帮助您完成繁重的工作。如果您需要更多详细信息,我将信息保留在代码中。以下是所有内容的有效代码段。看看我是否有任何遗漏。
//Hilitor Settings
var highlightIndex = new Hilitor("highlightIndex");
highlightIndex.setMatchType("left");
//Globals
var input = document.getElementById("DefinitionSearch");
var acc = document.getElementsByClassName("accordion");
//Open Subject Accordion
[].forEach.call(acc, function(item, index, a) {
item.addEventListener("click", function() {
var panel = this.nextElementSibling;
this.classList.toggle("active");
if (panel.style.maxHeight) {
panel.style.maxHeight = null;
} else {
panel.style.maxHeight = panel.scrollHeight + "px";
}
});
});
//Search Accordings; Highlight & Open Matching Areas
input.addEventListener("keyup", function(event) {
if (event.which === 13 || event.keyCode === 13) {
var input, filter, i, acc, panels, txtValue, searchText, searchTitle;
input = document.getElementById("DefinitionSearch");
filter = input.value.toUpperCase();
acc = document.getElementsByClassName("accordion");
panels = document.getElementsByClassName("panel");
for (i = 0; i < panels.length; i++) {
for (i = 0; i < acc.length; i++) {
searchText = panels[i].textContent || panels[i].innerText;
searchTitle = acc[i].textContent || acc[i].innerText;
if (input.value !== "") {
if (searchText.toUpperCase().indexOf(filter) > -1 || searchTitle.toUpperCase().indexOf(filter) > -1) {
if (!acc[i].classList.contains("active")) {
acc[i].classList.add("active");
}
highlightIndex.apply(filter);
panels[i].style.maxHeight = panels[i].scrollHeight + "px";
panels[i].scrollIntoView({
behavior: 'smooth'
});
} else {
if (acc[i].classList.contains("active")) {
acc[i].classList.remove("active");
}
panels[i].style.maxHeight = null;
}
} else {
highlightIndex.remove();
if (acc[i].classList.contains("active")) {
acc[i].classList.remove("active");
}
panels[i].style.maxHeight = null;
}
}
}
}
});
//Clear button
function clearBtn() {
var input, i, acc, panels;
input = document.getElementById("DefinitionSearch");
acc = document.getElementsByClassName("accordion");
panels = document.getElementsByClassName("panel");
input.value = "";
highlightIndex.remove();
for (i = 0; i < panels.length; i++) {
for (i = 0; i < acc.length; i++) {
if (acc[i].classList.contains("active")) {
acc[i].classList.remove("active");
}
panels[i].style.maxHeight = null;
}
}
}
// Highlight Script "hilitor.js" Found at: https://www.the-art-of-web.com/javascript/search-highlight/
// Original JavaScript code by Chirp Internet: www.chirp.com.au
// Please acknowledge use of this code by including this header.
function Hilitor(id, tag) {
// private variables
var targetNode = document.getElementById(id) || document.body;
var hiliteTag = tag || "MARK";
var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM|SPAN)$");
//var colors = ["#ff6", "#a0ffff", "#9f9", "#f99", "#f6f"];
var colors = ["#ff6"];
var wordColor = [];
var colorIdx = 0;
var matchRegExp = "";
var openLeft = false;
var openRight = false;
// characters to strip from start and end of the input string
var endRegExp = new RegExp('^[^\\w]+|[^\\w]+$', "g");
// characters used to break up the input string into words
var breakRegExp = new RegExp('[^\\w\'-]+', "g");
this.setEndRegExp = function(regex) {
endRegExp = regex;
return endRegExp;
};
this.setBreakRegExp = function(regex) {
breakRegExp = regex;
return breakRegExp;
};
this.setMatchType = function(type) {
switch (type) {
case "left":
this.openLeft = false;
this.openRight = true;
break;
case "right":
this.openLeft = true;
this.openRight = false;
break;
case "open":
this.openLeft = this.openRight = true;
break;
default:
this.openLeft = this.openRight = false;
}
};
this.setRegex = function(input) {
input = input.replace(endRegExp, "");
//The next two deal with the search, If you want to seach somthing like subject 1 and not see all words with subject highlighted then keep the settings as is. If you want to see them all highlighted then uncomment ...(breakRegExp, "|") and comment out the current setting ...(breakRegExp, " ")
//input = input.replace(breakRegExp, "|");
input = input.replace(breakRegExp, " ");
input = input.replace(/^\||\|$/g, "");
if (input) {
var re = "(" + input + ")";
if (!this.openLeft) re = "\\b" + re;
if (!this.openRight) re = re + "\\b";
matchRegExp = new RegExp(re, "i");
return matchRegExp;
}
return false;
};
this.getRegex = function() {
var retval = matchRegExp.toString();
retval = retval.replace(/(^\/(\\b)?|\(|\)|(\\b)?\/i$)/g, "");
retval = retval.replace(/\|/g, " ");
return retval;
};
// recursively apply word highlighting
this.hiliteWords = function(node) {
if (node === undefined || !node) return;
if (!matchRegExp) return;
if (skipTags.test(node.nodeName)) return;
if (node.hasChildNodes()) {
for (var i = 0; i < node.childNodes.length; i++)
this.hiliteWords(node.childNodes[i]);
}
if (node.nodeType == 3) { // NODE_TEXT
if ((nv = node.nodeValue) && (regs = matchRegExp.exec(nv))) {
if (!wordColor[regs[0].toLowerCase()]) {
wordColor[regs[0].toLowerCase()] = colors[colorIdx++ % colors.length];
}
var match = document.createElement(hiliteTag);
match.appendChild(document.createTextNode(regs[0]));
match.style.backgroundColor = wordColor[regs[0].toLowerCase()];
match.style.color = "#000";
var after = node.splitText(regs.index);
after.nodeValue = after.nodeValue.substring(regs[0].length);
node.parentNode.insertBefore(match, after);
}
};
};
// remove highlighting
this.remove = function() {
var arr = document.getElementsByTagName(hiliteTag);
while (arr.length && (el = arr[0])) {
var parent = el.parentNode;
parent.replaceChild(el.firstChild, el);
parent.normalize();
}
};
// start highlighting at target node
this.apply = function(input) {
this.remove();
if (input === undefined || !input) return;
if (this.setRegex(input)) {
this.hiliteWords(targetNode);
}
return matchRegExp;
};
}
.accordion {
background-color: #1AD879;
color: #FFFFFF;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 1.6s;
}
.active,
.accordion:hover {
background-color: #45F99F;
}
.panel {
padding: 0 18px;
background-color: #FFFFFF;
max-height: 0;
overflow: hidden;
transition: max-height 0.8s ease-out;
}
<h1>Search the definitions</h1>
<input type="text" id="DefinitionSearch" placeholder="Search for a definition" title="Type in a name">
<button type="button" id="clearHighlight" onclick="clearBtn();">Clear</button>
<h1>Section Header</h1>
<br>
<div id="highlightIndex">
<hr>
<button class="accordion">Subject 1</button>
<div class="panel">
<br>
<p class="accordiontext">hello</p>
<br>
</div>
<button class="accordion">Subject 2</button>
<div class="panel">
<br>
<p class="accordiontext">world</p>
<br>
</div>
<button class="accordion">Subject 3</button>
<div class="panel">
<br>
<p class="accordiontext">definition.</p>
<br>
</div>
<button class="accordion">Subject 4</button>
<div class="panel">
<br>
<p class="accordiontext">definition with more text.</p>
<br>
</div>
<button class="accordion">Subject 5</button>
<div class="panel">
<br>
<p class="accordiontext">make the page longer</p>
<br>
</div>
<button class="accordion">Subject 6</button>
<div class="panel">
<br>
<p class="accordiontext">to see the scroll effect</p>
<br>
</div>
<button class="accordion">Subject 7</button>
<div class="panel">
<br>
<p class="accordiontext">stackoverflow</p>
<br>
</div>
<button class="accordion">Subject 8</button>
<div class="panel">
<br>
<p class="accordiontext">many subjects</p>
<br>
</div>
<button class="accordion">Subject 9</button>
<div class="panel">
<br>
<p class="accordiontext">this is the end.</p>
<br>
</div>
<hr>
</div>
答案 1 :(得分:0)
我改进了里克·西布利(Rick Sibley)编写的代码。
先前的代码有一个错误。我在正确搜索后的不正确搜索中添加了突出显示删除功能。搜索现有单词时,文本以黄色突出显示。如果您使用不存在的单词hilight进行以下搜索,则将删除。在以前的代码中,此功能不起作用。
//Hilitor Settings
var highlightIndex = new Hilitor("highlightIndex");
highlightIndex.setMatchType("left");
//Globals
var input = document.getElementById("DefinitionSearch");
var acc = document.getElementsByClassName("accordion");
//Open Subject Accordion
[].forEach.call(acc, function(item, index, a) {
item.addEventListener("click", function() {
var panel = this.nextElementSibling;
this.classList.toggle("active");
if (panel.style.maxHeight) {
panel.style.maxHeight = null;
} else {
panel.style.maxHeight = panel.scrollHeight + "px";
}
});
});
//Search Accordings; Highlight & Open Matching Areas
input.addEventListener("keyup", function(event) {
if (event.which === 13 || event.keyCode === 13) {
var input, filter, i, acc, panels, txtValue, searchText, searchTitle;
input = document.getElementById("DefinitionSearch");
filter = input.value.toUpperCase();
acc = document.getElementsByClassName("accordion");
panels = document.getElementsByClassName("panel");
for (i = 0; i < panels.length; i++) {
for (i = 0; i < acc.length; i++) {
searchText = panels[i].textContent || panels[i].innerText;
searchTitle = acc[i].textContent || acc[i].innerText;
if (input.value !== "") {
if (searchText.toUpperCase().indexOf(filter) > -1 || searchTitle.toUpperCase().indexOf(filter) > -1) {
if (!acc[i].classList.contains("active")) {
acc[i].classList.add("active");
}
highlightIndex.apply(filter);
panels[i].style.maxHeight = panels[i].scrollHeight + "px";
panels[i].scrollIntoView({
behavior: 'smooth'
});
} else {
if (acc[i].classList.contains("active")) {
acc[i].classList.remove("active");
highlightIndex.remove();
}
panels[i].style.maxHeight = null;
}
} else {
highlightIndex.remove();
if (acc[i].classList.contains("active")) {
acc[i].classList.remove("active");
}
panels[i].style.maxHeight = null;
}
}
}
}
});
//Clear button
function clearBtn() {
var input, i, acc, panels;
input = document.getElementById("DefinitionSearch");
acc = document.getElementsByClassName("accordion");
panels = document.getElementsByClassName("panel");
input.value = "";
highlightIndex.remove();
for (i = 0; i < panels.length; i++) {
for (i = 0; i < acc.length; i++) {
if (acc[i].classList.contains("active")) {
acc[i].classList.remove("active");
}
panels[i].style.maxHeight = null;
}
}
}
// Highlight Script "hilitor.js" Found at: https://www.the-art-of-web.com/javascript/search-highlight/
// Original JavaScript code by Chirp Internet: www.chirp.com.au
// Please acknowledge use of this code by including this header.
function Hilitor(id, tag) {
// private variables
var targetNode = document.getElementById(id) || document.body;
var hiliteTag = tag || "MARK";
var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM|SPAN)$");
//var colors = ["#ff6", "#a0ffff", "#9f9", "#f99", "#f6f"];
var colors = ["#ff6"];
var wordColor = [];
var colorIdx = 0;
var matchRegExp = "";
var openLeft = false;
var openRight = false;
// characters to strip from start and end of the input string
var endRegExp = new RegExp('^[^\\w]+|[^\\w]+$', "g");
// characters used to break up the input string into words
var breakRegExp = new RegExp('[^\\w\'-]+', "g");
this.setEndRegExp = function(regex) {
endRegExp = regex;
return endRegExp;
};
this.setBreakRegExp = function(regex) {
breakRegExp = regex;
return breakRegExp;
};
this.setMatchType = function(type) {
switch (type) {
case "left":
this.openLeft = false;
this.openRight = true;
break;
case "right":
this.openLeft = true;
this.openRight = false;
break;
case "open":
this.openLeft = this.openRight = true;
break;
default:
this.openLeft = this.openRight = false;
}
};
this.setRegex = function(input) {
input = input.replace(endRegExp, "");
//The next two deal with the search, If you want to seach somthing like subject 1 and not see all words with subject highlighted then keep the settings as is. If you want to see them all highlighted then uncomment ...(breakRegExp, "|") and comment out the current setting ...(breakRegExp, " ")
//input = input.replace(breakRegExp, "|");
input = input.replace(breakRegExp, " ");
input = input.replace(/^\||\|$/g, "");
if (input) {
var re = "(" + input + ")";
if (!this.openLeft) re = "\\b" + re;
if (!this.openRight) re = re + "\\b";
matchRegExp = new RegExp(re, "i");
return matchRegExp;
}
return false;
};
this.getRegex = function() {
var retval = matchRegExp.toString();
retval = retval.replace(/(^\/(\\b)?|\(|\)|(\\b)?\/i$)/g, "");
retval = retval.replace(/\|/g, " ");
return retval;
};
// recursively apply word highlighting
this.hiliteWords = function(node) {
if (node === undefined || !node) return;
if (!matchRegExp) return;
if (skipTags.test(node.nodeName)) return;
if (node.hasChildNodes()) {
for (var i = 0; i < node.childNodes.length; i++)
this.hiliteWords(node.childNodes[i]);
}
if (node.nodeType == 3) { // NODE_TEXT
if ((nv = node.nodeValue) && (regs = matchRegExp.exec(nv))) {
if (!wordColor[regs[0].toLowerCase()]) {
wordColor[regs[0].toLowerCase()] = colors[colorIdx++ % colors.length];
}
var match = document.createElement(hiliteTag);
match.appendChild(document.createTextNode(regs[0]));
match.style.backgroundColor = wordColor[regs[0].toLowerCase()];
match.style.color = "#000";
var after = node.splitText(regs.index);
after.nodeValue = after.nodeValue.substring(regs[0].length);
node.parentNode.insertBefore(match, after);
}
};
};
// remove highlighting
this.remove = function() {
var arr = document.getElementsByTagName(hiliteTag);
while (arr.length && (el = arr[0])) {
var parent = el.parentNode;
parent.replaceChild(el.firstChild, el);
parent.normalize();
}
};
// start highlighting at target node
this.apply = function(input) {
this.remove();
if (input === undefined || !input) return;
if (this.setRegex(input)) {
this.hiliteWords(targetNode);
}
return matchRegExp;
};
}
.accordion {
background-color: #1AD879;
color: #FFFFFF;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 1.6s;
}
.active,
.accordion:hover {
background-color: #45F99F;
}
.panel {
padding: 0 18px;
background-color: #FFFFFF;
max-height: 0;
overflow: hidden;
transition: max-height 0.8s ease-out;
}
<h1>Search the definitions</h1>
<input type="text" id="DefinitionSearch" placeholder="Search for a definition" title="Type in a name">
<button type="button" id="clearHighlight" onclick="clearBtn();">Clear</button>
<h1>Section Header</h1>
<br>
<div id="highlightIndex">
<hr>
<button class="accordion">Subject 1</button>
<div class="panel">
<br>
<p class="accordiontext">hello</p>
<br>
</div>
<button class="accordion">Subject 2</button>
<div class="panel">
<br>
<p class="accordiontext">world</p>
<br>
</div>
<button class="accordion">Subject 3</button>
<div class="panel">
<br>
<p class="accordiontext">definition.</p>
<br>
</div>
<button class="accordion">Subject 4</button>
<div class="panel">
<br>
<p class="accordiontext">definition with more text.</p>
<br>
</div>
<button class="accordion">Subject 5</button>
<div class="panel">
<br>
<p class="accordiontext">make the page longer</p>
<br>
</div>
<button class="accordion">Subject 6</button>
<div class="panel">
<br>
<p class="accordiontext">to see the scroll effect</p>
<br>
</div>
<button class="accordion">Subject 7</button>
<div class="panel">
<br>
<p class="accordiontext">stackoverflow</p>
<br>
</div>
<button class="accordion">Subject 8</button>
<div class="panel">
<br>
<p class="accordiontext">many subjects</p>
<br>
</div>
<button class="accordion">Subject 9</button>
<div class="panel">
<br>
<p class="accordiontext">this is the end.</p>
<br>
</div>
<hr>
</div>