<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div class="main-wrap">
<div class="container">
<div id="nav">
<input type="text" id="one" placeholder="请输入关键字">
<div id="btn">搜索</div>
</div>
<div id="show" class="search-result" style="display: none">
<div></div>
</div>
</div>
<div class="info">
<div id="wrap" class="left-wrap"></div>
<div class="right-wrap" id="ansWrap"></div>
</div>
<!-- 层级展示区域 -->
<div class="levelBox">
<!-- 第一层 -->
<div class="levelOne level-item"></div>
<div class="levelTwo level-item">
</div>
</div>
</div>
<script>
let data = [
{
id: 1,
name: '光明学院',
children: [
{
id: 3,
name: '初级1',
children: [
{
id: 7,
name: '玛丽',
ans: '点击页面右上角“选择文书1列表”按钮后出现弹窗1,点击弹窗中“新建”字样即可创建新模板。',
},
{
id: 8,
name: '鲍勃',
ans: '点击页面右上角“选择文书2列表”按钮后出现弹窗2,选中列表中的文书3后点击右下方确认即可编辑1。',
},
{
id: 14,
name: '明米',
ans: '爱吃苹果',
},
{
id: 15,
name: '艾米',
ans: '爱学英语',
},
{
id: 16,
name: 'lily小说',
ans: '喜欢看英文小说',
},
],
},
{
id: 4,
name: '高级1',
children: [
{
id: 9,
name: '杰克点击',
ans: '点击页面右上角“导入1”按钮后选择想要导入2的文件即可导入(注:导入的文件名必须为“AIMS_DOC”,格式必须为zip)。',
},
{
id: 10,
name: '琼',
ans: '点击页面右上角“导出”按钮后即可导出1。',
},
{
id: 11,
name: '约翰',
ans: '点击页面右上角“提交”按钮后即可保存提交2。',
},
],
},
],
},
{
id: 2,
name: '魔法学院',
children: [
{
id: 5,
name: '初级2',
children: [
{
id: 12,
name: '迈克文书',
ans: '新建模板后首先需要在页面的右侧属性栏中设置文书的尺寸(关于尺寸:下拉的尺寸选项均为像素尺寸而非物理尺寸)。',
},
{
id: 13,
name: '史密斯控件',
ans: '如果要新增或修改模板控件,可点击页面右上角的“配置控件”按钮后进行操作。',
},
],
},
],
},
];
console.log('data', data);
// 左侧导航栏
let wrap = document.getElementById('wrap');
// 右侧内容
let ansWrap = document.getElementById('ansWrap');
data.forEach((el, idx0) => {
//遍历每一个大项
console.log('data', el);
let ul = document.createElement('ul'); //二层以下层级
let ansItem = document.createElement('div'); //第一层大标题
ansItem.classList = 'ansItem';
if (el.children) {
//每一个大项下有ul和div
el.children.forEach((child, idx1) => {
//大项遍历每个中项
let div = document.createElement('div');
div.classList = 'threeBox';
let ansCon = document.createElement('div');
ansCon.classList = 'ansCon';
console.log('child', child);
if (child.children) {
child.children.forEach((sub, idx2) => {
//sub是每一小项items
console.log('sub', sub);
// 创建一个节点 第三层
let b = document.createElement('div');
b.classList = 'sub-item name-item';
b.id = idx0 + '-' + idx1 + '-' + idx2;
// elementNode.setAttribute(name,value):增加一个指定名称和值得新属性,或者把一个现有的属性设定为指定的值。name:要设置的属性名。value:要设置的属性值。
// 给div设置一个新的属性值
b.setAttribute('pid', [idx0, idx0 + '-' + idx1]);
b.style.marginLeft = '50px';
b.style.cursor = 'pointer';
// 给第三层inner进名字
b.innerText = sub.name;
// 第二层级添加第三层级以及内容
div.append(b);
// 创建内容节点
let ans = document.createElement('div');
ans.classList = 'ans-item';
ans.id = 'ans-' + b.id;
ans.innerText = sub.ans; //inner进去内容
//克隆标题
ansCon.append(b.cloneNode(true), ans);
// 点击导航显示对应的内容在中间的位子且高亮
b.onclick = function () {
//获取菜单全部去除高亮的作用
let subItem = [
...document.getElementsByClassName('sub-item'),
...document.getElementsByClassName('second-item'),
...document.getElementsByClassName('first-item'),
];
console.log('subItem', subItem);
for (let i = 0; i < subItem.length; i++) {
subItem[i].classList.remove('active');
}
// elementNode.getAttribute(name):获取节点的属性,name是属性名称,比如ID,title,value等的值。
this.getAttribute('pid').split(',').forEach((e) => {
console.log('e----', e);
document.getElementById(e).classList.toggle('active');
});
console.log('parentNode', this.getAttribute('pid'));
this.classList.toggle('active');
let targetItem = document.getElementById('ans-' + this.id);
console.log('11111---', targetItem);
// 页面内容动画滚动过度, 第三层标签高亮
ansWrap.scrollTo({
top: targetItem.offsetTop - 30,
behavior: 'smooth',
block: 'start',
inline: 'start',
});
};
// 监听右边容器滚动
let districtName = ansWrap.onscroll = function (e) {
let sections = document.querySelectorAll('.ansCon .sub-item');
console.log('this.districtName', sections[0].offsetTop - 141 - 30);
// 滚动的高度
let scroll = ansWrap.scrollTop
console.log(ansWrap.scrollTop)
for (let i = 0; i < sections.length; i++) {
console.log(sections[i].offsetTop)
if(scroll > sections[i].offsetTop - 141 - 30){
activeSroll(sections[i])
}
}
};
// 获取左边节点
function activeSroll(sections) {
let leftWap = document.getElementById("wrap")
let leftDom = leftWap.getElementsByClassName("sub-item")
console.log(leftDom[0].innerText)
for (let i = 0; i < leftDom.length; i++) {
if(sections.innerText === leftDom[i].innerText){
leftDom[i].classList.add('active')
}else{
leftDom[i].classList.remove('active')
}
}
}
});
}
let m = document.createElement('div');
m.classList = 'second-item name-item';
m.id = idx0 + '-' + idx1;
m.innerText = child.name;
m.style.marginLeft = '20px';
ul.append(m, div);
ansItem.append(m.cloneNode(true), ansCon);
});
}
let s = document.createElement('div');
s.classList = 'first-item name-item';
s.id = idx0;
s.innerText = el.name;
wrap.append(s, ul);
// ansWrap.append(s.cloneNode(true), ansItem)
// 不用出现大标题
ansWrap.append(ansItem);
});
// 搜索内容的展示区域
let str = '';
// 搜索框
let searchBox = document.getElementById('nav');
let text_field = document.getElementById('one');
let show = document.getElementById('show');
// 克隆节点到展示区域
// show.append(wrap.cloneNode(true));
// 搜索
// 聚焦的时候展示框出现
text_field.onfocus = function() {
show.style.display = "block";
text_field.style.border = "1px #42b983 solid";
text_field.onkeyup = function (e) {
// 每次获取时先清空里面原有的,要不然会重复
str = '';
let searchInput = document.getElementById('one');
// 获取里面的数据
let searchValue = one.value.trim();
// 第二层
// let nameList = document.getElementsByClassName('name-item');
let nameList = document.querySelectorAll('.ansItem .name-item')
//内容层
// let ansList = document.getElementsByClassName('ans-item');
let ansList = document.querySelectorAll('.ansItem .ansCon .ans-item');
// 搜索标题匹配高亮
// 匹配lsit中的每一项
let hasKey = false;
for (let i = 0; i < nameList.length; i++) {
if (nameList[i].innerHTML.indexOf(searchValue) > -1 && searchValue) {
let pids = nameList[i].getAttribute('pid');
console.log('搜索有的222', searchValue, pids);
nameList[i].innerHTML = nameList[i].innerHTML.replaceAll(
searchValue,
`<span style="color:red">${searchValue}</span>`
);
show.style.display = 'block';
hasKey = true;
str += `<div class="namelist" id="namelist1">${nameList[i].innerHTML}</div>`
//点击标题跳转导航
let targetItem = document.getElementsByClassName('ans-item')
let a = document.getElementById('namelist1');
console.log('a----', a);
let clickNav = nameList[i]
console.log('clickNav', nameList[i]);
clickNav.onclick = function () {
console.log(111111111111111);
ansWrap.scrollTo({
top: targetItem.offsetTop - 30,
behavior: 'smooth',
block: 'start',
inline: 'start',
})
}
} else {
nameList[i].innerHTML = nameList[i].innerHTML
.replaceAll('<span style="color:red">', '')
.replaceAll('</span>', '');
}
}
// 内容层搜索
for (let i = 0; i < ansList.length; i++) {
if (ansList[i].innerHTML.indexOf(searchValue) > -1 && searchValue) {
let pids = ansList[i].getAttribute('pid');
console.log('搜索有的222', searchValue, pids);
ansList[i].innerHTML = ansList[i].innerHTML.replaceAll(
searchValue,
`<span style="color:red">${searchValue}</span>`
);
show.style.display = 'block';
hasKey = true;
// str += `<div>${ansList[i].innerHTML}</div>`
// 截取内容
let str2 = ansList[i].innerText
console.log('ansList[i].innerText', ansList[i].innerText);
let newStr = ""; //字符串中截取后拼接成的新字符串
let keys = searchValue; //关键字
console.log('keys', keys);
let keysArr = []; //字符串中截取的关键字数组
if (str2 != 0) {
let indexArr = []; //关键字索引数组 即关键字所在字符串的索引
// 遍历关键字数组,分别获取他们在字符串中的位置 (即是索引)
for (let j = 0; j < keys.length; j++){
let index = str2.indexOf(keys[j]);
console.log('index', str2.indexOf(keys[j]));
if (index != -1) {
indexArr.push(index); //不等于-1即是存在该关键字, 保存到关键字索引数组中
}
}
console.log('indexArr', indexArr); //空的
// 如果关键字索引数组有值,则说明字符串中还存在关键字的内容
if (indexArr.length > 0) {
indexObj = getMin(indexArr); //调用获取最小值函数
let minEle = indexObj.minEle; //最小值(对应的是字符串的索引)
let minIndex = indexObj.minIndex; //最小值对应的索引(对应的是关键字数组的索引)
keysArr.push(str2.substring(minEle - 4, minEle + keys[minIndex].length+4)+ '...');//截取所在索引的前4位和后4位
}
}
newStr = keysArr;
console.log('keysArr', keysArr); //空的
str += `<div class="anslist1">${newStr}</div>`
// 最小值函数
function getMin(arr) {
let minEle = Math.max.apply(Math, arr); //默认给数组的最大值
let minIndex = 0;
for (let i = 0; i < arr.length; i++){
// 如果当前元素的值比前面保存的值小,就替换,否则不变
if (arr[i] < minEle){
minEle = arr[i];
minIndex = i;
}
}
return {
minEle: minEle,
minIndex: minIndex
}
};
// 点击搜索的内容点击跳转导航
let clickContent = document.querySelectorAll('#show #namelist1');
console.log('clickContent', clickContent);
clickContent.onclick = function() {
console.log(2222222);
// ansWrap.scrollTo({
// top: targetItem.offsetTop - 30,
// behavior: 'smooth',
// block: 'start',
// inline: 'start',
// })
}
} else {
ansList[i].innerHTML = ansList[i].innerHTML
.replaceAll('<span style="color:red">', '')
.replaceAll('</span>', '');
}
}
// 当没有输入内容或者是内容不符时
if (searchValue == '' || !hasKey) {
show.innerHTML = `<div>暂无结果</div>`
} else {
show.innerHTML = str;
console.log('str---', str);
}
};
let levelBox = document.createElement('div');
levelBox.classList = 'levelBox';
// 层级展示区域
// 点击内容跳转导航
}
// 失焦时 展示框隐藏
text_field.onblur = function() {
show.style.display = 'none';
// show.style.display = "block";
text_field.style.border = '1px #e3e3e3 solid;';
show.innerHTML = '';
}
// 点击按钮
let button = document.getElementById('search');
</script>
<style>
* {
padding: 0;
margin: 0;
}
.content {
margin-top: 50px;
}
.child-item {
min-width: 50%;
text-align: center;
margin-bottom: 10px;
border: 1px dashed;
box-sizing: border-box;
}
.child-item2 {
height: 100px;
}
.link-text {
width: 100px;
border: 1px solid;
text-align: center;
}
.number-list {
width: 150px;
background-color: #5191ee;
}
.active {
background-color: yellow;
}
.main-wrap {
margin-left: 100px;
margin-top: 100px;
}
.info {
width: 800px;
height: 700px;
display: flex;
overflow: hidden;
margin-left: 100px;
}
.right-wrap .name-item {
margin-left: 0 !important;
}
.left-wrap {
width: 120px;
background-color: #5191ee;
min-height: 100vh;
margin-top: 50px;
margin-left: 100px;
}
.right-wrap {
flex: 1;
background-color: #fff;
overflow-y: auto;
height: 100vh;
margin-top: 50px;
}
.ans-item {
height: 200px;
}
.hidden {
display: none !important;
}
.show {
display: block !important;
}
.ans-list-item {
margin-left: 300px;
margin-top: -200px;
width: 300px;
height: 100%;
}
.search-result {
}
.container {
margin-left: 350px;
}
#nav {
display: flex;
}
.btn {
width: 50px;
height: 20px;
margin-left: 50px;
}
#one {
height: 30px;
line-height: 30px;
box-sizing: border-box;
padding: 0 15px 0 30px;
border: 1px solid #e3e3e3;
color: #273849;
outline: none;
border-radius: 15px;
margin-right: 10px;
transition: border-color 0.2s ease;
background-size: 20px;
vertical-align: middle !important;
}
#show {
position: absolute;
z-index: 99;
width: 270px;
height: 170px;
border: 1px solid rgba(77, 76, 76, 0.459);
display: none;
margin-top: 40px;
overflow: hidden;
background-color: #fff;
}
#show div{
width: 100%;
height: 40px;
line-height: 40px;
text-indent: 1em;
display: block;
}
#show div:hover{
background-color: rgb(240, 240, 245);
cursor:pointer;
}
/* 层级展示 */
.namelist {
background-color: #f1f3f5;
}
.anslist {
background-color: #ffffff;
}
</style>
</body>
</html>