soarli博客 - Javascript
type: channel
link: https://blog.soarli.top/tag/Javascript/
items: 近乎完美地解决MathJax与Marked的冲突
items: layuimini实现点击左侧菜单刷新对应页面
items: 解决Laydate在手机无法滑动问题
items: 解决blur事件与click事件的冲突
items: Ajax跨域解决方案总结
items: 通过Ajax以表单的形式提交多变量
items: 返回页面时强制刷新方案
items: JavaScript 操作选中当前的li元素并给它添加select类
items: 通过JS向剪切板写入数据
items: 键盘键码值keyCode大全

近乎完美地解决MathJax与Marked的冲突
type: item
date: 2024-09-19T22:04:21+08:00
description: 本文由AI辅助撰写，可能存在不准确之处，请读者注意甄别！在文章《让MathJax更好地兼容谷歌翻译和延时加载》中，原作者探讨了Cool Papers引入MathJax解析LaTeX公式后的兼容性问题。虽已解决部分问题，但在Cool Papers中，MathJax与Markdown渲染库Marked之间的冲突依然存在。这篇文章将专注于如何完美解决这个问题。问题背景Markdown是一种轻量级的标记语言，广泛用于编写文档。Cool Papers使用的Kimi功能输出的是Markdown语法，并通过Marked库在前端将其转换为HTML。然而，LaTeX公式与Markdown有部分语法重合，这导致Marked可能会错误处理LaTeX代码，导致MathJax无法正确渲染公式。一个简单的代码展示了问题所在： 在这段代码中，\\(a^2 + b^2\\)和\\\\(c^2 + d^2\\\\)代表LaTeX公式，但只有后者能被MathJax正确渲染。原因是Marked误解析了部分LaTeX代码，导致公式失效。已有解决方案目前，社区已经提出了几种解决MathJax与Marked冲突的方法：手动转义：通过手动修改LaTeX代码以适应Marked的解析方式，虽然有效但不直观，且Cool Papers使用的公式是自动生成的，不能轻易修改。保护公式：将LaTeX代码放在代码块中避免被Marked解析，但这种方式容易与实际的代码块混淆。更换引擎：使用更好的渲染引擎，如Pandoc，但这种方案主要针对后端，前端渲染没有很好的替代方案。修改Marked引擎：修改Marked的规则，避免其解析LaTeX代码。但这种方式治标不治本，需要不断手动调整规则。这些方案都存在一定的局限性，因此我们需要一个更加优雅的解决方案。逆向思路：先MathJax，后Marked问题的根源在于Marked与MathJax的渲染顺序——Marked会误解析LaTeX代码。那么，如果我们反过来处理，先用MathJax渲染公式，再用Marked处理Markdown内容，这样便可以从根本上解决问题。以下是实现该思路的代码： 该方案能够让MathJax优先处理LaTeX公式，确保公式能够被正确解析，然后再由Marked处理剩余的Markdown内容。进一步优化尽管上述方案能够有效解决问题，但对于有“强迫症”的用户来说，仍有两个小瑕疵：1. 初始页面显示乱码在渲染完成之前，用户会短暂看到未处理的Markdown文本，类似乱码。为了改善这一体验，可以在渲染完成后再将内容显示给用户： 通过在隐藏的元素中进行渲染，用户可以直接看到最终渲染结果，避免看到中间的乱码。2. MathJax菜单消失另一个问题是，MathJax自带的右键菜单功能消失了。原因是，重新渲染HTML内容时，绑定在公式上的事件监听器被移除了。为了解决这个问题，可以在Markdown解析后，重新调用MathJax的Typeset方法来渲染公式： 在此代码中，删除已渲染的公式并重新调用Typeset确保MathJax功能正常。3. 保存原始公式代码Marked会错误解析嵌入的 通过这种方式，我们能够避免Marked对公式进行错误解析，同时保证MathJax的正常渲染。结论通过逆向思路，先用MathJax处理公式，再用Marked渲染Markdown，我们可以有效解决MathJax与Marked的冲突问题，并进一步通过优化，提升页面的显示效果和用户体验。这种方法不仅适用于前端渲染的场景，也可以为后端渲染提供参考。参考资料：近乎完美地解决MathJax与Marked的冲突 - 科学空间|Scientific Spaces给自己的站点增加基于MathJax的LaTeX公式支持 - 知乎

