sessionStorage 键值是否为空进行判断

本文介绍如何在sessionStorage中检查指定键是否存在及其值是否为空。通过使用sessionStorage.getItem方法,可以安全地进行判断而不会因键不存在而引发错误。

sessionStorage中未存储任何键值时,若要对某个键的值是否为空进行判断,可进行如下判断

	if (sessionStorage.getItem("key") != null) {
	      //自定义代码
	}

注意:上述代码,可以直接进行 getItem("key")判断,即使 sessionStorage 中没有该键,也不会报错。

/* 框架页面js文件 */ // 渲染头像和昵称 document.querySelector('.avatar').innerHTML = ` <img src="./img/10043.png" alt="用户头像" onclick="preview('./img/10043.png')" onerror="this.src='./img/10043.png'" /> <div class="nickname">${proof?.userinfo?.nickname || proof?.nickname || '用户'}</div> `; // 映射菜单图表 const firstLevelIconMap = { 1: './img/IconBarChart.png', 2: './img/IconUserGroup.png', 3: './img/IconIdcard.png', 4: './img/IconCalendarClock.png', 5: './img/IconUser.png', 6: './img/IconApps.png', 7: './img/IconArchive.png', 10: './img/IconFile.png', 11: './img/IconImage.png', default: './img/default-icon.png' //默认 }; let tree = []; //用于存储构建好的树形结构 let data; //用于存储经过处理后的树形结构数据,后续用于渲染页面 // 获取菜单数据 let menuData = proof.menu; // 构建树形结构 let menuTree = buildTree(menuData); data = menuTree; /** * 构建树形结构 * @param {Array} menu - 传参菜单数据数组 * @returns {Array} - 构建后的树形结构数组 */ function buildTree(menu) { tree = []; let mapped = {}; // 第一遍循环,初始化mapped对象并且初始化children属性 menu.forEach(menu => { mapped[menu.id] = menu; menu.children = menu.children || []; // 确保children属性始终是数组 }); // 第二遍循环,根据pid构建树形结构 menu.forEach(menu => { if (menu.pid !== 0) { if (mapped[menu.pid]) { mapped[menu.pid].children.push(menu); } } else { tree.push(menu); } }); return tree; } // 检查数据是否有效 if (data && Array.isArray(data)) { // 渲染树形菜单 render(data); } // 将数据中的菜单赋给 `menu` 变量,方便后续使用 let menu = data; // 声明数组 `arr`,用于后续渲染面包屑导航 let arr; /** * 渲染树形菜单的递归函数 * @param {Array} menu - 菜单数据数组 * @param {boolean} isFirstLevel - 标记是否为一级菜单 * @returns {string} 拼接好的 HTML 字符串 */ function render(menu, isFirstLevel = true) { let str = ''; // 菜单数据验证(原有逻辑保留) if (!menu || !Array.isArray(menu)) { console.error('Invalid menu data:', menu); return str; } for (let i in menu) { const menuItem = menu[i]; if (!menuItem || typeof menuItem !== 'object') continue; // 基础数据获取 const locale = menuItem.meta && menuItem.meta.locale ? menuItem.meta.locale : '未命名菜单'; const menuId = menuItem.id || ''; // 一级菜单ID(用于匹配图标) const path = menuItem.path || '#'; // 仅一级菜单:匹配图标(从firstLevelIconMap取,无匹配用默认) let iconHtml = ''; // 存储图标HTML(子菜单为) if (isFirstLevel) { // 仅当"是一级菜单"时,拼接图标HTML const iconSrc = firstLevelIconMap[menuId] || firstLevelIconMap.default; iconHtml = `<img src="${iconSrc}" alt="${locale}" class="menu-icon" />`; } // 3. 有子菜单的菜单项 if (menuItem.children && Array.isArray(menuItem.children) && menuItem.children.length > 0) { str += `<p class="option_parent" data-menu-id="${menuId}">`; str += iconHtml; str += `<span class="nickname-text">${locale}</span>`; str += `<img src="./img/arrows.png" alt="" data-arrow="true" class="arrow-icon" /></p>`; str += `<div class="child" style="display:none;">`; // 递归渲染子菜单 str += render(menuItem.children, false); str += `</div>`; } // 4. 无子菜单的菜单项 else { str += `<p class="option" data-id="${menuId}" onclick="navigateToMenu(1,'${path}','${locale}','${menuId}')">`; str += iconHtml; // 仅一级菜单插入图标 str += `<span class="nickname-text">${locale}</span></p>`; } } return str; } // 调用 `render` 函数,开始渲染树形菜单 let str = render(menu); // 将渲染好的菜单项插入到页面的 .option_box 元素中 document.querySelector(".option_box").innerHTML = str; // 获取所有树形菜单中的选项元素 let tree_option = document.querySelectorAll(".option"); // 监听 class 为 'option_box' 的鼠标松开事件(mouseup) document.getElementsByClassName('option_box')[0].addEventListener('mouseup', function (e) { e = e || window.event; let target = e.target || e.srcElement; // 关键修复:如果点击的是父菜单文字,向上找到对应的父菜单容器 if (target.classList.contains('nickname-text')) { target = target.closest('.option_parent'); } // 如果点击的是图标或箭头,向上查找父菜单元素(option_parent 或 option) else if (target.classList.contains('menu-icon') || target.classList.contains('arrow-icon')) { target = target.parentElement; } // 点击子菜单选项(option):高亮当前子菜单 if (target?.className === 'option') { highlightTargetOnly(target); // 仅子菜单保留高亮 } // 点击父菜单选项(option_parent):仅展开,不高亮 else if (target?.className === 'option_parent') { // 此处删除 highlightTargetOnly(target); } // 处理子菜单的显示/隐藏逻辑(仅针对有子菜单的父菜单) if (target && target.nextElementSibling !== null && target.nextElementSibling.className === 'child') { const childMenu = target.nextElementSibling; childMenu.style.display = childMenu.style.display === 'none' ? 'block' : 'none'; } // 处理箭头图标旋转状态(仅针对有箭头的父菜单) if (target) { const arrowIcon = target.querySelector('.arrow-icon'); if (arrowIcon) { const isExpanded = arrowIcon.getAttribute('data-arrow') === 'false'; if (isExpanded) { arrowIcon.classList.remove('arrowhead'); arrowIcon.setAttribute('data-arrow', 'true'); } else { arrowIcon.classList.add('arrowhead'); arrowIcon.setAttribute('data-arrow', 'false'); } } } }); // 检查 sessionStorage是否存在 'main' 键值对 if (sessionStorage.getItem('main')) { // 获取到面包屑数据,使用 JSON.parse 解析字符串为数组,在为arr赋 arr = JSON.parse(sessionStorage.getItem('main')); } else { // arr没有就将"数据统计"的数据放入 arr = [{ status: 1, path: menu[0].path, locale: menu[0].meta.locale, // 从meta中获取locale id: menu[0].id }]; } // 页面加载完成后恢复高亮状态 document.addEventListener('DOMContentLoaded', function () { addCrumb(arr); // 调用面包屑的渲染函数 restoreMenuHighlight(); // 恢复菜单高亮状态 }); // 面包屑点击添加函数,通过传参将状态,路径,名称,id传过去 function navigateToMenu(status, path, locale, id) { let obj = { status: status, path: path, locale: locale, id: id }; let isExists = false; // 检查是否已存在该菜单项 for (let i = 0; i < arr.length; i++) { if (arr[i].id === id) { isExists = true; // 重置所有状态为默认,再将匹配项设为高亮 for (let j = 0; j < arr.length; j++) { arr[j].status = 2; } arr[i].status = 1; break; } } // 不存在则添加新项 if (!isExists) { for (let i = 0; i < arr.length; i++) { arr[i].status = 2; } arr.push(obj); arr[arr.length - 1].status = 1; } sessionStorage.setItem('main', JSON.stringify(arr)); addCrumb(arr); } // 面包屑渲染函数 function addCrumb(arr) { // 用于存储除首页外的面包屑 HTML 代码 let bread = ''; // 用于存储首页的面包屑 HTML 代码 let breads = ''; // 存储当前激活的菜单ID(用于后续高亮) let activeId = null; // 遍历传入的数组,处理每个面包屑项 for (let i in arr) { // 记录当前激活的菜单ID if (arr[i].status === 1) { activeId = arr[i].id; } // 渲染首页面包屑 if (arr[i].locale === '数据统计') { breads = ` <div class="home_bread ${arr[i].status === 1 ? 'highlighted' : ''}"> <img src="${arr[i].status === 1 ? './img/lightHome.png' : './img/home.png'}" alt="首页图标" class="home_icon" /> <div class="page" onclick="target(1, '${arr[i].path}', '${arr[i].locale}','${arr[i].id}')">${arr[i].locale}</div> </div> `; } else { // 渲染其他面包屑 bread += ` <div class="crumb ${arr[i].status === 1 ? 'highlighted' : ''}"> <p class="crumbName" onclick="target(${arr[i].status},'${arr[i].path}','${arr[i].locale}','${arr[i].id}')">${arr[i].locale}</p> <div class="omit" onclick="delete_btn('${arr[i].locale}', ${i})"> <img src="./img/delete.png" alt="删除图标" /> </div> </div> `; } // 更新 iframe 内容 if (arr[i].status === 1) { // 修复路径处理逻辑 let pathUrl = arr[i].path.startsWith('./') ? arr[i].path : arr[i].path.startsWith('/') ? '.' + arr[i].path + '.html' : './' + arr[i].path + '.html'; checkUrl(pathUrl, function (isValid) { if (isValid) { // 如果路径有效,加载 iframe document.getElementById("page").style.display = "block"; document.getElementById("page").setAttribute("src", pathUrl); document.getElementById("devAlert").style.display = "none"; } else { // 如果路径无效,隐藏 iframe 并显示提示 document.getElementById("page").style.display = "none"; document.getElementById("devAlert").style.display = "flex"; } }); } } // 将面包屑 HTML 插入到容器中 document.querySelector('.crumb_content').innerHTML = bread; document.querySelector('.home').innerHTML = breads; // 恢复菜单高亮状态 restoreMenuHighlight(); } // 恢复菜单高亮状态函数 function restoreMenuHighlight() { if (!arr || arr.length === 0) return; // 查找当前激活的菜单项 let activeItem = arr.find(item => item.status === 1); if (!activeItem) return; // 移除所有菜单的高亮 document.querySelectorAll(".option, .option_parent").forEach(el => { el.classList.remove("backColor"); }); // 高亮匹配的子菜单 document.querySelectorAll(`.option[data-id="${activeItem.id}"]`).forEach(el => { el.classList.add("backColor"); }); // 高亮匹配的父菜单 document.querySelectorAll(`.option_parent[data-menu-id="${activeItem.id}"]`).forEach(el => { el.classList.add("backColor"); }); // 动态控制父菜单箭头旋转 let activeElement = document.querySelector(".backColor"); if (activeElement) { // 查找最近的父菜单容器 let parentContainer = activeElement.closest('.child'); if (parentContainer && parentContainer.style.display === "none") { // 展开隐藏的子菜单 parentContainer.style.display = "block"; // 切换箭头方向 let arrowIcon = parentContainer.previousElementSibling.querySelector('.arrow-icon'); if (arrowIcon) { arrowIcon.classList.add("arrowhead"); arrowIcon.setAttribute("data-arrow", "false"); } } } } function highlightTargetOnly(target) { // 移除所有菜单(父 + 子)的高亮 document.querySelectorAll(".option, .option_parent").forEach(el => { el.classList.remove("backColor"); }); // 为当前点击的菜单添加高亮 target.classList.add("backColor"); } // 检查 URL 是否有效的函数 function checkUrl(url, callback) { const xhr = new XMLHttpRequest(); xhr.open("HEAD", url, true); xhr.onload = function () { // 如果状态码为 404,则说明路径不存在 if (xhr.status === 404) { callback(false); } else { callback(true); } }; xhr.onerror = function () { callback(false); // 如果请求发生错误,也视为路径不存在 }; xhr.send(); } // 面包屑的删除函数 function delete_btn(locale, index) { // 判断当前删除的如果是最后一个,并且最后一个时是当前高亮状态 if (index == arr.length - 1 && arr[arr.length - 1].status == 1) { // 将当前删除后的最后一个设置为高亮 arr[arr.length - 2].status = 1; sessionStorage.setItem('main', JSON.stringify(arr)); } // 再判断当前删除的如果是高亮状态的,并且不是面包屑最后一个 if (arr[index].status == 1 && arr[arr.length - 1].status != 1) { // 将当前删除面包屑后面的一个 arr[index + 1].status = 1; sessionStorage.setItem('main', JSON.stringify(arr)); } // 删除当前面包屑 arr.splice(index, 1); sessionStorage.setItem('main', JSON.stringify(arr)); // 重新调用一下渲染函数 addCrumb(arr); } // 面包屑的点击函数 function target(status, path, title, id) { // 将当前的面包屑循环一遍 for (let i in arr) { // 将全部的状态改为默认状态 arr[i].status = 2; // 再将当前的数据重新存储一下 sessionStorage.setItem('main', JSON.stringify(arr)); // 利用判断得到当前的面包屑 if (arr[i].id == id) { // 将当前面包屑的状态改为高亮状态 arr[i].status = 1; // 重新存储一下数据 sessionStorage.setItem('main', JSON.stringify(arr)); } } // 调用渲染函数,刷新页面状态 addCrumb(arr); } // 点击全屏开关函数 function full() { // 判断当前页面是否处于全屏状态 if (!document.fullscreenElement) { // 如果不是全屏状态,则请求将整个文档元素设置为全屏显示 document.documentElement.requestFullscreen(); // 切换全屏按钮的图标为退出全屏图标 document.querySelector("#screen img").setAttribute("src", `./img/screen.png`); } else { // 如果已经是全屏状态,则尝试退出全屏 if (document.exitFullscreen) { // 调用退出全屏的方法 document.exitFullscreen(); // 切换全屏按钮的图标为进入全屏图标 document.querySelector("#screen img").setAttribute("src", `./img/allScreen.png`); } } } document.addEventListener("fullscreenchange", updateIcon); // 该函数用于根据当前的全屏状态更新全屏按钮的图标 function updateIcon() { // 判断当前是否处于全屏状态,考虑了不同浏览器的兼容性 if ( document.fullscreenElement || // 标准的全屏元素属性 document.webkitFullscreenElement || // WebKit 浏览器(如 Safari)的全屏元素属性 document.mozFullScreenElement || // Firefox 浏览器的全屏元素属性 document.msFullscreenElement // IE 浏览器的全屏元素属性 ) { // 如果处于全屏状态,将全屏按钮的图标设置为退出全屏图标 document.querySelector("#screen img").setAttribute("src", `./img/screen.png`); } else { // 如果不是全屏状态,将全屏按钮的图标设置为进入全屏图标 document.querySelector("#screen img").setAttribute("src", `./img/allScreen.png`); } } // 刷新 function refresh() { document.querySelector("#refresh img").style.transform = 'rotate(360deg)'; document.querySelector("#refresh img").style.transition = 'all 0.5s'; // 延时500毫秒后刷新页面 setTimeout(function () { window.location.reload(); }, 500); } //点击跳转到锁屏页面 function lock() { window.location.replace('./lock.html'); sessionStorage.setItem('lock', 1); } // 头像点击退出登录 function exit() { document.querySelector('.over').style.display = 'block'; } function cancel() { document.querySelector('.over').style.display = 'none'; } // 点击确定清数据,并跳转到登录页 function sure() { sessionStorage.clear(); window.location.replace("./login.html"); } // 全局变量,用于跟踪菜单折叠状态 let isMenuCollapsed = false; let deg = true; // 声明状态用于判断菜单是否展开 // 折叠 function toggle() { const treeBar = document.querySelector('.tree_bar'); const content = document.querySelector('.content'); const toolImg = document.querySelector('.tool_img img'); if (deg) { // 折叠菜单 treeBar.classList.add('collapsed'); content.classList.add('expanded'); toolImg.style.transform = 'rotate(180deg)'; isMenuCollapsed = true; // 折叠时强制收起所有子菜单 document.querySelectorAll('.child').forEach(child => { child.style.display = 'none'; }); // 折叠时恢复所有箭头方向 document.querySelectorAll('.arrow-icon').forEach(icon => { icon.classList.remove('arrowhead'); icon.setAttribute('data-arrow', 'true'); }); } else { // 展开菜单 treeBar.classList.remove('collapsed'); content.classList.remove('expanded'); toolImg.style.transform = 'rotate(0deg)'; isMenuCollapsed = false; // 展开时恢复菜单高亮状态 restoreMenuHighlight(); } deg = !deg; } // 将渲染好的菜单项插入到页面的 .option_box 元素中 document.querySelector(".option_box").innerHTML = str; // 获取所有一级父菜单 const parentMenus = document.querySelectorAll(".option_parent"); let hoverTimer; // 用于延迟收起子菜单的计时器 parentMenus.forEach(parent => { // 悬浮进入:展开子菜单 parent.addEventListener("mouseenter", function () { // 仅当菜单处于折叠状态,且存在子菜单时,才展开 if (isMenuCollapsed) { const childMenu = this.nextElementSibling; // 子菜单容器 const arrowIcon = this.querySelector(".arrow-icon"); if (childMenu && childMenu.className === "child") { childMenu.style.display = "block"; } if (arrowIcon) { arrowIcon.classList.add("arrowhead"); arrowIcon.setAttribute("data-arrow", "false"); } } }); // 悬浮离开:延迟收起子菜单 parent.addEventListener("mouseleave", function () { // 仅当菜单处于折叠状态,且存在子菜单时,才延迟收起 if (isMenuCollapsed) { const childMenu = this.nextElementSibling; const arrowIcon = this.querySelector(".arrow-icon"); // 延迟300ms收起(避免鼠标快速划过误触发) hoverTimer = setTimeout(() => { if (childMenu && childMenu.className === "child") { childMenu.style.display = "none"; // 收起子菜单 } if (arrowIcon) { arrowIcon.classList.remove("arrowhead"); // 恢复箭头方向 arrowIcon.setAttribute("data-arrow", "true"); } }, 100); } }); // 子菜单区域悬浮:延续父菜单悬浮状态 const childMenu = parent.nextElementSibling; if (childMenu && childMenu.className === "child") { // 子菜单悬浮进入:清除延迟收起计时器 childMenu.addEventListener("mouseenter", function () { if (hoverTimer) clearTimeout(hoverTimer); }); // 子菜单悬浮离开:延迟收起 childMenu.addEventListener("mouseleave", function () { if (isMenuCollapsed) { hoverTimer = setTimeout(() => { childMenu.style.display = "none"; const arrowIcon = parent.querySelector(".arrow-icon"); if (arrowIcon) { arrowIcon.classList.remove("arrowhead"); arrowIcon.setAttribute("data-arrow", "true"); } }, 300); } }); } });怎么让子菜单在折叠情况下悬浮在父菜单右边?
09-05
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悟世君子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值