-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontent.json
More file actions
1 lines (1 loc) · 88.4 KB
/
content.json
File metadata and controls
1 lines (1 loc) · 88.4 KB
1
{"meta":{"title":"qinxs小站","subtitle":"qinxs的个人博客","description":"Hexo + Volantis:用于记录工作中的技术总结、博客主题信息以及其他个人爱好","author":"qinxs","url":"https://7bxing.com","root":"/"},"pages":[{"title":"","date":"2021-09-16T07:15:09.487Z","updated":"2021-09-16T07:15:09.487Z","comments":false,"path":"404.html","permalink":"https://7bxing.com/404","excerpt":"","text":".box { display: flex; margin-top: -32px; justify-content: space-around; align-items: center; flex-wrap: wrap; } .alert-box { margin-top: 80px; padding-bottom: 20px; width: 220px; border: 1px solid #ccc; border-radius: 10px 10px 2px 2px; box-shadow: 0 0 5px #abc inset; text-align: center; } .alert-circle { margin-top: -70px; } .circle-background { fill: #FFF; stroke: #F4F1F1; } .circle-progress { fill: none; stroke: #43AEFA; stroke-dasharray: 439.8; stroke-dashoffset: 439.8; transition: stroke-dashoffset 1s linear; } 404 很抱歉,您访问的页面不存在 可能是输入地址有误或该地址已被删除 secs 稍后将带您进入首页 立即前往 !function() { var timeout = t = 10, circle = document.querySelector(\".circle-progress\"), text = document.querySelector(\".circle-sec-text\"); function changeSecond() { text.innerHTML = timeout < 10 ? '0' + timeout : timeout; timeout--; if (timeout < 0) { document.getElementById(\"home\").click(); } else { var e = Math.round(timeout / t * 439.8); circle.style.strokeDashoffset = e; setTimeout(function(){ changeSecond() }, 1000); } } setTimeout(changeSecond, 500); }();"},{"title":"","date":"2024-06-10T06:57:49.848Z","updated":"2024-06-10T06:57:49.848Z","comments":true,"path":"about/index.html","permalink":"https://7bxing.com/about/","excerpt":"","text":".zifuhua { margin: 0 auto; width: 12.8em; letter-spacing: normal; } .zifuhua button { display: none; } .zifuhua pre { border-radius: 1em !important; } .zifuhua code { font-family: \"Courier New\", Courier, monospace; } 写 给 自 己 教员尽管酷爱历史,但在谈到该如何读二十四史时,却提出了一个让人吃惊的告诫,他说:“一部二十四史大半是假的,所谓实录之类也大半是假的。但是,如果因为大半是假的就不读了,那就是形而上学。不读,靠什么来了解历史呢?反过来,一切信以为真,书上的每句话,都被当作证实历史的信条,那就是历史唯心论了。正确的态度是用马克思主义的立场、观点和方法,分析它,批判它。把颠倒的历史颠倒过来。一部二十四史,写符瑞、迷信的文字,就占了不少,各朝各代的史书里都有。像《史记·高祖本纪》和《汉书·高帝纪》里,都写了刘邦斩白蛇的故事,又写了刘邦藏身的地方,上面常有云气,这一切都是骗人的鬼话。每一部史书,都是由继建的新王朝的臣子奉命修撰的,凡关系到本朝统治者不光彩的地方,自然不能写,也不敢写。如宋太祖赵匡胤本是后周的臣子,奉命北征,走到陈桥驿,竟发动兵变,篡夺了周的政权。宋臣薛居正等撰写的《旧五代史》里却说,他是黄袍加身,是受将士们‘擐甲将刃’、‘拥迫南行’被迫的结果,并把这次政变解释成是‘知其数而顺乎人’的正义行为。同时,封建社会有一条‘为尊者讳’的伦理道德标准,凡皇帝或父亲的恶性,或是隐而不书,或是把责任推给臣下或他人。譬如,宋高宗和秦桧主和投降,实际上,主和的责任不全在秦桧,起决定作用的是幕后的高宗赵构,这在《宋史·奸臣传》的《秦桧传》里,是多少有所反映的。特别是洋洋4000万言的二十四史,写的差不多都是帝王将相,人民群众的生活情形、生产情形,大多是只字不提,有的写了些,也是笼统地一笔带过,目的是谈如何加强统治的问题。有的更被歪曲地写了进去,如农民反压迫、剥削的斗争,一律被骂成十恶不赦的‘匪’、‘贼’、‘逆’。这是最不符合历史真实的假话。” 教员还说:“搞文学史的人,一定要好好地读历史,要认真地读《资治通鉴》、二十四史。但要用马克思主义的立场、观点和方法读,否则就读不好,弄不清历史发展的头绪。要明白,所谓正史,那是指合乎封建统治阶级要求的‘正’,所以,书里总是给统治阶级制造迷信,说许多天命、符瑞之类的骗人的鬼话。所以书里要‘为尊者讳’,并把反抗他们起义的农民群众骂做‘匪’。其实,有些稗官野史由于不是官方修撰的,有时倒会写出点实情。所以,二十四史要读,《资治通鉴》要读,稗官野史、笔记小说也要读。历史书籍要多读,多读一本,就多了一份调查研究。读得多了,又有正确的立场和观点,进行判断和评论,就较少失误,这是辩证法,也是把被颠倒的历史再颠倒过来的重要的条件。” 摘抄自:知乎回答"},{"title":"所有分类","date":"2020-05-16T07:29:05.923Z","updated":"2020-05-16T07:29:05.923Z","comments":true,"path":"categories/index.html","permalink":"https://7bxing.com/categories/","excerpt":"","text":""},{"title":"","date":"2020-07-17T11:08:34.000Z","updated":"2020-07-17T11:08:34.000Z","comments":false,"path":"cover/index.html","permalink":"https://7bxing.com/cover/","excerpt":"","text":".center { display: block; text-align: center; line-height: 1.5; } .cover { pointer-events: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; margin-top: 1em; } @media screen and (min-width: 500px) { .cover { margin: -24px; margin-top: 1em; width: calc(100% + 48px); } } .icon-color { color: #dd2e44; } .hitokoto, #hitokoto { font-size: 1.5em; background: linear-gradient(to right, #f73434, #562ef4); -webkit-background-clip: text; color: transparent; letter-spacing: normal; white-space: nowrap; } 一言: D 获取中... 🍁 欢迎来到qinxs的个人博客 🍁 (function(){ if (!(window.hitokoto instanceof Object)) { document.getElementById('hitokoto').innerText = window.hitokoto; } })();"},{"title":"","date":"2020-08-30T11:54:21.000Z","updated":"2020-08-30T11:54:21.000Z","comments":false,"path":"donate/index.html","permalink":"https://7bxing.com/donate/","excerpt":"","text":".article div.btns a, .md div.btns a { margin-top: 0 !important; } .article div.btns.around, .md div.btns.around { justify-content: space-evenly !important; } 打 赏 赞 助 Donate如果我的文章或者作品有幸能帮助到您,欢迎对我打赏捐助。您的肯定将是我最大的动力~ 微信 支付宝 感谢. 😏"},{"title":"","date":"2020-05-16T10:30:00.000Z","updated":"2020-08-31T05:13:25.000Z","comments":true,"path":"friends/index.html","permalink":"https://7bxing.com/friends/","excerpt":"🎉友链","text":"🎉友链 .effect { display: inline; padding: 10px 20px; border-radius: 20px; font-family: \"Arial Rounded MT Bold\", \"Helvetica Rounded\", Arial, sans-serif; font-size: 2em; letter-spacing: .2em; color: red; text-shadow: 0 8px 9px #c4b59d, 0px -2px 1px #fff; font-weight: bold; background: linear-gradient(to bottom, #ece4d9 0%,#e9dfd1 100%); } 交友链接Git-API辅助工具特别感谢失效链接各位大佬想交换友链的话可以在下方留言哦~ 1234- name: qinxs url: https://7bxing.com avatar: https://gcore.jsdelivr.net/gh/qinxs/cdn-assets@master/img/avatar.png tags: [技术总结, 各种折腾] 颜色仅供参考。 站点要求:内容合法、非营利性。 此数据供issues方式友链使用 12345"title": "qinxs","url": "https://7bxing.com","avatar": "https://gcore.jsdelivr.net/gh/qinxs/cdn-assets@master/img/avatar.png","screenshot": "https://gcore.jsdelivr.net/gh/qinxs/cdn-assets@master/img/screenshot.png","description": "技术总结, 各种折腾" 7bu图床 压缩图片 此友链页面参照了xaoxuuHuanhao的博客布局与内容,特此感谢~以下博友网站已失效,若修复,请留言恢复~HuanhaoXu’s BlogThrower的博客乌克兰老母居"},{"title":"","date":"2020-08-30T11:54:21.000Z","updated":"2020-08-30T11:54:21.000Z","comments":true,"path":"lab/index.html","permalink":"https://7bxing.com/lab/","excerpt":"","text":"实 验 室 测试项目 字体测试文本abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 12345678901234567890123456 壹贰叁肆伍陆柒捌玖拾壹贰叁 !@#$%^&*()_+{}|:"<>?-=[]\\;',./ 1ilIL0OoOygqaA 说明 此页面仅供测试使用"},{"title":"","date":"2020-07-22T10:35:58.000Z","updated":"2020-07-22T10:35:58.000Z","comments":true,"path":"message/index.html","permalink":"https://7bxing.com/message/","excerpt":"","text":".center { display: block; text-align: center; } .milky { padding: 10px 20px; border-radius: 20px; font-family: \"Arial Rounded MT Bold\", \"Helvetica Rounded\", Arial, sans-serif; font-size: 2em; letter-spacing: .1em; color: red; text-shadow: 0 8px 9px #c4b59d, 0px -2px 1px #fff; font-weight: bold; background: linear-gradient(to bottom, #ece4d9 0%,#e9dfd1 100%); } #lyxz { margin: 0 auto; width: 100%; } #lyxz fieldset { margin: 0 auto; width: 100%; padding: 5px 10px 10px; border: #06c dashed 1px; } @media screen and (max-width: 500px) { #lyxz fieldset { font-size: .875em; } } #lyxz legend { font-size: 1.5em; font-weight: 400; color: #06c; letter-spacing: .2em; } 🍭留言板 留言须知 对此博客有任何疑问,欢迎留言 如果你的留言需要回复,建议留下真实邮箱"},{"title":"所有标签","date":"2020-10-07T11:36:08.055Z","updated":"2020-10-07T11:36:08.055Z","comments":true,"path":"seek/index.html","permalink":"https://7bxing.com/seek/","excerpt":"","text":"article#tag, article#arc { padding-top: 36px !important; padding-bottom: 12px !important; }"},{"title":"所有标签","date":"2020-09-02T06:35:32.645Z","updated":"2020-09-02T06:35:32.645Z","comments":true,"path":"tags/index.html","permalink":"https://7bxing.com/tags/","excerpt":"","text":""},{"title":"","date":"2020-06-23T12:16:45.000Z","updated":"2020-06-23T12:16:45.000Z","comments":true,"path":"more/CatchTheCat/index.html","permalink":"https://7bxing.com/more/CatchTheCat/","excerpt":"","text":"游戏规则 点击小圆点,围住小猫。 你点击一次,小猫走一次。 直到你把小猫围住(赢),或者小猫走到边界并逃跑(输)。"},{"title":"","date":"2020-07-26T06:56:21.000Z","updated":"2020-07-26T06:56:21.000Z","comments":false,"path":"more/operations/index.html","permalink":"https://7bxing.com/more/operations/","excerpt":"","text":"本 站 维 护 所有相关工具及维护项 静态化工具 – Hexo 新建文章 1hexo new "shell猜数字游戏" 新建页面 一级页面 1hexo new page "test" 二级页面 1hexo new page --path more/operations/index "本站维护" 系列文章 1234- 复制之前的系列文章,然后更改目录名,只保留第一篇文章- 更改索引及文章的font-mater(包括group名、sidebar的widget)- 添加widget和菜单- 后续复制第一篇文章,更改内容即可 启动、清理、生成、部署、查看 12345678910hexo shexo clhexo ghexo dhexo list <type># Available types: page, post, route, tag, category 博客主题 – Volantisfront-matter 标签插件 组索引 DIY 玩法 关闭评论区: comments: false加密: password: 123456 内容加速 – CDN推荐使用格式: https://gcore.jsdelivr.net/gh/用户名/储存库名@分支名(版本号)/文件(目录)例:https://gcore.jsdelivr.net/gh/qinxs/cdn-assets@master/img/avatar.png简写(不推荐):https://gcore.jsdelivr.net/gh/qinxs/cdn-assets/img/avatar.png 文件更新由于存在缓存问题,所以要带上新的版本号(Tag 推送后,GitHub 自动 release)如:https://gcore.jsdelivr.net/gh/qinxs/cdn-assets@1.3.8/css/first.css直接用最近的 Commit ID(前8位)如:https://gcore.jsdelivr.net/gh/qinxs/cdn-assets@f415c64d/css/first.css 1https://gcore.jsdelivr.net/gh/qinxs/cdn-assets@master/img/md/ 详细说明: https://www.jsdelivr.com/features#gh 评论系统 – Valine-Admin批量管理Leancloud 菜单: 存储 -> 结构化数据 -> Comment 可视化管理Valine-Admin: https://plgl.7bxing.com/ 自动唤醒leancloud-self-wake: https://www.aimtao.net/slef-wake-leancloud/腾讯云函数: https://console.cloud.tencent.com/ (配置说明) 其他公告内容: _config.volantis.yml 中announce模块阿里图标: https://www.iconfont.cn/字体图标: https://dh.xiaokang.me/font5/图标案例: http://www.fontawesome.com.cn/examples/字体动画: https://www.51qianduan.com/article/view/4111.html加密模块: https://github.com/MikeCoder/hexo-blog-encrypt/blob/master/ReadMe.zh.md头像上传: http://cn.gravatar.com/Emoji: https://emojixd.com/"},{"title":"","date":"2020-05-26T15:12:50.000Z","updated":"2020-05-26T15:12:50.000Z","comments":true,"path":"more/tools/index.html","permalink":"https://7bxing.com/more/tools/","excerpt":"","text":"工 具 书 签 该内容已移至 网址导航"},{"title":"","date":"2020-07-26T06:56:21.000Z","updated":"2020-07-26T06:56:21.000Z","comments":false,"path":"series/bywz/index.html","permalink":"https://7bxing.com/series/bywz/","excerpt":"","text":"博 友 文 章 博友的优秀文章 🍁 ES6 快速入坑 正向、反向代理区别 探究网页资源究竟是如何阻塞浏览器加载的"},{"title":"","date":"2020-07-16T04:57:35.000Z","updated":"2020-07-28T09:56:11.000Z","comments":true,"path":"series/docker/index.html","permalink":"https://7bxing.com/series/docker/","excerpt":"","text":"说明 系列内容来源于网络,经自己实践后总结于此 操作环境: CentOS7.x + Docker19.x 更新中…"},{"title":"Docker简介","date":"2020-07-28T09:56:06.000Z","updated":"2020-07-28T09:56:11.000Z","comments":true,"path":"series/docker/Introduction/index.html","permalink":"https://7bxing.com/series/docker/Introduction/","excerpt":"","text":"本文来源: https://www.runoob.com/docker/docker-tutorial.html Docker 是什么? Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。 容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。 Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版),我们用社区版就可以了。 Docker的应用场景 Web 应用的自动化打包和发布。 自动化测试和持续集成、发布。 在服务型环境中部署和调整数据库或其他的后台应用。 从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境。 Docker 的优点Docker 是一个用于开发,交付和运行应用程序的开放平台。Docker 使您能够将应用程序与基础架构分开,从而可以快速交付软件。借助 Docker,您可以与管理应用程序相同的方式来管理基础架构。通过利用 Docker 的方法来快速交付,测试和部署代码,您可以大大减少编写代码和在生产环境中运行代码之间的延迟。 快速,一致地交付您的应用程序Docker 允许开发人员使用您提供的应用程序或服务的本地容器在标准化环境中工作,从而简化了开发的生命周期。 容器非常适合持续集成和持续交付(CI / CD)工作流程,请考虑以下示例方案: 您的开发人员在本地编写代码,并使用 Docker 容器与同事共享他们的工作。 他们使用 Docker 将其应用程序推送到测试环境中,并执行自动或手动测试。 当开发人员发现错误时,他们可以在开发环境中对其进行修复,然后将其重新部署到测试环境中,以进行测试和验证。 测试完成后,将修补程序推送给生产环境,就像将更新的镜像推送到生产环境一样简单。 响应式部署和扩展Docker 是基于容器的平台,允许高度可移植的工作负载。Docker 容器可以在开发人员的本机上,数据中心的物理或虚拟机上,云服务上或混合环境中运行。 Docker 的可移植性和轻量级的特性,还可以使您轻松地完成动态管理的工作负担,并根据业务需求指示,实时扩展或拆除应用程序和服务。 在同一硬件上运行更多工作负载Docker 轻巧快速。它为基于虚拟机管理程序的虚拟机提供了可行、经济、高效的替代方案,因此您可以利用更多的计算能力来实现业务目标。Docker 非常适合于高密度环境以及中小型部署,而您可以用更少的资源做更多的事情。 Docker的未来发展趋势体现 Docker 相比虚拟机的优势 Docker 是 虚拟化、Linux、云服务的集大成者 Docker 对Windows、Linux、Mac操作系统的兼容 相关链接Docker 官网:https://www.docker.comDocker Hub 官网:https://hub.docker.com/Github Docker 源码:https://github.com/docker/docker-ce"},{"title":"快速部署一个Docker服务","date":"2020-07-15T16:56:14.000Z","updated":"2020-07-15T16:56:14.000Z","comments":true,"path":"series/docker/Quick-deploy/index.html","permalink":"https://7bxing.com/series/docker/Quick-deploy/","excerpt":"","text":"简短说明 Docker 安装替换镜像源(镜像加速)Hello world"}],"posts":[{"title":"Win32 API编程——前言","slug":"Win32-API编程——前言","date":"2022-02-26T11:43:21.000Z","updated":"2022-02-26T11:43:21.000Z","comments":true,"path":"posts/67bdf631/","link":"","permalink":"https://7bxing.com/posts/67bdf631/","excerpt":"Windows 编程中使用的一些基本术语和编码约定","text":"Windows 编程中使用的一些基本术语和编码约定 什么是Win32 API?简单来讲,就是微软为了保护操做系统的安全性和稳定性,不容许运行在用户层的进程随意操控系统内核,而是必须按照必定方式。咱们用户层要与系统内核层交互(好比对内存、进程操做),只能经过调用Windows内核层提供的接口函数,也就是Win32API来操控。这些API以DLL(动态连接库)的形式保存(在SYSTEM32文件夹中,你能够发现许多DLL文件),最经常使用的是kernel32.dll、user32.dll和gdi32.dll。 全部基于NT内核(XP到Win10都是基于NT内核开发)的Windows API均可以称为Win32,即使是64位系统,也用这个名称,由于64位系统是彻底兼容32位程序的(32位系统不能彻底兼容16位程序),因此你能够看到这些DLL名称都有个”32”的后缀。那咱们用C/C++写程序,没用到Win32,怎么也可以执行分配内存,打开进程等操做呢?实际上在Windows系统上的C/C++的运行库内部也是封装了Win32API。进一步说,全部运行在Windows用户层的程序必须得调用Win32API。 Windows采用分层结构,大体来讲就是(用户层->内核层->硬件抽象层->硬件层),每一层使用下一层提供的接口来与下一层进行交互。咱们平常使用的应用程序都是运行在用户层,经过调用内核层提供的接口(Win32API)来与内核层交互,而后系统会请求中断(调用nt*.dll函数),调用内核中的中断服务程序,进而对硬件抽象层进行操做,从而实现用户到硬件的交互。固然,也有许多程序是运行在内核层的(好比驱动程序),Windows没有公布用于内核层编程的源码,可是提供了WDK(Windows Driver Kit)来给程序员编写驱动程序,驱动程序可经过内核API,编写中断服务例程来操控硬件抽象层。 为何要学Win32 API?如今用于windows平台的程序开发方式突飞猛进,种类繁多,好比使用Dephi、WPF、Qt等,开发效率远高于使用Win32 API开发,那为何还要学习使用Win32 API开发呢? 理解Windows程序底层运行机制。 帮助学习Windows上其余的编程语言、平台。 实现其余库没有提供的高级功能,好比修改其余进程内存等。 开始前你必须知道语言基础: C/C++ 开发平台: Visual Studio 编码格式:Unicode 为何区分编码格式?windows程序的编码格式分为两种:ANSI(MBCS:多字节字符集)和Unicode,Windows会按程序的编码格式解码字符。 ANSI:根据系统当前设置的语言采用不一样编码,好比系统语言设置为简体中文,则ANSI采用GBK编码。 Unicode:统一的字符集,在全部系统中均相同,每一个字符占用两个字节。 为何使用Unicode? Windows NT是使用Unicode开发的,调用API时要把ANSI字符转换成Unicode字符,直接使用Unicode能够提升运行效率。 使你的程序在不一样语言的系统上运行时不会出现乱码。 一些API只能处理Unicode字符。 怎么设置Unicode?修改编译器设置 项目->属性->高级->字符集:使用Unicode字符集 设置后观察 项目->属性->C/C++->命令行:看到两个选项 /D “_UNICODE” /D “UNICODE”,说明已成功设置为Unicode编码,不然看到选项 /D “_MBCS”,说明使用的是MBCS编码。 其中_UNICODE定义在C运行库的头文件中,UNICODE定义在Windows的头文件中。 尽可能使用Windows数据类型在平时使用C/C++编程时,咱们都使用C/C++标准库提供的数据类型,好比char,short,int,long int等等,可是在使用Windows API编程时,咱们应该尽可能使用Windows提供的数据类型,由于Win32 API函数都是使用Windows数据类型编写的,因此你必需要认识它。事实上,这些Windows数据类型都是在windows头文件中对C/C++库原生类型的宏定义,本质上并没有差异。下面列举常见的Windows数据类型。 类型前缀c=const 常量 u=unsigned 无符号 p=pointer 指针 h=handle 句柄 w=word 字 dw=double word 双字 sz=strinszg terminated with a zero 以0结尾的字符串 lp=long pointer 长指针 函数后缀A=ansi字符 参数接受ANSI字符 W=wide宽字符 参数接受Unicode字符 EX=expand 扩展版函数,在原函数基础上增长某些新的特性 Windows类型举例1234567891011typedef int INT;typedef int BOOL;typedef unsigned int UINT;typedef unsigned short WORD;typedef WORD near *PWORD;typedef WORD far *LPWORD; 其余定义详见 <minwindef.h>near指针NP,far指针FP,long指针LP,是为了兼容16位程序,在32位编程中都为P(32位指针) 在字符串前添加 L标志 该字符串将按宽字符(Unicode)编码 TEXT、__TEXT(winnt.h内定义的宏) 若是 UNICODE被定义,则在字符串前添加L _T、__T、_TEXT(tchar.h内定义的宏) 若是 _UNICODE被定义,则在字符串前添加L 12345#ifdef UNICODE#define __TEXT(x) L##x#else#define __TEXT(x) x#endif 带T前缀的数据类型 根据是否定义UNICODE选择使用宽/窄字符 12345#ifdef UNICODE typedef wchar_t TCHAR#else typedef char TCHAR#endif 其他原文出处:博客园 Celng更多资料:Win32平台数据类型总结Windows编码约定Win32基本知识总结","categories":[{"name":"IT技术","slug":"IT技术","permalink":"https://7bxing.com/categories/IT%E6%8A%80%E6%9C%AF/"},{"name":"Win32编程","slug":"IT技术/Win32编程","permalink":"https://7bxing.com/categories/IT%E6%8A%80%E6%9C%AF/Win32%E7%BC%96%E7%A8%8B/"}],"tags":[{"name":"Win32术语及编码约定","slug":"Win32术语及编码约定","permalink":"https://7bxing.com/tags/Win32%E6%9C%AF%E8%AF%AD%E5%8F%8A%E7%BC%96%E7%A0%81%E7%BA%A6%E5%AE%9A/"}]},{"title":"【原创作品】Ease Bookmarks","slug":"Ease-Bookmarks","date":"2021-12-27T13:01:23.000Z","updated":"2021-12-27T13:01:23.000Z","comments":true,"path":"posts/beb3fd2a/","link":"","permalink":"https://7bxing.com/posts/beb3fd2a/","excerpt":"Ease-Bookmarks,是一款简单易用的书签管理器为了替代浏览器原有书签栏而编写的扩展","text":"Ease-Bookmarks,是一款简单易用的书签管理器为了替代浏览器原有书签栏而编写的扩展 在此基础上,尽可能满足各类 书签使用习惯 用户的需求 主要功能修改书签的默认打开方式 对书签的各种基本操作(编辑、删除、移动等) 书签多列显示 快捷键支持 在未使用本扩展时,不占用后台 另外,本扩展对 JS 小书签 进行了特别支持~ 更新日志:ChangeLog.md 相关截图 使用快捷键打开/关闭 本扩展默认快捷键是 Ctrl + Q,你可以在如下管理页面进行修改: Chrome:chrome://extensions/shortcuts Edge:edge://extensions/shortcuts 功能键 Ctrl:在 当前标签/新标签 打开页面 Shift:是否在后台打开页面 自定义 别名(书签栏和其他书签,其他语言可能会需要) 自定义样式(popup 页面,DOM 结构可在 header 区域 右键 -> 检查 查看) 资源链接 如果觉得有用的话,可以在谷歌商店给个五星,GitHub 给个 Star,感谢~","categories":[{"name":"原创作品","slug":"原创作品","permalink":"https://7bxing.com/categories/%E5%8E%9F%E5%88%9B%E4%BD%9C%E5%93%81/"}],"tags":[{"name":"书签管理器","slug":"书签管理器","permalink":"https://7bxing.com/tags/%E4%B9%A6%E7%AD%BE%E7%AE%A1%E7%90%86%E5%99%A8/"}]},{"title":"从AI导出Web的SVG的最佳设置","slug":"从AI导出Web的SVG的最佳设置","date":"2021-09-06T13:03:49.000Z","updated":"2021-09-06T13:03:49.000Z","comments":true,"path":"posts/f28f8693/","link":"","permalink":"https://7bxing.com/posts/f28f8693/","excerpt":"偶尔需要自己动手画 SVG,但每次都忘记导出参数…特此记录","text":"偶尔需要自己动手画 SVG,但每次都忘记导出参数…特此记录 SVG 配置文件 SVG 1.0:所有现代台式机和移动浏览器都支持 SVG 1.1,因此请不要选择此选项。 SVG 1.1:您几乎总是会想要这个。 SVG Tiny / Basic:这是用于移动设备的 SVG 的子集。只有少数设备支持 SVG Tiny,而不支持完整规格,因此请使用 SVG 1.1。 注意:SVG Tiny 不会减小文件大小,它只是 SVG 的一个子集,足以满足低处理能力的设备。它将丢弃渐变,不透明度,嵌入的字体和过滤器。ErikDahlström 说:所有 SVG 1.1 完整查看器都应该能够显示所有 SVG 1.1 Tiny / Basic 内容(根据规范),并且可能还会显示 Illustrator 产生的所有 SVG 1.2 Tiny 内容。 字体文字 注意:如果图像中没有任何文本,则此设置无关紧要。 Adobe CEF:切勿在打算在浏览器中显示它时使用此选项。据我所知,这是 Adobe 在 SVG 文件中嵌入字体的方式,仅 Adobe 的 SVG 查看器插件才支持。 SVG:这将字体嵌入为 SVG,Firefox 不支持,但是如果您打算仅支持移动设备(通常运行 webkit),则是一个不错的选择。 创建轮廓:除非您有大量文本,否则您通常会希望执行此操作。如果您有大量文本,则需要在 WOFF 中嵌入字体,但是您必须手动执行此操作。 子集化 无:如果您不在乎用户计算机上的字体会退回到其他字体,则此选项将取消以前的设置并且不会嵌入任何字体。 仅使用字形:大多数情况下,如果您选择嵌入字体,则需要使用此字形。它仅嵌入使用的字符,因此不会增加文件大小。 [其余子集]:这很清楚,您可以选择包含整个字体或它的子集。仅当 SVG 是动态的并且文本可能会根据用户输入而更改时,此选项才有用。 选项图像位置:仅当您包含位图图片时才重要 嵌入:通常这就是您想要的,它会将图像编码为数据 uri,因此您只需上传一个文件,而不是带有其配套位图图像的 svg 文件。 链接:仅当您有多个引用一个位图文件的 svg 文件时才使用它(因此,每次渲染 svg 文件时都不会下载该文件)。 请注意,如果通过 <img> 标记显示 SVG,则不会显示链接的位图图像,因为 img 不允许加载外部资源。此外:webkit 有一个错误,即使您将其嵌入,也不会在 svg 文件中显示位图图像。简而言之:<svg> 如果您打算嵌入或链接位图图像,请使用纯标签,请勿使用 <img>。 保留 Illustrator 编辑功能 我更喜欢将.ai 文件另存为我的源映像,并且将 SVG 文件视为 Export for web 功能。这样,您就可以专注于减小文件大小,并拥有具有所有编辑功能的矢量文件的原始副本。所以不要选择这个。 高级选项CSS 属性 一般选择样式属性(偶尔选择样式元素) 小数位数 默认设置3为正常设置,您几乎可以忽略它。 如果图像比较复杂,将该值设为 1(输出体积会大大减少),然后观察显示是否正常 但是,如果您的路径真的很复杂,并且有很多点,请将此设置降低到 1 或什至 0 会大大减小文件大小。但是您必须小心,因为贝塞尔曲线段对此设置非常敏感,并且它们似乎有些变形。因此,如果降低此设置,请始终确保它在浏览器中看起来可以接受。 编码方式 字符编码背后的解释是相当技术性的,仅涉及带文本的 svg 文件。您最可能需要的编码是 UTF-8,除非您知道自己在做什么,否则不要更改它。 针对 Adobe SVG Viewer 进行优化 从浏览器本身不支持 SVG 开始,Adobe SVG Viewer 便是一个浏览器插件。我不知道它的作用,但这无关紧要,请不要检查。 包括切片数据 这会将元数据膨胀添加到您的 SVG 文件中,除非您打算稍后在 Illustrator 中打开 SVG 文件并找到您的切片(如果有),请不要选中此选项 包括 XMP 有关文件的更多元数据,您可以 在 XMP 上阅读。不要检查这个 输出更少的 <tspan> 元素 如果您没有文字,则将显示为灰色。SVG 不支持字距调整表,因此,某些字符序列似乎间隔太远,即 AVA。Illustrator 通过添加 tspan 元素和微调字符位置来解决该问题。这增添了几分膨胀到文件,除非你更关心的不是文字的外观文件大小不查这个。 在路径文字上使用 SVG <textPath> 元素 如果您的路径上没有文字,则该字段将显示为灰色。在将文本放置在路径上时,浏览器的变化往往很大,因此 Illustrator 尝试通过对字符应用旋转和位置而不是将工作留给浏览器来提供帮助。除非您更关心文件的大小而不是文本的外观,否则请不要选中此选项。 最终图 其他 生成的 SVG 可以能冗余 dom,查看源代码删除 SVG 图标 可以在浏览器开发者工具中 编辑 DOM 贝塞尔曲线 AI 操作 12Ctrl + 左键 选择一部分(文字转换为轮廓后)Ctrl + 0 大小适应窗口","categories":[{"name":"未分类","slug":"未分类","permalink":"https://7bxing.com/categories/%E6%9C%AA%E5%88%86%E7%B1%BB/"}],"tags":[{"name":"Illustrator","slug":"Illustrator","permalink":"https://7bxing.com/tags/Illustrator/"}]},{"title":"正则表达式","slug":"正则表达式","date":"2021-07-18T15:10:00.000Z","updated":"2021-07-18T15:10:00.000Z","comments":true,"path":"posts/2f57a694/","link":"","permalink":"https://7bxing.com/posts/2f57a694/","excerpt":"正则表达式(Regular Expression)是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。","text":"正则表达式(Regular Expression)是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。 给定一个正则表达式和另一个字符串,我们可以达到如下的目的: 给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”); 可以通过正则表达式,从字符串中获取我们想要的特定部分。 历史: 维基百科 - 正则表达式 基础语法正则表达式30分钟入门教程 菜鸟教程: 正则表达式 - 语法 优先权 优先权 运算符 描述 最高 \\ 转义符 高 (), (?:), (?=), [] 圆括号和方括号 中 *, +, ?, {n}, {n,}, {n,m} 限定符 低 ^, $, \\任何元字符、任何字符 定位点和序列(即:位置和顺序) 最低 | 替换,”或” 操作字符具有高于替换运算符的优先级,使得”m|food”匹配”m”或”food”。若要匹配”mood”或”food”,请使用括号创建子表达式,从而产生”(m|f)ood”。 正则性能优化正则是个很好用的利器,如果使用得当,如有神助,能省掉大量代码。当如果使用不当,则是处处埋坑。所以如何写一个高性能的正则表达式就尤为重要。 避免量词嵌套举个简单的例子对比: 我们使用正则表达式 /a*b/ 去匹配字符串 aaaaa 我们将以上正则修改成 /(a*)*b/ 去匹配字符串 aaaaa 上两个正则的基本执行步骤可以简单认为是: 贪婪匹配 回溯 直至发现匹配失败 但令人惊奇的是,第一个正则的从开始匹配到匹配失败这个过程只有 14 步。而第二个正则却有 128 步之多。可想而知,嵌套量词会大大增加正则的执行过程。因为这其中进行了两层回溯,这个执行步骤增加的过程就如同算法复杂度从 O(n)上升到 O(n^2)的过程一般。 所以,面对量词嵌套,我们需作出适当的转化消除这些嵌套: 12(a*)* <=> (a+)* <=> (a*)+ <=> a* (a+)+ <=> a+ 使用非捕获组NFA 正则引擎中的括号主要有两个作用: 主流功能,提升括号中内容的运算优先级 反向引用 反向引用这个功能很强大,强大的代价是消耗性能。所以,当我们如果不需要用到括号反向引用的功能时,我们应该尽量使用非捕获组,也就是: 12// 捕获组与非捕获组 () => (?:) 分支优化分支也是导致正则回溯的重要原因,所以,针对正则分支,我们也需要作出必要的优化。 a. 减少分支数量 首先,需要减少分支数量。比如不少正则在匹配 http 和 https 的时候喜欢写成: 1/^http|https/ 其实上面完全可以优化成: 1/^https?/ 这样就能减少没必要的分支回溯 b. 缩小分支内的内容 缩小分支中的内容也是很有必要的,例如我们需要匹配 this 和 that ,我们也许会写成: 1/this|that/ 但上面其实完全可以优化成: 1/th(?:is|at)/ 有人可能认为以上没啥区别,实践出真知,让我们用以上两个正则表达式去匹配一下 that。 我们会发现第一个正则的执行步骤比第一个正则多两步,那是因为第一个正则的回溯路径比第二个正则的回溯路径更长了,最终导致执行步骤变长。 锚点优化在能使用锚点的情况下尽量使用锚点。大部分正则引擎会在编译阶段做些额外分析, 判断是否存在成功匹配必须的字符或者字符串。类似 ^、$ 这类锚点匹配能给正则引擎更多的优化信息。 例如正则表达式 hello(hi)?$ 在匹配过程中只可能从字符串末尾倒数第 7 个字符开始, 所以正则引擎能够分析跳到那个位置, 略过目标字符串中许多可能的字符, 大大提升匹配速度。 RegexBuddy 性能优化完整版: 腾讯技术工程的知乎回答 匹配中文\\w 匹配的仅仅是中文,数字,字母,对于国人来讲,仅匹配中文时常会用到,见下 中文汉字: 1匹配中文字符的正则表达式: [\\u4e00-\\u9fa5] 双字节(包含中日韩等): 1匹配双字节字符(包括汉字在内):[^\\x00-\\xff] 相关资源正则可视化 - regexper 在线测试 - regexr 性能调试工具 - RegexBuddy 最全的常用正则表达式大全","categories":[{"name":"IT技术","slug":"IT技术","permalink":"https://7bxing.com/categories/IT%E6%8A%80%E6%9C%AF/"},{"name":"正则表达式","slug":"IT技术/正则表达式","permalink":"https://7bxing.com/categories/IT%E6%8A%80%E6%9C%AF/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/"}],"tags":[{"name":"正则表达式","slug":"正则表达式","permalink":"https://7bxing.com/tags/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/"}]},{"title":"✳️ Vi/Vim使用备忘","slug":"Vi、Vim使用备忘","date":"2020-10-23T06:37:53.000Z","updated":"2020-10-25T06:21:15.000Z","comments":true,"path":"posts/b04c6f46/","link":"","permalink":"https://7bxing.com/posts/b04c6f46/","excerpt":"vi 是 linux 的内置文本编辑器事实上,所有的 Unix Like 系统都会内建 vi文本编辑器 vim 则是 vi编辑器 的增强版本(支持语法高亮,方便程序设计,习惯上也称为vi),使用更广泛","text":"vi 是 linux 的内置文本编辑器事实上,所有的 Unix Like 系统都会内建 vi文本编辑器 vim 则是 vi编辑器 的增强版本(支持语法高亮,方便程序设计,习惯上也称为vi),使用更广泛 工作模式vi编辑器 有命令模式、输入模式、底线命令模式我们通过 vi 文件名 的形式打开(或新建)文件进行编辑,如图所示: 结合图示介绍 vi编辑器 的三种工作模式,相当于图形软件窗口中的不同界面,不同的模式中能够对文件进行的操作也不相同 1)命令模式(Command mode):启动vi编辑器后默认进入命令模式,该模式中主要完成如光标移动、字符串查找,以及删除、复制、粘贴文件内容等相关操作 2)输入模式(Insert mode):该模式中主要的操作就是录入文件内容,可以对文本文件正文进行修改、或者添加新的内容。处于输入模式时,vi编辑器的最后一行会出现 -- INSERT -- 的状态提示信息 3)底线命令模式(Last line mode):该模式中可以设置vi编辑环境、保存文件、退出编辑器,以及对文件内容进行查找、替换等操作。处于末行模式时,vi编辑器的最后一行会出现冒号 : 提示符 i、a、o等插入模式具体区别插入模式则用来向文本中添加内容的,常用的是 i 和 o i 在光标所在字符前开始输入文字并进入插入模式 o (字母 o) 在光标所在行的下面单独开一新行来输入文字并进入插入模式i 是在光标所在的字符之前插入需要录入的文本。I 是在光标所在行的行首插入需要录入的文本。 a 是在光标所在的字符之后插入需要录入的文本。A 是在光标所在行的行尾插入需要录入的文本。 o 是光标所在行的下一行行首插入需要录入的文本。O 是光标所在行的上一行行首插入需要录入的文本。 补充说明: 宏录制详细操作特别地,命令模式按 q 会进入宏录制非insert模式下输入 q 停止宏的录制 此功能不是特别常用,但我们需要知道触发后怎么退出 在命令模式下按下q键盘(此时左下角有“recording”这个标识) 选择a-z或0-9中任意一个作为缓冲器的名字,准备开始录制宏 正常的操作,此次所有的操作都会被记录在上一步中定义的缓冲器中 在非insert模式下输入q停止宏的录制 使用@ + 第二步中定义的缓冲器的名字即可 命令模式的基本操作光标移动 复制、粘贴、删除 文件内容查找 撤销编辑及保存退出 保存文件及退出vi编辑器 打开新文件或读入其他文件内容 文件内容替换 其他常用切换到后台 CTRL+Z 挂起进程并放入后台 jobs 显示当前暂停的进程 bg %N 使第N个任务在后台运行(%前有空格) fg %N 使第N个任务在前台运行 默认 bg,fg 不带 %N 时表示对最后一个进程操作! 多窗口操作水平方向 :sp [filename]垂直方向 :vs [filename] 窗口切换 先按Ctrl+w,然后按方向键 :qall 关闭所有文件quit all:wall 写入所有文件write all","categories":[{"name":"工具学习","slug":"工具学习","permalink":"https://7bxing.com/categories/%E5%B7%A5%E5%85%B7%E5%AD%A6%E4%B9%A0/"},{"name":"Vim","slug":"工具学习/Vim","permalink":"https://7bxing.com/categories/%E5%B7%A5%E5%85%B7%E5%AD%A6%E4%B9%A0/Vim/"}],"tags":[{"name":"Vim","slug":"Vim","permalink":"https://7bxing.com/tags/Vim/"}]},{"title":"【推荐】Hexo博客配置及源文件备份","slug":"Hexo博客配置及源文件备份","date":"2020-09-19T12:38:31.000Z","updated":"2020-09-19T12:38:31.000Z","comments":true,"path":"posts/659688f7/","link":"","permalink":"https://7bxing.com/posts/659688f7/","excerpt":"利用 批处理 + 坚果云 来增量备份 Hexo 配置及源文件","text":"利用 批处理 + 坚果云 来增量备份 Hexo 配置及源文件 背景建站初期,经常折腾博客配置,有次不小心还误删除了 package.json,后来花费很久才重新配置完成。又权衡了很久,决定要把配置和源文件备份起来! 于是乎,在网上搜索怎么备份 Hexo 配置及源文件?大多都是直接或间接(通过插件)备份到 git仓库,而且操作相对复杂,感觉没必要 所以还是要研究自己的备份方法… 需求点整理一下:大致分为三个条件 操作简单 增量备份 由于存在不少 key,必须满足私密性 好在简单的 bat脚本 + 坚果云 就能实现 操作步骤以下是正文部分 批处理复制到单独文件夹 xcopy命令可以增量复制(只复制改动过的文件)需要复制的文件一般为package.json、_config.*yml、source和scaffolds具体可以查看官方文档 hexo目录结构或者其他更详细的介绍 简单认识Hexo的目录结构 bat脚本代码为: 12345678910111213141516171819@ECHO OFFtitle Hexo博客备份set "Dir=D:\\Tools\\!Hexo\\"echo -------------------------@ECHO ONxcopy /y /d %~nx0 "%Dir%"xcopy /y /d package.json "%Dir%"xcopy /y /d _config.*yml "%Dir%"xcopy /y /d /e source "%Dir%source\\"xcopy /y /d /e scaffolds "%Dir%scaffolds\\"@ECHO OFFecho.echo -------------------------echo 备份完成,按任意键退出...pause>nul 使用方法:在博客根目录下,新建文本文档,改名为 !copy.bat,复制脚本代码,将 D:\\Tools\\!Hexo\\ 改为你的备份路径,保存每次配置有调整或者新建了文章,点一下此脚本即可,效果如下: 注:如果你在源文件夹删除了某个文件或文件夹,此脚本就不能同步删除了,需要你去手动删除 备份到 坚果云其实没什么可说的(将bat脚本备份的文件夹同步到坚果云就行)主要是强烈推荐一波 坚果云 截两张图片吧: 最后,作为一个长期免费用户,衷心希望坚果云越做越好~","categories":[{"name":"Hexo","slug":"Hexo","permalink":"https://7bxing.com/categories/Hexo/"}],"tags":[{"name":"Hexo备份","slug":"Hexo备份","permalink":"https://7bxing.com/tags/Hexo%E5%A4%87%E4%BB%BD/"}]},{"title":"「硬核JS」一次搞懂JS运行机制","slug":"「硬核JS」一次搞懂JS运行机制","date":"2020-09-08T14:15:55.000Z","updated":"2020-09-08T14:15:55.000Z","comments":true,"path":"posts/9c28944f/","link":"","permalink":"https://7bxing.com/posts/9c28944f/","excerpt":"从零到一百再到一,从多方面了解JS的运行机制,体会更深刻","text":"从零到一百再到一,从多方面了解JS的运行机制,体会更深刻 前言 来自原作者的开场白: 从开始做前端到目前为止,陆续看了很多帖子讲JS运行机制,看过不久就忘了,还是自己理一遍好些通过码字使自己对JS运行机制相关内容更加深刻(自己用心写过的贴子,内容也会牢记于心)顺道给大家看看(我太难了,深夜码字,反复修改,说这么多就是想请你点个赞在看)参考了很多资料(帖子),取其精华,去其糟糠,都在文末,可自行了解 是时候搞一波我大js了 本文大致分为以下这样的步骤来帮助我们由广入深更加清晰的了解JS运行机制 首先我们要了解进程和线程的概念 其次我们要知道浏览器的进程线程常识 再然后通过Event Loop、宏任务(macrotask)微任务(microtask)来看浏览器的几个线程间是怎样配合的 再然后通过例子来印证我们的猜想 最后提下NodeJS的运行机制 灵魂一问JS运行机制在平常前端面试时不管是笔试题还是面试题命中率都极高 说到JS运行机制,你知道多少 看到这大家可能回说:JS运行机制嘛,很简单,事件循环、宏微任务那点东西 是的,作为一名前端我们都了解,但是如果这真的面试问到了这个地方,你真的可以答好吗(灵魂一问️) 不管你对JS了解多少,到这里大家不妨先停止一下阅读,假设你目前在面试,面试官让你阐述下JS运行机制,思考下你的答案,用20秒的时间(面试时20s已经很长了),然后带着答案再接着往下看,有人曾经说过:没有思考的阅读纯粹是消磨时间罢了,这话很好(因为是我说的,皮一下) 也有很多刚开始接触JS的同学会被任务队列 执行栈 微任务 宏任务这些高大上点的名次搞的很懵 接下来,我们来细致的梳理一遍你就可以清晰的了解它们了 进程与线程什么是进程我们都知道,CPU是计算机的核心,承担所有的计算任务 官网说法,进程是CPU资源分配的最小单位 字面意思就是进行中的程序,我将它理解为一个可以独立运行且拥有自己的资源空间的任务程序 进程包括运行中的程序和程序所使用到的内存和系统资源 CPU可以有很多进程,我们的电脑每打开一个软件就会产生一个或多个进程,为什么电脑运行的软件多就会卡,是因为CPU给每个进程分配资源空间,但是一个CPU一共就那么多资源,分出去越多,越卡,每个进程之间是相互独立的,CPU在运行一个进程时,其他的进程处于非运行状态,CPU使用 时间片轮转调度算法 来实现同时运行多个进程 什么是线程线程是CPU调度的最小单位 线程是建立在进程的基础上的一次程序运行单位,通俗点解释线程就是程序中的一个执行流,一个进程可以有多个线程 一个进程中只有一个执行流称作单线程,即程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行 一个进程中有多个执行流称作多线程,即在一个程序中可以同时运行多个不同的线程来执行不同的任务, 也就是说允许单个程序创建多个并行执行的线程来完成各自的任务 进程和线程的区别进程是操作系统分配资源的最小单位,线程是程序执行的最小单位 一个进程由一个或多个线程组成,线程可以理解为是一个进程中代码的不同执行路线 进程之间相互独立,但同一进程下的各个线程间共享程序的内存空间(包括代码段、数据集、堆等)及一些进程级的资源(如打开文件和信号) 调度和切换:线程上下文切换比进程上下文切换要快得多 多进程和多线程多进程:多进程指的是在同一个时间里,同一个计算机系统中如果允许两个或两个以上的进程处于运行状态。多进程带来的好处是明显的,比如大家可以在网易云听歌的同时打开编辑器敲代码,编辑器和网易云的进程之间不会相互干扰 多线程:多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务 JS为什么是单线程JS的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准? 还有人说js还有Worker线程,对的,为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程是完 全受主线程控制的,而且不得操作DOM 所以,这个标准并没有改变JavaScript是单线程的本质 了解了进程和线程之后,接下来看看浏览器解析,浏览器之间也是有些许差距的,不过大致是差不多的,下文我们皆用市场占有比例最大的Chrome为例 浏览器浏览器是多进程的作为前端,免不了和浏览器打交道,浏览器是多进程的,拿Chrome来说,我们每打开一个Tab页就会产生一个进程,我们使用Chrome打开很多标签页不关,电脑会越来越卡,不说其他,首先就很耗CPU 浏览器包含哪些进程 Browser进程 浏览器的主进程(负责协调、主控),该进程只有一个 负责浏览器界面显示,与用户交互。如前进,后退等 负责各个页面的管理,创建和销毁其他进程 将渲染(Renderer)进程得到的内存中的Bitmap(位图),绘制到用户界面上 网络资源的管理,下载等 第三方插件进程 每种类型的插件对应一个进程,当使用该插件时才创建 GPU进程 该进程也只有一个,用于3D绘制等等 渲染进程(重) 即通常所说的浏览器内核(Renderer进程,内部是多线程) 每个Tab页面都有一个渲染进程,互不影响 主要作用为页面渲染,脚本执行,事件处理等 为什么浏览器要多进程我们假设浏览器是单进程,那么某个Tab页崩溃了,就影响了整个浏览器,体验有多差 同理如果插件崩溃了也会影响整个浏览器 当然多进程还有其它的诸多优势,不过多阐述 浏览器进程有很多,每个进程又有很多线程,都会占用内存 这也意味着内存等资源消耗会很大,有点拿空间换时间的意思 到此可不只是为了让我们理解为何Chrome运行时间长了电脑会卡,哈哈,第一个重点来了 简述渲染进程Renderer(重)页面的渲染,JS的执行,事件的循环,都在渲染进程内执行,所以我们要重点了解渲染进程 渲染进程是多线程的,我们来看渲染进程的一些常用较为主要的线程渲染进程Renderer的主要线程 GUI渲染线程 负责渲染浏览器界面,解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等 解析html代码(HTML代码本质是字符串)转化为浏览器认识的节点,生成DOM树,也就是DOM Tree 解析css,生成CSSOM(CSS规则树) 把DOM Tree 和CSSOM结合,生成Rendering Tree(渲染树) 当我们修改了一些元素的颜色或者背景色,页面就会重绘(Repaint) 当我们修改元素的尺寸,页面就会回流(Reflow) 当页面需要Repaing和Reflow时GUI线程执行,绘制页面 回流(Reflow)比重绘(Repaint)的成本要高,我们要尽量避免Reflow和Repaint GUI渲染线程与JS引擎线程是互斥的 当JS引擎执行时GUI线程会被挂起(相当于被冻结了) GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行 JS引擎线程 JS引擎线程就是JS内核,负责处理Javascript脚本程序(例如V8引擎) JS引擎线程负责解析Javascript脚本,运行代码 JS引擎一直等待着任务队列中任务的到来,然后加以处理 浏览器同时只能有一个JS引擎线程在运行JS程序,所以js是单线程运行的 一个Tab页(renderer进程)中无论什么时候都只有一个JS线程在运行JS程序 GUI渲染线程与JS引擎线程是互斥的,js引擎线程会阻塞GUI渲染线程 就是我们常遇到的JS执行时间过长,造成页面的渲染不连贯,导致页面渲染加载阻塞(就是加载慢) 例如浏览器渲染的时候遇到<script>标签,就会停止GUI的渲染,然后js引擎线程开始工作,执行里面的js代码,等js执行完毕,js引擎线程停止工作,GUI继续渲染下面的内容。所以如果js执行时间太长就会造成页面卡顿的情况 事件触发线程 属于浏览器而不是JS引擎,用来控制事件循环,并且管理着一个事件队列(task queue) 当js执行碰到事件绑定和一些异步操作(如setTimeOut,也可来自浏览器内核的其他线程,如鼠标点击、AJAX异步请求等),会走事件触发线程将对应的事件添加到对应的线程中(比如定时器操作,便把定时器事件添加到定时器线程),等异步事件有了结果,便把他们的回调操作添加到事件队列,等待js引擎线程空闲时来处理。 当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理 因为JS是单线程,所以这些待处理队列中的事件都得排队等待JS引擎处理 定时触发器线程 setInterval与setTimeout所在线程 浏览器定时计数器并不是由JavaScript引擎计数的(因为JavaScript引擎是单线程的,如果处于阻塞线程状态就会影响记计时的准确) 通过单独线程来计时并触发定时(计时完毕后,添加到事件触发线程的事件队列中,等待JS引擎空闲后执行),这个线程就是定时触发器线程,也叫定时器线程 W3C在HTML标准中规定,规定要求setTimeout中低于4ms的时间间隔算为4ms 异步http请求线程 在XMLHttpRequest在连接后是通过浏览器新开一个线程请求 将检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件,将这个回调再放入事件队列中再由JavaScript引擎执行 简单说就是当执行到一个http异步请求时,就把异步请求事件添加到异步请求线程,等收到响应(准确来说应该是http状态变化),再把回调函数添加到事件队列,等待js引擎线程来执行 了解了上面这些基础后,接下来我们开始进入今天的正题 事件循环(Event Loop)初探首先要知道,JS分为同步任务和异步任务 同步任务都在主线程(这里的主线程就是JS引擎线程)上执行,会形成一个执行栈 主线程之外,事件触发线程管理着一个任务队列,只要异步任务有了运行结果,就在任务队列之中放一个事件回调 一旦执行栈中的所有同步任务执行完毕(也就是JS引擎线程空闲了),系统就会读取任务队列,将可运行的异步任务(任务队列中的事件回调,只要任务队列中有事件回调,就说明可以执行)添加到执行栈中,开始执行 我们来看一段简单的代码 12345678910111213let setTimeoutCallBack = function() { console.log('我是定时器回调');};let httpCallback = function() { console.log('我是http请求回调');};console.log('我是同步任务1'); // 同步任务/setTimeout(setTimeoutCallBack,1000); // 异步定时任务//* * 异步http请求任务 * ajax.get('/info',httpCallback); //无此环境 */console.log('我是同步任务2'); // 同步任务/ 上述代码执行过程 JS是按照顺序从上往下依次执行的,可以先理解为这段代码时的执行环境就是主线程,也就是也就是当前执行栈 首先,执行console.log(‘我是同步任务1’) 接着,执行到setTimeout时,会移交给定时器线程,通知定时器线程 1s 后将 setTimeoutCallBack 这个回调交给事件触发线程处理,在 1s 后事件触发线程会收到 setTimeoutCallBack 这个回调并把它加入到事件触发线程所管理的事件队列中等待执行 接着,执行http请求,会移交给异步http请求线程发送网络请求,请求成功后将 httpCallback 这个回调交由事件触发线程处理,事件触发线程收到 httpCallback 这个回调后把它加入到事件触发线程所管理的事件队列中等待执行 再接着执行console.log(‘我是同步任务2’) 至此主线程执行栈中执行完毕,JS引擎线程已经空闲,开始向事件触发线程发起询问,询问事件触发线程的事件队列中是否有需要执行的回调函数,如果有将事件队列中的回调事件加入执行栈中,开始执行回调,如果事件队列中没有回调,JS引擎线程会一直发起询问,直到有为止 到了这里我们发现,浏览器上的所有线程的工作都很单一且独立,非常符合单一原则 定时触发线程只管理定时器且只关注定时不关心结果,定时结束就把回调扔给事件触发线程 异步http请求线程只管理http请求同样不关心结果,请求结束把回调扔给事件触发线程 事件触发线程只关心异步回调入事件队列 而我们JS引擎线程只会执行执行栈中的事件,执行栈中的代码执行完毕,就会读取事件队列中的事件并添加到执行栈中继续执行,这样反反复复就是我们所谓的事件循环(Event Loop) 图解 首先,执行栈开始顺序执行 判断是否为同步,异步则进入异步线程,最终事件回调给事件触发线程的任务队列等待执行,同步继续执行 执行栈空,询问任务队列中是否有事件回调 任务队列中有事件回调则把回调加入执行栈末尾继续从第一步开始执行 任务队列中没有事件回调则不停发起询问 宏任务(macrotask) & 微任务(microtask)宏任务(macrotask)在ECMAScript中,macrotask也被称为task 我们可以将每次执行栈执行的代码当做是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行), 每一个宏任务会从头到尾执行完毕,不会执行其他 由于JS引擎线程和GUI渲染线程是互斥的关系,浏览器为了能够使宏任务和DOM任务有序的进行,会在一个宏任务执行结果后,在下一个宏任务执行前,GUI渲染线程开始工作,对页面进行渲染 宏任务 -> GUI渲染 -> 宏任务 -> … 常见的宏任务 主代码块 setTimeout setInterval setImmediate ()-Node requestAnimationFrame ()-浏览器 微任务(microtask)ES6新引入了Promise标准,同时浏览器实现上多了一个microtask微任务概念,在ECMAScript中,microtask也被称为jobs 我们已经知道宏任务结束后,会执行渲染,然后执行下一个宏任务, 而微任务可以理解成在当前宏任务执行后立即执行的任务 当一个宏任务执行完,会在渲染前,将执行期间所产生的所有微任务都执行完 宏任务 -> 微任务 -> GUI渲染 -> 宏任务 -> … 常见微任务 process.nextTick ()-Node Promise.then() catch finally Object.observe MutationObserver 简单区分宏任务与微任务看了上述宏任务微任务的解释你可能还不太清楚,没关系,往下看,先记住那些常见的宏微任务即可 我们通过几个例子来看,这几个例子思路来自掘金云中君的文章参考链接【14】,通过渲染背景颜色来区分宏任务和微任务,很直观,我觉得很有意思,所以这里也用这种例子 找一个空白的页面,在console中输入以下代码 1234document.body.style = 'background:black';document.body.style = 'background:red';document.body.style = 'background:blue';document.body.style = 'background:pink'; 我们看到上面动图背景直接渲染了粉红色,根据上文里讲浏览器会先执行完一个宏任务,再执行当前执行栈的所有微任务,然后移交GUI渲染,上面四行代码均属于同一次宏任务,全部执行完才会执行渲染,渲染时GUI线程会将所有UI改动优化合并,所以视觉上,只会看到页面变成粉红色 再接着看 1234document.body.style = 'background:blue';setTimeout(()=>{ document.body.style = 'background:black'},200) 上述代码中,页面会先卡一下蓝色,再变成黑色背景,页面上写的是200毫秒,大家可以把它当成0毫秒,因为0毫秒的话由于浏览器渲染太快,录屏不好捕捉,我又没啥录屏慢放的工具,大家可以自行测试的,结果也是一样,最安全的方法是写一个index.html文件,在这个文件中插入上面的js脚本,然后浏览器打开,谷歌下使用控制台中performance功能查看一帧一帧的加载最为恰当,不过这样录屏不好录所以。。。 回归正题,之所以会卡一下蓝色,是因为以上代码属于两次宏任务,第一次宏任务执行的代码是将背景变成蓝色,然后触发渲染,将页面变成蓝色,再触发第二次宏任务将背景变成黑色 再来看 1234567document.body.style = 'background:blue'console.log(1);Promise.resolve().then(()=>{ console.log(2); document.body.style = 'background:pink';});console.log(3); 控制台输出 1 3 2 , 是因为 promise 对象的 then 方法的回调函数是异步执行,所以 2 最后输出 页面的背景色直接变成粉色,没有经过蓝色的阶段,是因为,我们在宏任务中将背景设置为蓝色,但在进行渲染前执行了微任务, 在微任务中将背景变成了粉色,然后才执行的渲染 微任务宏任务注意点 浏览器会先执行一个宏任务,紧接着执行当前执行栈产生的微任务,再进行渲染,然后再执行下一个宏任务 微任务和宏任务不在一个任务队列,不在一个任务队列 例如setTimeout是一个宏任务,它的事件回调在宏任务队列,Promise.then()是一个微任务,它的事件回调在微任务队列,二者并不是一个任务队列 以Chrome 为例,有关渲染的都是在渲染进程中执行,渲染进程中的任务(DOM树构建,js解析…等等)需要主线程执行的任务都会在主线程中执行,而浏览器维护了一套事件循环机制,主线程上的任务都会放到消息队列中执行,主线程会循环消息队列,并从头部取出任务进行执行,如果执行过程中产生其他任务需要主线程执行的,渲染进程中的其他线程会把该任务塞入到消息队列的尾部,消息队列中的任务都是宏任务 微任务是如何产生的呢?当执行到script脚本的时候,js引擎会为全局创建一个执行上下文,在该执行上下文中维护了一个微任务队列,当遇到微任务,就会把微任务回调放在微队列中,当所有的js代码执行完毕,在退出全局上下文之前引擎会去检查该队列,有回调就执行,没有就退出执行上下文,这也就是为什么微任务要早于宏任务,也是大家常说的,每个宏任务都有一个微任务队列(由于定时器是浏览器的API,所以定时器是宏任务,在js中遇到定时器会也是放入到浏览器的队列中) 此时,你可能还很迷惑,没关系,请接着往下看 图解宏任务和微任务 首先执行一个宏任务,执行结束后判断是否存在微任务 有微任务先执行所有的微任务,再渲染,没有微任务则直接渲染 然后再接着执行下一个宏任务 图解完整的Event Loop 首先,整体的script(作为第一个宏任务)开始执行的时候,会把所有代码分为同步任务、异步任务两部分 同步任务会直接进入主线程依次执行 异步任务会再分为宏任务和微任务 宏任务进入到Event Table中,并在里面注册回调函数,每当指定的事件完成时,Event Table会将这个函数移到Event Queue中 微任务也会进入到另一个Event Table中,并在里面注册回调函数,每当指定的事件完成时,Event Table会将这个函数移到Event Queue中 当主线程内的任务执行完毕,主线程为空时,会检查微任务的Event Queue,如果有任务,就全部执行,如果没有就执行下一个宏任务 上述过程会不断重复,这就是Event Loop,比较完整的事件循环 关于Promisenew Promise(() => {}).then() ,我们来看这样一个Promise代码 前面的 new Promise() 这一部分是一个构造函数,这是一个同步任务 后面的 .then() 才是一个异步微任务,这一点是非常重要的 1234567new Promise((resolve) = > { console.log(1) resolve()}).then(() = > { console.log(2)});console.log(3) 上面代码输出1 3 2 关于 async/await 函数async/await本质上还是基于Promise的一些封装,而Promise是属于微任务的一种 所以在使用await关键字与Promise.then效果类似 12345678setTimeout(() => console.log(4))async function test() { console.log(1) await Promise.resolve() console.log(3)}test()console.log(2) 上述代码输出1 2 3 4 可以理解为,await 以前的代码,相当于与 new Promise 的同步代码,await 以后的代码相当于 Promise.then的异步 举栗印证首先给大家来一个比较直观的动图 之所以放这个动图,就是为了向大家推荐这篇好文,动图录屏自参考链接【1】 极力推荐大家看看这篇帖子,非常nice,分步动画生动且直观,有时间的话可以自己去体验下 不过在看这个帖子之前你要先了解下运行机制会更好读懂些 接下来这个来自网上随意找的一个比较简单的面试题,求输出结果 12345678910111213141516171819202122function test() { console.log(1) setTimeout(function () { // timer1 console.log(2) }, 1000)}test();setTimeout(function () { // timer2 console.log(3)})new Promise(function (resolve) { console.log(4) setTimeout(function () { // timer3 console.log(5) }, 100) resolve()}).then(function () { setTimeout(function () { // timer4 console.log(6) }, 0) console.log(7)})console.log(8) 结合我们上述的JS运行机制再来看这道题就简单明了的多了 JS是顺序从上而下执行 执行到test(),test方法为同步,直接执行,console.log(1)打印1 test方法中setTimeout为异步宏任务,回调我们把它记做timer1放入宏任务队列 接着执行,test方法下面有一个setTimeout为异步宏任务,回调我们把它记做timer2放入宏任务队列 接着执行promise,new Promise是同步任务,直接执行,打印4 new Promise里面的setTimeout是异步宏任务,回调我们记做timer3放到宏任务队列 Promise.then是微任务,放到微任务队列 console.log(8)是同步任务,直接执行,打印8 主线程任务执行完毕,检查微任务队列中有Promise.then 开始执行微任务,发现有setTimeout是异步宏任务,记做timer4放到宏任务队列 微任务队列中的console.log(7)是同步任务,直接执行,打印7 微任务执行完毕,第一次循环结束 检查宏任务队列,里面有timer1、timer2、timer3、timer4,四个定时器宏任务,按照定时器延迟时间得到可以执行的顺序,即Event Queue:timer2、timer4、timer3、timer1,依次拿出放入执行栈末尾执行 (插播一条:浏览器 event loop 的 Macrotask queue,就是宏任务队列在每次循环中只会读取一个任务) 执行timer2,console.log(3)为同步任务,直接执行,打印3 检查没有微任务,第二次结束 执行timer4,console.log(6)为同步任务,直接执行,打印6 检查没有微任务,第三次Event Loop结束 执行timer3,console.log(5)同步任务,直接执行,打印5 检查没有微任务,第四次Event Loop结束 执行timer1,console.log(2)同步任务,直接执行,打印2 检查没有微任务,也没有宏任务,第五次Event Loop结束 结果:1,4,8,7,3,6,5,2 提一下NodeJS中的运行机制上面的一切都是针对于浏览器的EventLoop 虽然NodeJS中的JavaScript运行环境也是V8,也是单线程,但是,还是有一些与浏览器中的表现是不一样的 其实nodejs与浏览器的区别,就是nodejs的宏任务分好几种类型,而这好几种又有不同的任务队列,而不同的任务队列又有顺序区别,而微任务是穿插在每一种宏任务之间的 在node环境下,process.nextTick的优先级高于Promise,可以简单理解为在宏任务结束后会先执行微任务队列中的nextTickQueue部分,然后才会执行微任务中的Promise部分 上图来自NodeJS官网 如上图所示,nodejs的宏任务分好几种类型,我们只简单介绍大体内容了解,不详细解释,不然又是啰哩啰嗦一大篇 NodeJS的Event Loop相对比较麻烦 Node会先执行所有类型为 timers 的 MacroTask,然后执行所有的 MicroTask(NextTick例外)进入 poll 阶段,执行几乎所有 MacroTask,然后执行所有的 MicroTask再执行所有类型为 check 的 MacroTask,然后执行所有的 MicroTask再执行所有类型为 close callbacks 的 MacroTask,然后执行所有的 MicroTask至此,完成一个 Tick,回到 timers 阶段……如此反复,无穷无尽…… 反观浏览器中Event Loop就比较容易理解 先执行一个 MacroTask,然后执行所有的 MicroTask再执行一个 MacroTask,然后执行所有的 MicroTask……如此反复,无穷无尽…… 好了,关于Node中各个类型阶段的解析,这里就不过多说明了,自己查阅资料吧,这里就是简单提一下,NodeJS的Event Loop解释起来比浏览器这繁杂,这里就只做个对比 最后本文转载自今日头条创作者Echa攻城狮,感谢! 原文链接: 「硬核JS」一次搞懂JS运行机制","categories":[{"name":"IT技术","slug":"IT技术","permalink":"https://7bxing.com/categories/IT%E6%8A%80%E6%9C%AF/"},{"name":"JavaScript","slug":"IT技术/JavaScript","permalink":"https://7bxing.com/categories/IT%E6%8A%80%E6%9C%AF/JavaScript/"}],"tags":[{"name":"JavaScript","slug":"JavaScript","permalink":"https://7bxing.com/tags/JavaScript/"}]},{"title":"2016美国总统候选人辩论","slug":"2016总统候选人辩论","date":"2020-08-27T04:42:41.000Z","updated":"2020-08-27T04:42:41.000Z","comments":true,"path":"posts/52bf0210/","link":"","permalink":"https://7bxing.com/posts/52bf0210/","excerpt":"2016美国总统候选人辩论,共三场 电视辩论,特朗普对决希拉里","text":"2016美国总统候选人辩论,共三场 电视辩论,特朗普对决希拉里 观看视频 第一场第二场第三场TODO 请从下方原始链接观看~ 请从下方原始链接观看~ 如果感兴趣请从下方原始链接观看第二场和第三场~ 备注:页面嵌套多个西瓜视频会非常卡顿(多个视频也会同时播放)事实上,只嵌套一个时 也有报错(官方的iframe还处于开发模式)而B站的该视频第二场,清晰度最高只有480p 转载出处 视频来源: 西瓜视频作者: 波涛学时 原文链接: 第一场 第二场 第三场","categories":[{"name":"未分类","slug":"未分类","permalink":"https://7bxing.com/categories/%E6%9C%AA%E5%88%86%E7%B1%BB/"}],"tags":[{"name":"其他","slug":"其他","permalink":"https://7bxing.com/tags/%E5%85%B6%E4%BB%96/"}]},{"title":"短网址生成","slug":"短网址生成","date":"2020-07-12T05:46:41.000Z","updated":"2020-07-14T06:48:16.000Z","comments":true,"path":"posts/991130e/","link":"","permalink":"https://7bxing.com/posts/991130e/","excerpt":"基于 suowo.cn(开始弹广告了…) 官方API制作的 短网址生成 的小书签和快捷指令","text":"基于 suowo.cn(开始弹广告了…) 官方API制作的 短网址生成 的小书签和快捷指令 安装说明 小书签: 教程说明 使用了ES6语法,不兼容IE浏览器如果需要批量处理,请到官网处理(或采用其他工具, 推荐 Short Url) IOS捷径: 首次安装使用教程 强烈建议: 安装后申请个人的 key , 并进行手动替换 小书签替换key IOS捷径替换key js小书签 小书签代码 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155javascript:(function() { 'use strict'; const suo_now = true; /*打开时直接压缩window.location.href*/ const suo_api = 'https://api.suowo.cn/api.htm'; const suo_key = '5f0729c5b1b63c45d0cb8173@ae63a2ad212f6e56088ab7814732c4c0'; const dq = css => document.querySelector(css); let suoIm = { show: function() { let content = '也可以输入长网址:'; let css = `<style> .dialog-container { position: fixed; top: 0; width: 40%; min-width:300px; margin: 0 auto; border: 1px solid #ddd; border-radius: 4px; background-color: #fff; font: 14px/1.5 -apple-system,'Microsoft Yahei'; z-index: 99999; } .ctrlV-content {padding: 10px;} .bm-btns { float: right; margin-right: 20px; margin-bottom: 10px; } .long-url { display: block; width: 98%; margin-top: 10px; padding-left: 0.3em; border: 1px solid #ddd; border-radius: 4px; line-height: 28px; } .mybtn { margin-right: 6px; padding: 0 12px !important; border: none; border-radius: 10px; background: #981a1a; color: #fff; letter-spacing: .5em; text-indent: .5em; font-size: 14px; line-height: 27.5px; } .mybtn:hover {background-color: #0371df !important;} #cancel {background: #2d2d2d;} </style>`; let html = ` <div class='dialog-container'> <div class='ctrlV-content'>${content} <input class='long-url' value='' placeholder='为空则默认为当前网址'> </div> <div class='bm-btns'> <button id='operation' class='mybtn'>${suo_now?'清空':'生成'}</button> <button id='copy' class='mybtn'>复制</button> <button id='cancel' class='mybtn'>取消</button> </div> </div> `; dq('head').insertAdjacentHTML('beforeend', css); dq('body').insertAdjacentHTML('beforeend', html); setTimeout(() => { dq('.long-url').focus(); }, 50); let screenWidth = window.screen.width; let _left = (screenWidth - (dq('.dialog-container').offsetWidth)) / 2; dq('.dialog-container').style.marginLeft = _left + 'px'; suo_now && this.shortUrl(window.location.href); dq('.bm-btns').addEventListener('click', this.handle); }, handle: function() { if (!event.target.id) return; let url = dq('.long-url').value || window.location.href; let button = event.target.id; let oldText = event.target.innerText; if (button == 'operation'){ if (oldText=='生成') { suoIm.shortUrl(url); event.target.innerText = '清空'; } else { dq('.long-url').value = ''; event.target.innerText = '生成'; } } else { if (button == 'copy' && !dq('.long-url').value){ dq('.long-url').setAttribute('placeholder','请先点 [生成] 后再复制'); return; } dq('.dialog-container').remove(); dq('style:last-child').remove(); } }, shortUrl: function(long_url) { /* let long_url = 'https://www.bilibili.com/video/BV1EW411u7th?p=1'; */ this.jsonp({ format:'jsonp', key: suo_key, expireDate:'2030-03-31', url: encodeURIComponent(long_url) },'jsoncallback'); }, jsonp: function(data, callback) { let queryString = '?'; for(let k in data){ queryString += k + '=' + data[k] + '&'; } /*回调函数*/ let _url = suo_api + queryString + 'callback=' + callback; let head = document.getElementsByTagName('head')[0]; let script = document.createElement('script'); head.appendChild(script); /*创建jsonp回调函数*/ window[callback] = json => { dq('.long-url').value = json.url; dq('.long-url').select(); dq('#copy').addEventListener('click', this.copyText); head.removeChild(script); window[callback] = null; }; /*发送请求*/ script.src = _url; }, copyText: function() { let ele = dq('.long-url'); if (navigator.userAgent.match(/ipad|iphone/i)) { let range = document.createRange(); range.selectNode(ele); window.getSelection().addRange(range); document.execCommand('copy'); /*Remove the selections - NOTE: Should use*/ window.getSelection().removeAllRanges(); } else { ele.focus(); ele.select(); document.execCommand('copy'); } } }; suoIm.show();})(); 测试: 短网址 安装: 将上一行的 短网址 拖入到书签栏即可 IOS捷径地址: https://www.icloud.com/shortcuts/3f4de7b4f2a1415b8cd34eec19874b27 更多功能 密码短网址 匿名网址 统计分析 请访问官网: https://suowo.cn/","categories":[{"name":"IT技术","slug":"IT技术","permalink":"https://7bxing.com/categories/IT%E6%8A%80%E6%9C%AF/"},{"name":"JavaScript","slug":"IT技术/JavaScript","permalink":"https://7bxing.com/categories/IT%E6%8A%80%E6%9C%AF/JavaScript/"}],"tags":[{"name":"短网址生成","slug":"短网址生成","permalink":"https://7bxing.com/tags/%E7%9F%AD%E7%BD%91%E5%9D%80%E7%94%9F%E6%88%90/"}]},{"title":"VIDAA3/4系统工厂模式","slug":"VIDDA3-4系统工厂模式","date":"2020-07-05T14:06:01.000Z","updated":"2020-07-05T14:06:01.000Z","comments":true,"path":"posts/be2c6b79/","link":"","permalink":"https://7bxing.com/posts/be2c6b79/","excerpt":"之前(海信电视)在安装当贝市场时 了解到 VIDAA 系统,但在网上查找了各种方法,没能进入工厂模式最近无意中看到方法(准确说应该是网上终于更新了),特此记录!","text":"之前(海信电视)在安装当贝市场时 了解到 VIDAA 系统,但在网上查找了各种方法,没能进入工厂模式最近无意中看到方法(准确说应该是网上终于更新了),特此记录! 不同电视品牌、型号进入工厂模式的方法都不一样…好好的开发功能,做优化,不好么? 搞这些!!! 进入工厂模式 按遥控器上的「智汇」键,进入到桌面 点击「设置」项进入设置界面 点击「声音设置」,遥控器选中「声音平衡」 依次按遥控器「菜单 - OK - 菜单 - OK」键 此时可以看到电视机左上角出现大字「M」 接着按遥控器上的「菜单」键 进入到工程设置界面(普通用户请谨慎操作) 退出方法: 遥控器关机,再开机 然后选择电视信号源 相关参数开机模式,三种选项的含义是: 记忆 - 关闭机身电源开关,再次打开时,电视状态为关闭前的状态,物理关机前用遥控器关了就是关,没关就是开 关 - 关闭机身电源开关,再次打开时,电视状态永远为关,需要按一下遥控器的电源才会打开 开 - 关闭机身电源开关,再次打开时,电视状态永远为开 其他如果需要关闭开机广告,直接打客服电话反馈就行,不用自己去破解 参考教程海信电视精简教程,去除电视多余应用,换桌面 海信工厂模式没有adb调试的开启方法","categories":[{"name":"未分类","slug":"未分类","permalink":"https://7bxing.com/categories/%E6%9C%AA%E5%88%86%E7%B1%BB/"}],"tags":[{"name":"VIDAA系统","slug":"VIDAA系统","permalink":"https://7bxing.com/tags/VIDAA%E7%B3%BB%E7%BB%9F/"}]},{"title":"Shell猜数字游戏","slug":"Shell猜数字游戏","date":"2020-06-06T13:12:21.000Z","updated":"2020-06-08T13:12:21.000Z","comments":true,"path":"posts/3713cf69/","link":"","permalink":"https://7bxing.com/posts/3713cf69/","excerpt":"猜数字游戏加强版, 熟悉shell的基础语法,shell注意事项","text":"猜数字游戏加强版, 熟悉shell的基础语法,shell注意事项 猜数字规则 随机生成一个0~99的数字 输入错误 直接返回重新输入 猜测错误 提示大小 继续猜测(并返回剩余猜测次数) 连续猜错5次 退出(提示GAME OVER) 猜测正确(返回 you got it!) Shell备忘1. 文件模式windows下的换行(\\r\\n)与linux(\\n)下不同,如果是windows下创建的shell文件,传到linux后,需要在vim下重设格式为linux模式(重新编辑不需要改) set ff 查看文件模式 set ff=unix 设置文件为unix模式 注:mac系统换行为(\\r) 2. 立即执行 $() `` 推荐最外层用反引号``,内层用$()rn=$((`head -20 /dev/urandom | cksum | cut -f1 -d “ “` % 100))$(()) 表示算数运算 3. 各种判断推荐用法: [] 用于判断文件(目录)或者变量的存在与否,如 [ -z “a.sh” ] [[]] 用于正则判断,如 [[ “$INT” =~ ^-?[0-9]+$ ]] (()) 用于整数比较和计算,如 (( $gn > $rn )) 、$((chance-count)) !表示否定,如 [ ! -z “a.sh” ] 测试: ((1>2)) && echo 111 || echo 222 注: [] 和 [[]] 两边必须有空格 4. 函数的返回值 可以显示加:return 返回 如果不加,将以最后一条命令运行结果,作为返回值 return后跟数值n(0-255) 如需要其他返回值: 可以通过echo返回字符串,或者操作全局变量 远程执行拷贝下列命令,在 linux 环境下粘贴执行 1bash <(curl -sSL https://gcore.jsdelivr.net/gh/qinxs/cdn-assets@master/demo/guess.sh) 猜数字代码1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889#!/bin/bash# Shell猜数字游戏# 规则# 1 随机生成一个0~99的数字# 2 输入错误 直接返回重新输入# 3 猜测错误 提示大小 继续猜测(并返回剩余猜测次数)# 4 连续猜错5次 退出(提示GAME OVER)# 5 猜测正确(返回 you got it!)count=0chance=5cat << EOF======= Shell猜数字游戏 =======# 数字区间[0~99]# 你共有${chance}次机会!# Ctrl+C可强制退出EOFrn=$((`head -20 /dev/urandom | cksum | cut -f1 -d " "` % 100))# echo $rnechoColor(){ declare -A colors colors=( [black]=30 # 30m 黑色字 [red]=31 # 31m 红色字 [green]=32 # 32m 绿色字 [yellow]=33 # 33m 黄色字 [blue]=34 # 34m 蓝色字 [purple]=35 # 35m 紫色字 [skyblue]=36 # 36m 天蓝字 [white]=37 # 37m 白色字 ) mes="$1" # 示例 echo -e "\\033[31m 颜色字 \\033[0m" echo -e "\\033[${colors[$2]}m${mes}\\033[0m"}chkValue(){ gn="$1" # 非空判断 if [ -z "$gn" ]; then echoColor "你还未输入呢" "skyblue" continue # 有效数字判断 elif echo "$gn" | grep -q '[^0-9]'; then echoColor "请输入有效的数字" "red" continue # 范围判断 elif (( $gn < 0 )) || (( $gn > 99 )); then echoColor "输入大小有误,请重新输入!" "red" continue fi}chkCount(){ if (( $1 >= $chance )); then echoColor "${chance}次机会已用完, GAME OVER!" "blue" exit 0 fi}guess(){ while true; do read -p "请输入你猜测的数字[0~99]:" gn chkValue "$gn" break done if (( $gn > $rn )); then let "count++" echo '猜大了' echo "剩余猜测次数:$((chance-count))" chkCount $count guess elif (( $gn < $rn )); then let "count++" echo '猜小了' echo "剩余猜测次数:$((chance-count))" chkCount $count guess else echoColor "you got it!!!" "green" fi}guess","categories":[{"name":"IT技术","slug":"IT技术","permalink":"https://7bxing.com/categories/IT%E6%8A%80%E6%9C%AF/"},{"name":"Shell","slug":"IT技术/Shell","permalink":"https://7bxing.com/categories/IT%E6%8A%80%E6%9C%AF/Shell/"}],"tags":[{"name":"Shell","slug":"Shell","permalink":"https://7bxing.com/tags/Shell/"},{"name":"猜数字游戏","slug":"猜数字游戏","permalink":"https://7bxing.com/tags/%E7%8C%9C%E6%95%B0%E5%AD%97%E6%B8%B8%E6%88%8F/"}]},{"title":"Git学习","slug":"Git学习","date":"2020-05-16T05:05:02.000Z","updated":"2020-05-16T05:05:02.000Z","comments":true,"path":"posts/e28ceec1/","link":"","permalink":"https://7bxing.com/posts/e28ceec1/","excerpt":"快速学习Git, Git学习总结, 常见问题","text":"快速学习Git, Git学习总结, 常见问题 本文用于快速学习git请使用 Chrome 浏览器, 并安装 MarkDown Preview Plus 扩展后查看本文档 三年 Git 使用心得 & 常见问题整理https://juejin.im/post/5ee649ff51882542ea2b5108 廖雪峰教程 教程链接 别名配置 别名记录12345678$ git config --global alias.st status st -> status co -> checkout ci -> commit br -> branch unstage -> reset HEAD last -> log -1 lg -> log --color --graph --pretty=format:'...' --abbrev-commit 服务端 Gogs 推荐客户端(smartgit) Download git-bash命令 命令图解 常用命令 文件夹操作 常用快捷键 快捷键123456789Ctrl + A 移动光标到整条命令的起始位置Ctrl + E 移动光标到整条命令的结束位置Ctrl + ← 移动光标到单词的左边Ctrl + → 移动光标到单词的右边Ctrl + U 删除光标左侧的所有内容Ctrl + K 删除光标右侧的所有内容Ctrl + L 清屏(与reset类似,但不清除已显示内容)移动命令 上(上一行)、下(下一行)、F(下一页)、B(上一页)、D(下半页)、U(上半页)、q(退出)其 他: Tab、上下","categories":[{"name":"工具学习","slug":"工具学习","permalink":"https://7bxing.com/categories/%E5%B7%A5%E5%85%B7%E5%AD%A6%E4%B9%A0/"},{"name":"Git","slug":"工具学习/Git","permalink":"https://7bxing.com/categories/%E5%B7%A5%E5%85%B7%E5%AD%A6%E4%B9%A0/Git/"}],"tags":[{"name":"Git","slug":"Git","permalink":"https://7bxing.com/tags/Git/"}]},{"title":"hello world","slug":"hello-world","date":"2020-05-16T05:00:02.000Z","updated":"2020-05-16T05:00:02.000Z","comments":true,"path":"posts/d4a1185/","link":"","permalink":"https://7bxing.com/posts/d4a1185/","excerpt":"Hexo自动生成的hello world","text":"Hexo自动生成的hello world Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub. Quick StartCreate a new post1$ hexo new "My New Post" More info: Writing Run server1$ hexo server More info: Server Generate static files1$ hexo generate More info: Generating Deploy to remote sites1$ hexo deploy More info: Deployment","categories":[{"name":"未分类","slug":"未分类","permalink":"https://7bxing.com/categories/%E6%9C%AA%E5%88%86%E7%B1%BB/"}],"tags":[{"name":"其他","slug":"其他","permalink":"https://7bxing.com/tags/%E5%85%B6%E4%BB%96/"}]}],"categories":[{"name":"IT技术","slug":"IT技术","permalink":"https://7bxing.com/categories/IT%E6%8A%80%E6%9C%AF/"},{"name":"Win32编程","slug":"IT技术/Win32编程","permalink":"https://7bxing.com/categories/IT%E6%8A%80%E6%9C%AF/Win32%E7%BC%96%E7%A8%8B/"},{"name":"原创作品","slug":"原创作品","permalink":"https://7bxing.com/categories/%E5%8E%9F%E5%88%9B%E4%BD%9C%E5%93%81/"},{"name":"未分类","slug":"未分类","permalink":"https://7bxing.com/categories/%E6%9C%AA%E5%88%86%E7%B1%BB/"},{"name":"正则表达式","slug":"IT技术/正则表达式","permalink":"https://7bxing.com/categories/IT%E6%8A%80%E6%9C%AF/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/"},{"name":"工具学习","slug":"工具学习","permalink":"https://7bxing.com/categories/%E5%B7%A5%E5%85%B7%E5%AD%A6%E4%B9%A0/"},{"name":"Vim","slug":"工具学习/Vim","permalink":"https://7bxing.com/categories/%E5%B7%A5%E5%85%B7%E5%AD%A6%E4%B9%A0/Vim/"},{"name":"Hexo","slug":"Hexo","permalink":"https://7bxing.com/categories/Hexo/"},{"name":"JavaScript","slug":"IT技术/JavaScript","permalink":"https://7bxing.com/categories/IT%E6%8A%80%E6%9C%AF/JavaScript/"},{"name":"Shell","slug":"IT技术/Shell","permalink":"https://7bxing.com/categories/IT%E6%8A%80%E6%9C%AF/Shell/"},{"name":"Git","slug":"工具学习/Git","permalink":"https://7bxing.com/categories/%E5%B7%A5%E5%85%B7%E5%AD%A6%E4%B9%A0/Git/"}],"tags":[{"name":"Win32术语及编码约定","slug":"Win32术语及编码约定","permalink":"https://7bxing.com/tags/Win32%E6%9C%AF%E8%AF%AD%E5%8F%8A%E7%BC%96%E7%A0%81%E7%BA%A6%E5%AE%9A/"},{"name":"书签管理器","slug":"书签管理器","permalink":"https://7bxing.com/tags/%E4%B9%A6%E7%AD%BE%E7%AE%A1%E7%90%86%E5%99%A8/"},{"name":"Illustrator","slug":"Illustrator","permalink":"https://7bxing.com/tags/Illustrator/"},{"name":"正则表达式","slug":"正则表达式","permalink":"https://7bxing.com/tags/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/"},{"name":"Vim","slug":"Vim","permalink":"https://7bxing.com/tags/Vim/"},{"name":"Hexo备份","slug":"Hexo备份","permalink":"https://7bxing.com/tags/Hexo%E5%A4%87%E4%BB%BD/"},{"name":"JavaScript","slug":"JavaScript","permalink":"https://7bxing.com/tags/JavaScript/"},{"name":"其他","slug":"其他","permalink":"https://7bxing.com/tags/%E5%85%B6%E4%BB%96/"},{"name":"短网址生成","slug":"短网址生成","permalink":"https://7bxing.com/tags/%E7%9F%AD%E7%BD%91%E5%9D%80%E7%94%9F%E6%88%90/"},{"name":"VIDAA系统","slug":"VIDAA系统","permalink":"https://7bxing.com/tags/VIDAA%E7%B3%BB%E7%BB%9F/"},{"name":"Shell","slug":"Shell","permalink":"https://7bxing.com/tags/Shell/"},{"name":"猜数字游戏","slug":"猜数字游戏","permalink":"https://7bxing.com/tags/%E7%8C%9C%E6%95%B0%E5%AD%97%E6%B8%B8%E6%88%8F/"},{"name":"Git","slug":"Git","permalink":"https://7bxing.com/tags/Git/"}]}