layuimini实现点击左侧菜单刷新对应页面
type: item
date: 2022-07-29T21:23:00+08:00
description: 在项目\js\lay-module\layuimini\miniTab.js文件中，修改listenSwitch方法：listenSwitch: function (options) { options.filter = options.filter || null; options.multiModule = options.multiModule || false; options.urlHashLocation = options.urlHashLocation || false; options.listenSwichCallback = options.listenSwichCallback || function () { }; element.on('tab(' + options.filter + ')', function (data) { console.log('页面切换123........'); var tabId = $(this).attr('lay-id'); if (options.urlHashLocation) { location.hash = '/' + tabId; } if (typeof options.listenSwichCallback === 'function') { options.listenSwichCallback(); } // 判断是否为新增窗口 if ($('.layuimini-menu-left').attr('layuimini-tab-tag') === 'add') { $('.layuimini-menu-left').attr('layuimini-tab-tag', 'no') } else { $("[layuimini-href]").parent().removeClass('layui-this'); if (options.multiModule) { miniTab.listenSwitchMultiModule(tabId); } else { miniTab.listenSwitchSingleModule(tabId); } $(".layui-tab-item.layui-show").find("iframe")[0].contentWindow.location.reload(); //尝试刷新 } miniTab.rollPosition(); }); },在最后一行加上$(".layui-tab-item.layui-show").find("iframe")[0].contentWindow.location.reload(); //尝试刷新如下图所示：参考文章：https://icode.best/i/52249049464567https://blog.csdn.net/weixin_44828157/article/details/115290927

解决Laydate在手机无法滑动问题
type: item
date: 2022-03-13T16:18:00+08:00
description: 前言Laydate选择时间模块在手机使用时需要先手动在框里点击一下的问题在一年前困扰我和学长许久（都是这方面的强迫症，没办法）。记得去年有一次（不止一次尝试解决这个问题）我独自尝试用js的focus等事件通过条件对焦的方法调试了一晚上，看着眼花缭乱的父子DOM结点变化而无法在互联网上查阅到任何一种有效监听方法的绝望仍然记忆犹新。为减小Laydate的兼容性bug对请假系统项目体验的不良影响，学长在项目中写了前端代码通过增大可选时间跨度以及根据当前时间展示可选范围。然而我们当时万万没想到的是：正确解决这个前端问题的方法竟然是两行CSS代码。分析既然JavaScript无从解决，那就从CSS下手：分析到时间选择列表ol对应的overflow属性值为hidden，其作用包括溢出隐藏、清除浮动和解决外边距塌陷（点击查看详情）的意思，其中触发visible的默认条件是hover。然而手机端触发hover必须得点一下，而PC端只需将光标移上即可。因此，只需修改overflow对应的属性即可完美解决问题：/* 允许手机端laydate选择时间时上下滑动 */ .laydate-time-list ol{ overflow-x: hidden !important; overflow-y:auto !important; }目前，该解决方案已部署于我的毕设和学生请假系统git项目及正式环境中。总结通过今天晚上（昨天晚上今天凌晨）在请假系统项目的实战中对CSS和汉字编码有了更深一步的理解。参考资料：https://www.php.cn/css-tutorial-412426.htmlhttps://www.w3school.com.cn/tags/tag_ol.asphttps://blog.csdn.net/boysky0015/article/details/72824172https://blog.csdn.net/Start2019/article/details/116226021https://blog.csdn.net/qq_41638795/article/details/83304388

解决blur事件与click事件的冲突
type: item
date: 2022-03-12T23:17:00+08:00
description: 前言近日在毕设中引入了搜索框，巧妙设计前端样式后遇到了在点击搜索按钮时搜索框失去焦点事件与点击搜索按钮事件冲突的现象，并且浏览器会优先执行blur事件从而导致click事件无法执行。知识下面是关于二者的介绍：blur事件：当元素失去焦点时触发blur事件；早前，blur 事件仅发生于表单元素上。在新浏览器中，该事件可用于任何元素，blur和focus事件不会冒泡，其他表单事件都可以。click事件：当点击元素时触发click事件；所有元素都有此事件，会产生冒泡。至于为什么会出现上述问题：Javascript为单线程，同一时间只能执行处理一个事件，所以当blur执行时，会导致其后续click事件并不会执行。解决方法一：让click事件比blur事件先触发，可以给blur事件加定时器延迟触发：/*删除图标的点击事件*/ $(".delete-icon").on("click",function () { $(this).prev("input").val("").focus(); }); /*输入框失去焦点的blur事件*/ $("input[name='username'],input[name='password']").on("blur",function () { var $this = $(this); setTimeout(function(){ $this.parent().removeClass("active"); $this.next(".delete-icon").hide(); },250) });缺点：设置多久的延时是一个难以两全的问题，时间太短不能保证click事件的100%触发，时间太长则会造成卡顿的感觉，影响用户体验方法二：将click事件改为mousedown事件，mousedown事件会优先于blur事件执行/*删除图标的点击事件*/ $(".delete-icon").on("mousedown",function () { $(this).prev("input").val("").focus(); }); /*输入框失去焦点的blur事件*/ $("input[name='username'],input[name='password']").on("blur",function () { var $this = $(this); $this.parent().removeClass("active"); $this.next(".delete-icon").hide(); });缺点：鼠标按下便触发了事件，不收起、长按也会触发，可能在特殊场景下造成用户体验不好（足够满足我的需求了）方法三：给图标再添加一个mousedown事件，在其中执行event.preventDefault()阻止浏览器默认事件，这样点击按钮时输入框就不会失去焦点了/*阻止浏览器默认事件*/ $(".delete-icon").on("mousedown",function(e) { e.preventDefault(); }) /*删除图标的点击事件*/ $(".delete-icon").on("click",function () { $(this).prev("input").val("").focus(); }); /*输入框失去焦点的blur事件*/ $("input[name='username'],input[name='password']").on("blur",function () { var $this = $(this); $this.parent().removeClass("active"); $this.next(".delete-icon").hide(); });方法四：动态绑定blur事件，当鼠标进入input框父级元素时，移除input绑定事件blur，当鼠标移出输入框父级元素时，给input绑定blur事件/*动态绑定blur事件*/ $(".login-con li").mouseenter(function(){ $(this).find("input").unbind("blur"); }); $(".login-con li").mouseleave(function(event){ $(this).find("input").bind("blur"); }); /*删除图标的点击事件*/ $(".delete-icon").on("click",function () { $(this).prev("input").val("").focus(); }); /*输入框失去焦点的blur事件*/ $("input[name='username'],input[nam…

Ajax跨域解决方案总结
type: item
date: 2022-02-03T15:23:51+08:00
description: 本文转载自互联网，已在文末注明来源。本人后续将把实践中积累的相关经验归并总结到本文中。题纲关于跨域，有N种类型，本文只专注于ajax请求跨域(,ajax跨域只是属于浏览器"同源策略"中的一部分,其它的还有Cookie跨域iframe跨域,LocalStorage跨域等这里不做介绍)，内容大概如下:什么是ajax跨域原理表现(整理了一些遇到的问题以及解决方案)如何解决ajax跨域JSONP方式CORS方式代理请求方式如何分析ajax跨域http抓包的分析一些示例什么是ajax跨域ajax跨域的原理ajax出现请求跨域错误问题,主要原因就是因为浏览器的“同源策略”,可以参考浏览器同源政策及其规避方法(阮一峰)CORS请求原理CORS是一个W3C标准，全称是"跨域资源共享"（Cross-origin resource sharing）。它允许浏览器向跨源服务器，发出XMLHttpRequest请求，从而克服了AJAX只能同源使用的限制。基本上目前所有的浏览器都实现了CORS标准,其实目前几乎所有的浏览器ajax请求都是基于CORS机制的,只不过可能平时前端开发人员并不关心而已(所以说其实现在CORS解决方案主要是考虑后台该如何实现的问题)。关于CORS，强烈推荐阅读 跨域资源共享 CORS 详解(阮一峰)另外，这里也整理了一个实现原理图(简化版):如何判断是否是简单请求?浏览器将CORS请求分成两类：简单请求（simple request）和非简单请求（not-so-simple request）。只要同时满足以下两大条件，就属于简单请求。请求方法是以下三种方法之一：HEAD,GET,POSTHTTP的头信息不超出以下几种字段：AcceptAccept-LanguageContent-LanguageLast-Event-IDContent-Type(只限于三个值application/x-www-form-urlencoded、 multipart/form-data、text/plain)凡是不同时满足上面两个条件，就属于非简单请求。ajax跨域的表现说实话，当初整理过一篇文章，然后作为了一个解决方案，但是后来发现仍然有很多人还是不会。无奈只能耗时又耗力的调试。然而就算是我来分析，也只会根据对应的表现来判断是否是跨域，因此这一点是很重要的。ajax请求时,如果存在跨域现象,并且没有进行解决,会有如下表现:(注意，是ajax请求，请不要说为什么http请求可以，而ajax不行，因为ajax是伴随着跨域的，所以仅仅是http请求ok是不行的)注意:具体的后端跨域配置请看题纲位置。第一种现象:No 'Access-Control-Allow-Origin' header is present on the requested resource,并且The response had HTTP status code 404出现这种情况的原因如下：本次ajax请求是“非简单请求”,所以请求前会发送一次预检请求(OPTIONS)服务器端后台接口没有允许OPTIONS请求,导致无法找到对应接口地址解决方案: 后端允许options请求第二种现象:No 'Access-Control-Allow-Origin' header is present on the requested resource,并且The response had HTTP status code 405这种现象和第一种有区别,这种情况下，后台方法允许OPTIONS请求,但是一些配置文件中(如安全配置),阻止了OPTIONS请求,才会导致这个现象解决方案: 后端关闭对应的安全配置第三种现象:No 'Access-Control-Allow-Origin' header is present on the requested resource,并且status 200这种现象和第一种和第二种有区别,这种情况下，服务器端后台允许OPTIONS请求,并且接口也允许OPTIONS请求,但是头部匹配时出现不匹配现象比如origin头部检查不匹配,比如少了一些头部的支持(如常见的X-Requested-With头部),然后服务端就会将response返回给前端,前端检测到这个后就触发XHR.onerror,导致前端控制台报错解决方案: 后端增加对应的头部支持第四种现象:heade contains multiple values '*,*'表现现象是，后台响应的http头部信息有两个Access-Control-Allow-Origin:*说实话，这种问题出现的主要原因就是进行跨域配置的人不了解原理，导致了重复配置，如:常见于.net后台(一般在web.config中配置了一次orig…

通过Ajax以表单的形式提交多变量
type: item
date: 2022-01-21T03:11:00+08:00
description: 通过Ajax以表单的形式提交多变量键值对： function AJAX(b64) { var xmlhttp; if (window.XMLHttpRequest) { // IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码 xmlhttp = new XMLHttpRequest(); } else { // IE6, IE5 浏览器执行代码 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { document.getElementById("myDiv").innerHTML = xmlhttp.responseText; } } xmlhttp.open("POST", "/try/ajax/demo_post.php", true); xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xmlhttp.send( "test=" + encodeURIComponent('123456') + "&b64value=" + encodeURIComponent(b64) ); }参考文章：https://www.runoob.com/ajax/ajax-xmlhttprequest-send.htmlhttps://www.itbaoku.cn/post/49055.htmlhttps://blog.csdn.net/KingJin_CSDN_/article/details/53156864https://blog.csdn.net/qq_34549618/article/details/78480128https://www.cnblogs.com/han-1034683568/p/7199168.htmlhttps://www.w3cschool.cn/ajax/ajax-uy1r2or1.html

返回页面时强制刷新方案
type: item
date: 2021-10-20T23:34:00+08:00
description: 未成功的方法记录第一种：在浏览器中点击返回或者前进按钮时，页面不刷新的问题。如果是移动端下，可能有两种情况：第一种是在自己的app下点击返回的时候页面不刷新，这有可能是你们原生开发人员，只是关闭了当前的一个窗口，也就是说那个窗口是新开的。这种解决方案，老夫只能说找你们的原生开发吧。第二种则是在微信、uc这类的浏览器出现，这是因为浏览器保存了DOM和js的状态，相当于保存了整个页面，这种特性称作 “往返缓存”（back-forward cache，或bfcache）。对于这种情况可以用“pageshow”事件来解决，“pageshow”事件表示浏览器展示文档的时候触发，并且是在“onload”事件之后触发。如果浏览器是存在往返缓存机制的话，那么onload事件就只会触发一次，而“pageshow”事件则每次都会触发。这里需要注意“pageshow”事件必须绑定在window这个对象中，可根据以下方法来让浏览器刷新如下代码：window.addEventListener('pageshow', function(event) { //event.persisted属性为true时，表示当前文档是从往返缓存中获取 if(event.persisted) location.reload(); $(".loading").hide(); });结论：安卓未测试；iOS、Windows测试无效第二种：一、多页面下浏览器返回多页面时浏览器返回的上一个页面如果数据是用ajax加载的则页面会显示不出数据，可以通过以下方法判断在浏览器的返回前进时刷新当前页面，以下方法放到jquery的ready或者HTML的onload方法里，主要针对移动端H5开发function backForwardListen(){ //window.performance.navigation.type=2表示当前页面行为是history.back()或history.forward() if(window.performance.navigation.type == 2) { reloadDeal(window.location.href);//reloadDeal为监测到前进后退时的处理方法，在这里简单的刷新页面所以把当前页面的链接作为参数传进该方法 } }二、单页面下浏览器返回在单面中通过显示和隐藏不同的部分来模拟页面跳转时，如果触发浏览器返回事件则会关闭当前页面，以下例子可以在触发浏览器返回事件时按自己的需要显示不同的部分，主要针对移动端H5开发功能说明：页面上有tag1,tag2,tag3三个标签，点击某个标签时该标签的背景变红，其他标签背景变白，当前在tag3标签时浏览器返回会改变到tag2，在tag2时会改变到tag1，在tag1时不变，或者可以跳转到其他页面 测试 TAG1 TAG2 TAG3 结论：安卓未测试；iOS、Windows测试无效有效的方法记录需要被刷新的页面：window.addEventListener("pageshow", function(){ if(sessionStorage.getItem("need-refresh")){ location.reload(); sessionStorage.removeItem("need-refresh"); } });触发添加需要刷新条件的页面：sessionStorage.setItem("need-refresh", true); 参考文章备份在做移动端项目的时候经常遇到这样一个功能比如：返回后页面不刷新，一些失效的信息依然显示在页面上。这个问题在iphone手机上会出现，在Android手机上返回时会自动刷新（由于手机机器种类不多，无法做更多测试，欢迎补充）。为了解决这个问题实验了很多解决办法用计时器呀onload呀都不行，后来找到了一个方法pageshow。onpageshow 事件在用户浏览网页时触发。onpageshow 事件类似于 onload 事件，onload 事件在页面第一次加载时触发， onpageshow 事件在每次加载页面时触发，即 onload 事件在页面从浏览器缓存中读取时不触发，此外还有pagehide在不显示的时候触发。为了查看页面是直接从服务器上载入还是从缓存中读取，可以使用 PageTransitionEvent 对象的 persisted 属性来判断。window.addEventListener('pageshow', function(event) { console.log("PageShow Event " + event.persisted); console.log(event) })如果页面从浏览器的缓存中读取该属性返回 ture，否…

JavaScript 操作选中当前的li元素并给它添加select类
type: item
date: 2021-07-06T01:19:00+08:00
description: Title 这是菜单1 这是菜单2 这是菜单3 这是菜单4 这是菜单5 这是菜单6 这是菜单7 这是菜单8 效果：原文地址：https://www.cnblogs.com/liubeimeng/p/5509103.html

通过JS向剪切板写入数据
type: item
date: 2021-06-18T22:39:00+08:00
description: 6月12号晚上，辅助温春阳调试请假系统bug期间，留意到复制绑定密钥时自动复制的需求，想起两年前给电脑120网站配置复制自动复制QQ群号的场景，扒出了当年的代码： 电脑120 <!-- --> <marquee direction="left" scrollamount="7" scrolldelay="10" border="10" width="88%" > 欢迎加入服务群和大家交流计算机问题，群1：322935908，群2：181626714。期待在春暖花开的时节与大家在兰亭116重逢... </marquee> 使用方法 ①群 | ②群 关于我们 Copyright © 2019 电脑120 版权所有 然而没想到这段复制代码在其请假系统上针对iOS设备无论如何都不能生效，于是乎，和学长一起并肩开始了干到近凌晨3点的debug之旅。直接贴出结论吧，最后问题在“缩量”和“断点”等各种神仙调试过后仍然无法解决后由“增量”大法得以找出。问题核心在于iOS针对ajax异步请求做出了“非交互不得复制”的安全措施。（也就是说除非搞个复制按钮上去，否则你的数据就是“自动”进不了它的剪切板）解决方法：对单个页面指定ajax请求指定为同步。前些时候刚做出PHP上传功能，就有了落地需求-->多人同步调试CSS：于是乎：上传插件拿来开干，同时希望大家上传css文件后可以直接手动复制上传的文件地址，复制功能拿来开干：index.html： 上传CSS入口 上传CSS文件（不得超过2M）： upload.php：<?php // 后端验证防止上传超过2M的文件，定义最大值常量 define('MAX_SIZE',2097152); define('MuLu','css/'); // echo $_FILES; 返回Array // print_r($_FILES); // 返回这种结构： /* Array ( [userfile] => Array ( [name] => 1.jpg [type] => image/jpeg [tmp_name] => C:\Users\soarli\AppData\Local\Temp\php5449.tmp [error] => 0 [size] => 376151 ) ) */ // 只允许上传jpg格式的图片 // if ($_FILES['userfile']['type'] != 'image/jpeg' && $_FILES['userfile']['type'] != 'image/png' && $_FILES['userfile']['type'] != 'image/gif') { // echo " "; // exit; // } // 使用以下方法设置格式白名单更加直观 // switch ($_FILES['userfile']['type']){ // case 'image/jpeg': // break; // case 'image/png': // break; // case 'image/gif': // break; // default: echo " "; // exit; // } // 如果上传失败，根据$_FILES的error值判断报错类型并在前端提示 if ($_FILES['userfile']['error'] > 0) { switch ($_FILES['userfile']['error']) { case 1: echo " 上传失败，上传文件超过PHP配置文件限定值大小（后端的限制，由后端发现）！"; break; case 2: echo " 上传失败，上传文件超过HTML表单限定值大小（前端的限制，由后端发现）！"; break; case 3: echo " 上传失败（部分被上传）！"; break; case 4: echo " 上传失败，没有任何部分被上传！"; break; } exit; } // 后端判断上传文件的大小 if($_FILES['userfile']['size'] > MAX_SIZE){ echo " 上传失败，上传文件超过限定值大小（由后端大小检测模块发现）！"; exit; } // 只允许上传图片 $file_Extension_string = strrev($_FILES['userfile']['name']); // 从$_FILES数组中获取name字段并反转字符串 $file_Extension_array = explode('.',$file_Extension_string); // 以.号为分割拆分成为新的数组 $houZhui = strrev($file_Extension_a…

键盘键码值keyCode大全
type: item
date: 2021-06-16T21:57:00+08:00
description: 建模实习作业是做一个界面，果断上html+css+js：https://lab.soarli.top/web/html/calc/其中，js监听键盘输入通过document.onkeydown=function(event)方法实现，下面是关于keyCode的总结记录（内容来自互联网，已在文末放置参考资料链接）：js判定不能输入某个字母或符号οnkeydοwn=“if(event.keyCode==32) return false”字母和数字键的键码值(keyCode)（左侧）按键键码按键键码按键键码按键键码A65J74S83149B66K75T84250C67L76U85351D68M77V86452E69N78W87553F70O79X88654G71P80Y89755H72Q81Z90856I73R82048957数字键盘上键的键码值（右侧）按键键码按键键码按键键码0966102Enter1081977103-1092989104.1103999105/1114100*106 5101+107 F键键码值按键键码按键键码F1112F7118F2113F8119F3114F9120F4115F10121F5116F11122F6117F12123控制键键码值(keyCode)按键键码按键键码按键键码按键键码BackSpace8Esc27Right Arrow39-_189Tab9Spacebar32Dw Arrow40.>190Clear12Page Up33Insert45/?191Enter13Page Down34Delete46`~192Shift16End35Num Lock144[{219Control17Home36;:186\ 220Alt18Left Arrow37=+187]}221Cape Lock20Up Arrow38,<188'"222多媒体键码值按键键码音量加175音量减174停止179静音173浏览器172邮件180搜索170收藏171参考资料：https://blog.csdn.net/weixin_44476265/article/details/110531227https://www.cnblogs.com/zhulmz/p/11623685.htmlhttps://www.cnblogs.com/fubuki/p/9835581.html