『原创』『教程』博客评论框添加随机一言
前言由于我的博客之前经常有人回复一些无意义的内容，导致很多垃圾评论所以我在想既然很多游客喜欢回复一些垃圾评论，不如我直接设置一个随机一言，让他们省去了垃圾评论的打字时间，同时又能让我的评论区少一些无意义的评论而且那些真正认真回复的人只需要一键删除即可，也不会很影响评论体验，所以就给自己的评论框添加了随机一言前段时间有小伙伴留言让我出个评论随机一言的教程，而我这边突然爆发了疫情，前些天自己又感染了，所以一直拖到现在效果展示按照惯例，先来一波效果展示本教程仅以Joe主题为例，其他主题可自行发挥能力，如有技术问题，博主可提供简单的指导教程开始一、添加后台控制在 Joe/functions.php 或者 Joe/public/custom.php（有的话） 内添加以下代码// 评论框随机语录功能 $Comment_Citation = new Typecho_Widget_Helper_Form_Element_Select( 'Comment_Citation', array('off' => '关闭（默认）', 'on' => '开启'), 'off', '是否开启评论框随机语录功能', '介绍：开启后，评论框自动随机填充随机语录' ); $Comment_Citation->setAttribute('class', 'joe_content joe_change'); // 如果后台无法展示该设置，将joe_change修改为joe_other $form->addInput($Comment_Citation->multiMode()); //评论框随机语录链接/文字 $Comment_Citation__text = new Typecho_Widget_Helper_Form_Element_Textarea( 'Comment_Citation__text', NULL, "https://api.vvhan.com/api/ian", '评论框随机语录', '介绍：用于修改评论框随机语录（可以为api地址） 格式：一行一个，可以为api地址，也可为文字，可以填写多个API地址 注意：必须填写JSON格式的API，API需要开启跨域权限才能调取，否则会调取失败！ 如果为api地址可在前台按钮刷新内容，如果为文字只能刷新页面来刷新内容（建议使用api地址） 推荐API：https://api.vvhan.com/api/ian' ); $Comment_Citation__text->setAttribute('class', 'joe_content joe_change'); // 如果后台无法展示该设置，将joe_change修改为joe_other $form->addInput($Comment_Citation__text);二、添加刷新按钮（可省略）在 Joe/public/comment.php 添加以下代码，不添加则不设置刷新按钮{tabs}{tabs-pane label="添加位置"}{/tabs-pane}{tabs-pane label="添加代码"}<?php if ($this->options->Comment_Citation !== "off") : ?> 语录 <?php endif; ?>{/tabs-pane}{/tabs}三、添加内容获取1、添加后端获取在 Joe/core/function.php 添加以下代码{tabs}{tabs-pane label="添加位置"}{/tabs-pane}{tabs-pane label="添加代码"}/* 获取评论框随机语录 */ function _getComment_Citation() { $CitationRandom = explode("\r\n", Helper::options()->Comment_Citation__text); echo $CitationRandom[array_rand($CitationRandom)]; }{/tabs-pane}{/tabs}2、添加前端获取在 Joe/public/config.php 添加以下代码{tabs}{tabs-pane label="添加位置"}{/tabs-pane}{tabs-pane label="添加代码"}CITATION: `<?php _getComment_Citation() ?>`, // 评论随机语录{/tabs-pane}{/tabs}四、添加核心代码在 Joe/assets/js/joe.global.min.js 或者 Joe/assets/js/custom.min.js（有的话） 添加以下代码{hide}if ($(".Comment_Citation").length) {function e() {let e = Joe.CITATION,t = /(https?:\/\/[^\s]+)/g;t.test(e)? $.ajax({url: e,dataType: "text",success: (e) => $(".joe_comment__respond-form .body textarea").val(e),}) : $(".joe_comment__respond-form .body textarea").val(e);}e(),$(".Comment_Citation").click(function () { e(); });}{/hide}五、添加刷新按钮样式（可省略）这是刷新按钮样式，如果前面没添加刷新按钮，可跳过此步骤在 Joe/assets/css/joe.global.min.css 或者 Joe/assets/css/custom.min.css（如果有）添加以下代码.joe_owo__contain { position: static; .box { position: absolute; bottom: 100%; margin-bottom: 6px; left: 0px; padding-top: 5px; border: 1px solid rgba(0, 0, 0, 0.15); border-color: transparent; box-shadow: 0 0 10px 8px rgb(116 116 116 / 8%); } } .comment_box { cursor: pointer; text-align: center; color: var(--routine); height: 26px; line-height: 26px; background: var(--background); opacity: 0.85; border-radius: 13px; width: 70px; margin-left: 5px; &:hover { background: var(--theme); color: #fff; }}结语教程稍有点复杂，但其实是沿用侧栏随机一言的方法，所以如果你能看懂核心js的话，可以仅修改 第四步 中ajax的 url 来实现，那样会简单很多很多
『原创』『教程』为你的博客添加阅读模式（适配Joe，其他主题也可用）
『转载』『教程』搭建z-file文件目录并开启反向代理，可做图床和网盘
ZFile此项目是一个在线文件目录的程序, 支持各种对象存储和本地存储, 使用定位是个人放常用工具下载, 或做公共的文件库. 不会向多账户方向开发.前端基于 h5ai 的原有功能使用 Vue 重新开发、后端采用 SpringBoot, 数据库采用内嵌数据库.成果安装教程一、安装依赖基于java开发，所以要先安装java环境# CentOS系统 yum install -y java-1.8.0-openjdk unzip # Debian/Ubuntu系统 apt update apt install -y openjdk-8-jre-headless unzip 二、下载、上传项目{hide}github下载{cloud title="zfile" type="github" url="https://github.com/zhaojun1998/zfile" password=""/}最新版的3.2.1有一个bug，部分服务器会出现短链无法使用，作者已经修复，但是未更新github的版本，我这里下载了一份作为备份{cloud title="zfile" type="default" url="https://file.fuuuy.cn/s/0p6616" password=""/}{/hide}直接下载并上传到网站根目录，然后解压得到以下目录z-file ├─ META-INF ├─ WEB-INF └─ bin ├── start.sh # 启动脚本 ├── stop.sh # 停止脚本 └── restart.sh # 重启脚本三、开启部署服务直接在当前目录打开终端输入以下代码./bin/start.shWeb默认端口为8080，如需修改端口可直接编辑配置文件 /zfile/WEB-INF/classes/application.yml 启动之后部署工作即宣告完成，可以在浏览器里直接输入ip:8080进入Web进行下一步配置，如果觉得每次都要加端口号麻烦可以参考后续设置反代。 具体访问地址如下四、域名访问在宝塔面板中添加一个新的网站如果想要开启HTTPS可以在设置反代之前在SSL选项卡配置证书打开反向代理选项卡，选择添加反向代理，端口填你设置的端口号（我这里改成了8282），如图配置五、初始化因为上一步已经配置了域名访问，所以直接输入域名，无需再加端口号，设置管理用户名和密码。输入 域名/#/admin进入管理后台，可以设置域名，外观设置，修改密码，添加存储等。六、更多用法1、文件夹加密直接在欲加密的文件夹中上传一个名为“password.txt”的文件即可，密码即为文件内容。加密之后效果如图2、显示readme如果想在某个文件夹中显示readme文件，直接在该文件夹中上传readme.md文件即可，同时需要在后台中开启显示文档区功能。3、可以作为图床使用如果你的博客需要图片外链，那么你可以将图片上传到某个目录，接着在zfile中打开这个目录，找到图片文件，右键并选择复制直链，这样就获取了这张图片的直链。总结Z-File作为一款开源免费的网盘列表程序，优点还是很多的。安装部署和配置都比较方便，也可以生成固定的文件链接，使用定位是个人放常用工具下载, 或做公共的文件库. 不会向多账户方向开发。
『转载』『教程』H5ai（Dplayer）完整安装使用教程及注意事项
前言关于如何搭建 H5ai ，网上虽然有很多教程，但详细的却不多，有的也是比较模糊。本文将介绍一下如何在宝塔Nginx环境下搭建 H5ai 以及其中的一些注意事项。成果H5ai是一款德国程序员Lars Jung打造的基于HTTP Web服务器的现代文件索引器，是一款功能强大的PHP文件目录列表程序，适合做个人仓库，它提供多种文件目录列表呈现方式，支持 Apache Httpd, Lighttpd, Nginx等多种WEB服务器，支持多国语言（如英语，简体中文等），你可以在线预览以及下载TXT，图片，音频，视频等文件格式。 安装教程一、环境要求{callout color＝"#f0ad4e"}Nginx - MySQLPHP 7.1或以上phpMyAdmin{/callout}二、添加站点请在左边的菜单栏,找到网站,然后点击添加站点,输入相关信息后点击提交即可 三、H5ai下载将文件解压后放在网站根目录下的_h5ai文件夹内，结构如下 下载地址{hide}{cloud title="h5ai" type="default" url="https://release.larsjung.de/h5ai/h5ai-0.30.0.zip" password=""/}{/hide}DOC_ROOT ├─ _h5ai ├─ your files └─ and folders 四、上传文件把你需要列的文件及目录放在_h5ai同目录下即可（我这里是把_去掉了） 五、修改配置文件在宝塔面板首页->左边的网站 -> H5ai(放H5ai的网站) -> 设置 -> 配置文件中六、查看依赖信息访问 http(s)://你的网站名/_h5ai/public/index.php来查看H5ai的功能开放情况，默认密码为空 右边已经是yes或者变成绿色的,证明对应的依赖已经安装成功 七、配置PHP1、安装Use EXIF thumbs{callout color＝"#2bff00"}安装imagemagick和exifUse EXIF thumbs会显示成yes{/callout}2、Movie thumbs (ffmpeg)安装CentOS 6和7安装方法是不一样的，下面分别说明： 安装前都需要先安装epel扩展源:# yum -y install epel-release # su -c ‘yum localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-6.noarch.rpm https://download1.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-6.noarch.rpm‘ # yum -y install ffmpeg ffmpeg-devel 3、PDF thumbs安装选择安装convert# yum -y install ImageMagick 4、Shell tar/Shell zip/Shell du安装这三项根据h5ai官网,在 php.ini被禁用函数中去掉 exec和 passthru即可，是否有危险不知道,自己掂量,禁用好像也不影响一些功能，另外顺便把 scandir函数去掉禁用，不然会出现无非显示目录中文件的情况。 在你的软件商店中找到你下载的PHP版本–进入设置–禁用函数 {callout color＝"#14ffb9"}删除exec 和 passthruShell tar Shell zip Shell du就会显示成yes{/callout}八、给H5ai加密码首先我们要找到这个文件 _h5ai/public/index.php ，在最下面增加以下代码：function mima() { $user＝array(‘填写你的用户名‘,‘填写你的密码‘); if(!($user[0]＝＝＝$_SERVER[‘PHP_AUTH_USER‘] && $user[1]＝＝＝$_SERVER[‘PHP_AUTH_PW‘])){ header(‘WWW-Authenticate: Basic realm＝"MY Mark"‘); header(‘HTTP/1.0 401 Unauthorized‘); die("please login"); } } 然后在第一行，也就是<?php的下面（也就是第二行）插入以下代码：php mima(); 九、注意事项1、读取不出文件如果存在文件，但读不出来，可能原因就是 php 已禁用 scandir函数了，请修改 php.ini解决。 disable_functions＝passthru,exec,system,chroot,scandir,... 删掉 scandir,字样，再重启 php 即可：/etc/init.d/php-fpm restart。 文件仍读不出 把h5ai程序_h5ai中 private和 public两个文件夹中的 cache目录权限设置为 777。2、404报错检查上面步骤说到的配置文件步骤，如果正确请重启服务器试一试。
前言最近失恋了，就一直在学习前端基础，所以个人博客都好久没更新了偶然在翠翠的博客看到给typecho添加表情包的教程，所以自己也添加了两组表情包但是在添加途中遇到了一个问题，所以将自己遇到的坑记录下来成果展示后台编辑器代码位置 教程开始一、添加表情过滤因为Joe主题之前被人恶意注入过xss，因此主题作者添加了关键词屏蔽，所以还要进行过滤拿到一个表情包后，在 windows 系统中下这样操作，在表情包文件夹内创建一个 文本文档 然后双击打开，使用以下命令生成该文件夹文件（图片）列表：dir /b > list.txt 保存后将文件后缀改为 bat ，然后再双击打开，就会生成一个 list.txt 文件生成的 list.txt 就包含了改目录下的全部文件名，就可以很方便的批处理。 关键词拼串可以使用Excel进行，直接使用以下代码就行=A2&$F$2&A3 =E2&$F$2&A4然后打开 Joe/core/parse.php 文件，找到表情过滤在下面添加你表情的关键词与表情地址{tabs}{tabs-pane label="添加位置"}{/tabs-pane}{tabs-pane label="代码"}{hide}$text = preg_replace_callback( '/\:\#\(\s*(doge|亲亲|偷笑|再见|发怒|发财|可爱|吐血|呆|呕吐|困|坏笑|大佬|大哭|委屈|害羞|尴尬|微笑|思考|惊吓|打脸|抓狂|抠鼻子|斜眼笑|无奈|晕|流汗|流鼻血|点赞|生气|生病|疑问|白眼|睡着|笑哭|腼腆|色|调皮|鄙视|闭嘴|难过|馋|黑人问号|鼓掌)\s*\)/is', function ($match) { return ' themeUrl . '/assets/owo/bilibili/' . str_replace('%', '', urlencode($match[1])) . '.gif" alt="小电视"/>'; }, $text ); $text = preg_replace_callback( '/\:\$\(\s*(爱你|爱心|傲慢|白眼|棒棒糖|爆筋|抱拳|鄙视|闭嘴|擦汗|菜刀|吃|呲牙|大兵|大哭|蛋|得意|doge|发呆|发怒|奋斗|尴尬|勾引|鼓掌|害羞|憨笑|好棒|哈欠|喝彩|河蟹|坏笑|饥饿|惊恐|惊喜|惊讶|菊花|可爱|可怜|抠鼻|酷|快哭了|骷髅|困|篮球|泪奔|冷汗|流汗|流泪|难过|OK|喷血|撇嘴|啤酒|强|敲打|亲亲|糗大了|拳头|骚扰|色|胜利|手枪|衰|睡|调皮|偷笑|吐|托腮|委屈|微笑|握手|我最美|无奈|吓|小纠结|笑哭|小样儿|斜眼笑|西瓜|嘘|羊驼|阴险|疑问|右哼哼|幽灵|晕|再见|眨眼睛|折磨|咒骂|抓狂|左哼哼)\s*\)/is', function ($match) { return ' themeUrl . '/assets/owo/QQ/' . str_replace('%', '', urlencode($match[1])) . '.gif" alt="QQ"/>'; }, $text );{/hide}{/tabs-pane}{/tabs}这里有一个坑 ，因为原作者引用表情包地址是用的 urlencode() 函数，将文字转换为UrlEncode编码的字符{hide}所以图片地址应该为不带 % 的UrlEncode，因此可以在站长工具 UrlEncode编码/UrlDecode解码 中将图片list.txt的文字转码为UrlEncode字符串然后再复制到Excel中将 % 替换为 空值 ，就像这样虽然转码完成了，但是还要把图片名称都换成不带 % 的UrlEncode才行如果你是Windows系统就很简单了（Mac的同学自行百度批量修改文件名），同样是在Excel中进行拼串="ren "&A3&".gif "&C3&".gif"得到结果后，首先在表情包文件夹中创建一个 red.txt 文件，然后将得到的结果粘贴到txt文件中保存最后将 red.txt 改为 red.bat ，再双击运行，你就会看到你的图片被批量重命名了 {/hide}二、配置 OwO.json打开 Joe/assets/json 下的 joe.owo.json 文件在里面添加（请自行删除代码中的 删除 字符） "表情": [ { "icon": "assets/owo/QQ/E788B1E4BDA0.gif", "data": ":删除$(爱你)" }, { "icon": "assets/owo/QQ/E788B1E5BF83.gif", "data": ":删除$(爱心)" }, { "icon": "assets/owo/QQ/E582B2E685A2.gif", "data": ":删除$(傲慢)" }, { "icon": "assets/owo/QQ/E799BDE79CBC.gif", "data": ":删除$(白眼)" }, { "icon": "assets/owo/QQ/E6A392E6A392E7B396.gif", "data": ":删除$(棒棒糖)" }, { "icon": "assets/owo/QQ/E78886E7AD8B.gif", "data": ":删除$(爆筋)" }, { "icon": "assets/owo/QQ/E68AB1E68BB3.gif", "data": ":删除$(抱拳)" }, { "icon": "assets/owo/QQ/E98499E8A786.gif", "data": ":删除$(鄙视)" }, { "icon": "assets/owo/QQ/E997ADE598B4.gif", "data": ":删除$(闭嘴)" }, { "icon": "assets/owo/QQ/E693A6E6B197.gif", "data": ":删除$(擦汗)" }, { "icon": "assets/owo/QQ/E88F9CE58880.gif", "data": ":删除$(菜刀)" }, { "icon": "assets/owo/QQ/E59083.gif", "data": ":删除$(吃)" }, { "icon": "assets/owo/QQ/E591B2E78999.gif", "data": ":删除$(呲牙)" }, { "icon": "assets/owo/QQ/E5A4A7E585B5.gif", "data": ":删除$(大兵)" }, { "icon": "assets/owo/QQ/E5A4A7E593AD.gif", "data": ":删除$(大哭)" }, { "icon": "assets/owo/QQ/E89B8B.gif", "data": ":删除$(蛋)" }, { "icon": "assets/owo/QQ/E5BE97E6848F.gif", "data": ":删除$(得意)" }, { "icon": "assets/owo/QQ/doge.gif", "data": ":删除$(doge)" }, { "icon": "assets/owo/QQ/E58F91E59186.gif", "data": ":删除$(发呆)" }, { "icon": "assets/owo/QQ/E58F91E68092.gif", "data": ":删除$(发怒)" }, { "icon": "assets/owo/QQ/E5A58BE69697.gif", "data": ":删除$(奋斗)" }, { "icon": "assets/owo/QQ/E5B0B4E5B0AC.gif", "data": ":删除$(尴尬)" }, { "icon": "assets/owo/QQ/E58BBEE5BC95.gif", "data": ":删除$(勾引)" }, { "icon": "assets/owo/QQ/E9BC93E68E8C.gif", "data": ":删除$(鼓掌)" }, { "icon": "assets/owo/QQ/E5AEB3E7BE9E.gif", "data": ":删除$(害羞)" }, { "icon": "assets/owo/QQ/E686A8E7AC91.gif", "data": ":删除$(憨笑)" }, { "icon": "assets/owo/QQ/E5A5BDE6A392.gif", "data": ":删除$(好棒)" }, { "icon": "assets/owo/QQ/E59388E6ACA0.gif", "data": ":删除$(哈欠)" }, { "icon": "assets/owo/QQ/E5969DE5BDA9.gif", "data": ":删除$(喝彩)" }, { "icon": "assets/owo/QQ/E6B2B3E89FB9.gif", "data": ":删除$(河蟹)" }, { "icon": "assets/owo/QQ/E59D8FE7AC91.gif", "data": ":删除$(坏笑)" }, { "icon": "assets/owo/QQ/E9A5A5E9A5BF.gif", "data": ":删除$(饥饿)" }, { "icon": "assets/owo/QQ/E6838AE68190.gif", "data": ":删除$(惊恐)" }, { "icon": "assets/owo/QQ/E6838AE5969C.gif", "data": ":删除$(惊喜)" }, { "icon": "assets/owo/QQ/E6838AE8AEB6.gif", "data": ":删除$(惊讶)" }, { "icon": "assets/owo/QQ/E88F8AE88AB1.gif", "data": ":删除$(菊花)" }, { "icon": "assets/owo/QQ/E58FAFE788B1.gif", "data": ":删除$(可爱)" }, { "icon": "assets/owo/QQ/E58FAFE6809C.gif", "data": ":删除$(可怜)" }, { "icon": "assets/owo/QQ/E68AA0E9BCBB.gif", "data": ":删除$(抠鼻)" }, { "icon": "assets/owo/QQ/E985B7.gif", "data": ":删除$(酷)" }, { "icon": "assets/owo/QQ/E5BFABE593ADE4BA86.gif", "data": ":删除$(快哭了)" }, { "icon": "assets/owo/QQ/E9AAB7E9AB85.gif", "data": ":删除$(骷髅)" }, { "icon": "assets/owo/QQ/E59BB0.gif", "data": ":删除$(困)" }, { "icon": "assets/owo/QQ/E7AFAEE79083.gif", "data": ":删除$(篮球)" }, { "icon": "assets/owo/QQ/E6B3AAE5A594.gif", "data": ":删除$(泪奔)" }, { "icon": "assets/owo/QQ/E586B7E6B197.gif", "data": ":删除$(冷汗)" }, { "icon": "assets/owo/QQ/E6B581E6B197.gif", "data": ":删除$(流汗)" }, { "icon": "assets/owo/QQ/E6B581E6B3AA.gif", "data": ":删除$(流泪)" }, { "icon": "assets/owo/QQ/E99ABEE8BF87.gif", "data": ":删除$(难过)" }, { "icon": "assets/owo/QQ/OK.gif", "data": ":删除$(OK)" }, { "icon": "assets/owo/QQ/E596B7E8A180.gif", "data": ":删除$(喷血)" }, { "icon": "assets/owo/QQ/E69287E598B4.gif", "data": ":删除$(撇嘴)" }, { "icon": "assets/owo/QQ/E595A4E98592.gif", "data": ":删除$(啤酒)" }, { "icon": "assets/owo/QQ/E5BCBA.gif", "data": ":删除$(强)" }, { "icon": "assets/owo/QQ/E695B2E68993.gif", "data": ":删除$(敲打)" }, { "icon": "assets/owo/QQ/E4BAB2E4BAB2.gif", "data": ":删除$(亲亲)" }, { "icon": "assets/owo/QQ/E7B397E5A4A7E4BA86.gif", "data": ":删除$(糗大了)" }, { "icon": "assets/owo/QQ/E68BB3E5A4B4.gif", "data": ":删除$(拳头)" }, { "icon": "assets/owo/QQ/E9AA9AE689B0.gif", "data": ":删除$(骚扰)" }, { "icon": "assets/owo/QQ/E889B2.gif", "data": ":删除$(色)" }, { "icon": "assets/owo/QQ/E8839CE588A9.gif", "data": ":删除$(胜利)" }, { "icon": "assets/owo/QQ/E6898BE69EAA.gif", "data": ":删除$(手枪)" }, { "icon": "assets/owo/QQ/E8A1B0.gif", "data": ":删除$(衰)" }, { "icon": "assets/owo/QQ/E79DA1.gif", "data": ":删除$(睡)" }, { "icon": "assets/owo/QQ/E8B083E79AAE.gif", "data": ":删除$(调皮)" }, { "icon": "assets/owo/QQ/E581B7E7AC91.gif", "data": ":删除$(偷笑)" }, { "icon": "assets/owo/QQ/E59090.gif", "data": ":删除$(吐)" }, { "icon": "assets/owo/QQ/E68998E885AE.gif", "data": ":删除$(托腮)" }, { "icon": "assets/owo/QQ/E5A794E5B188.gif", "data": ":删除$(委屈)" }, { "icon": "assets/owo/QQ/E5BEAEE7AC91.gif", "data": ":删除$(微笑)" }, { "icon": "assets/owo/QQ/E68FA1E6898B.gif", "data": ":删除$(握手)" }, { "icon": "assets/owo/QQ/E68891E69C80E7BE8E.gif", "data": ":删除$(我最美)" }, { "icon": "assets/owo/QQ/E697A0E5A588.gif", "data": ":删除$(无奈)" }, { "icon": "assets/owo/QQ/E59093.gif", "data": ":删除$(吓)" }, { "icon": "assets/owo/QQ/E5B08FE7BAA0E7BB93.gif", "data": ":删除$(小纠结)" }, { "icon": "assets/owo/QQ/E7AC91E593AD.gif", "data": ":删除$(笑哭)" }, { "icon": "assets/owo/QQ/E5B08FE6A0B7E584BF.gif", "data": ":删除$(小样儿)" }, { "icon": "assets/owo/QQ/E6969CE79CBCE7AC91.gif", "data": ":删除$(斜眼笑)" }, { "icon": "assets/owo/QQ/E8A5BFE7939C.gif", "data": ":删除$(西瓜)" }, { "icon": "assets/owo/QQ/E59898.gif", "data": ":删除$(嘘)" }, { "icon": "assets/owo/QQ/E7BE8AE9A9BC.gif", "data": ":删除$(羊驼)" }, { "icon": "assets/owo/QQ/E998B4E999A9.gif", "data": ":删除$(阴险)" }, { "icon": "assets/owo/QQ/E79691E997AE.gif", "data": ":删除$(疑问)" }, { "icon": "assets/owo/QQ/E58FB3E593BCE593BC.gif", "data": ":删除$(右哼哼)" }, { "icon": "assets/owo/QQ/E5B9BDE781B5.gif", "data": ":删除$(幽灵)" }, { "icon": "assets/owo/QQ/E69995.gif", "data": ":删除$(晕)" }, { "icon": "assets/owo/QQ/E5868DE8A781.gif", "data": ":删除$(再见)" }, { "icon": "assets/owo/QQ/E79CA8E79CBCE79D9B.gif", "data": ":删除$(眨眼睛)" }, { "icon": "assets/owo/QQ/E68A98E7A3A8.gif", "data": ":删除$(折磨)" }, { "icon": "assets/owo/QQ/E59292E9AA82.gif", "data": ":删除$(咒骂)" }, { "icon": "assets/owo/QQ/E68A93E78B82.gif", "data": ":删除$(抓狂)" }, { "icon": "assets/owo/QQ/E5B7A6E593BCE593BC.gif", "data": ":删除$(左哼哼)" } ], "BiliBili": [ { "icon": "assets/owo/bilibili/doge.gif", "data": ":删除#(doge)" }, { "icon": "assets/owo/bilibili/E4BAB2E4BAB2.gif", "data": ":删除#(亲亲)" }, { "icon": "assets/owo/bilibili/E581B7E7AC91.gif", "data": ":删除#(偷笑)" }, { "icon": "assets/owo/bilibili/E5868DE8A781.gif", "data": ":删除#(再见)" }, { "icon": "assets/owo/bilibili/E58F91E68092.gif", "data": ":删除#(发怒)" }, { "icon": "assets/owo/bilibili/E58F91E8B4A2.gif", "data": ":删除#(发财)" }, { "icon": "assets/owo/bilibili/E58FAFE788B1.gif", "data": ":删除#(可爱)" }, { "icon": "assets/owo/bilibili/E59090E8A180.gif", "data": ":删除#(吐血)" }, { "icon": "assets/owo/bilibili/E59186.gif", "data": ":删除#(呆)" }, { "icon": "assets/owo/bilibili/E59195E59090.gif", "data": ":删除#(呕吐)" }, { "icon": "assets/owo/bilibili/E59BB0.gif", "data": ":删除#(困)" }, { "icon": "assets/owo/bilibili/E59D8FE7AC91.gif", "data": ":删除#(坏笑)" }, { "icon": "assets/owo/bilibili/E5A4A7E4BDAC.gif", "data": ":删除#(大佬)" }, { "icon": "assets/owo/bilibili/E5A4A7E593AD.gif", "data": ":删除#(大哭)" }, { "icon": "assets/owo/bilibili/E5A794E5B188.gif", "data": ":删除#(委屈)" }, { "icon": "assets/owo/bilibili/E5AEB3E7BE9E.gif", "data": ":删除#(害羞)" }, { "icon": "assets/owo/bilibili/E5B0B4E5B0AC.gif", "data": ":删除#(尴尬)" }, { "icon": "assets/owo/bilibili/E5BEAEE7AC91.gif", "data": ":删除#(微笑)" }, { "icon": "assets/owo/bilibili/E6809DE88083.gif", "data": ":删除#(思考)" }, { "icon": "assets/owo/bilibili/E6838AE59093.gif", "data": ":删除#(惊吓)" }, { "icon": "assets/owo/bilibili/E68993E884B8.gif", "data": ":删除#(打脸)" }, { "icon": "assets/owo/bilibili/E68A93E78B82.gif", "data": ":删除#(抓狂)" }, { "icon": "assets/owo/bilibili/E68AA0E9BCBBE5AD90.gif", "data": ":删除#(抠鼻子)" }, { "icon": "assets/owo/bilibili/E6969CE79CBCE7AC91.gif", "data": ":删除#(斜眼笑)" }, { "icon": "assets/owo/bilibili/E697A0E5A588.gif", "data": ":删除#(无奈)" }, { "icon": "assets/owo/bilibili/E69995.gif", "data": ":删除#(晕)" }, { "icon": "assets/owo/bilibili/E6B581E6B197.gif", "data": ":删除#(流汗)" }, { "icon": "assets/owo/bilibili/E6B581E9BCBBE8A180.gif", "data": ":删除#(流鼻血)" }, { "icon": "assets/owo/bilibili/E782B9E8B59E.gif", "data": ":删除#(点赞)" }, { "icon": "assets/owo/bilibili/E7949FE6B094.gif", "data": ":删除#(生气)" }, { "icon": "assets/owo/bilibili/E7949FE79785.gif", "data": ":删除#(生病)" }, { "icon": "assets/owo/bilibili/E79691E997AE.gif", "data": ":删除#(疑问)" }, { "icon": "assets/owo/bilibili/E799BDE79CBC.gif", "data": ":删除#(白眼)" }, { "icon": "assets/owo/bilibili/E79DA1E79D80.gif", "data": ":删除#(睡着)" }, { "icon": "assets/owo/bilibili/E7AC91E593AD.gif", "data": ":删除#(笑哭)" }, { "icon": "assets/owo/bilibili/E885BCE88586.gif", "data": ":删除#(腼腆)" }, { "icon": "assets/owo/bilibili/E889B2.gif", "data": ":删除#(色)" }, { "icon": "assets/owo/bilibili/E8B083E79AAE.gif", "data": ":删除#(调皮)" }, { "icon": "assets/owo/bilibili/E98499E8A786.gif", "data": ":删除#(鄙视)" }, { "icon": "assets/owo/bilibili/E997ADE598B4.gif", "data": ":删除#(闭嘴)" }, { "icon": "assets/owo/bilibili/E99ABEE8BF87.gif", "data": ":删除#(难过)" }, { "icon": "assets/owo/bilibili/E9A68B.gif", "data": ":删除#(馋)" }, { "icon": "assets/owo/bilibili/E9BB91E4BABAE997AEE58FB7.gif", "data": ":删除#(黑人问号)" }, { "icon": "assets/owo/bilibili/E9BC93E68E8C.gif", "data": ":删除#(鼓掌)" } ] 将上文中转码后的名称列成 Excel 表格，并在某单元格（比如图例中的 G2 ~ G5）输入前缀=$G$2&C2&$G$3&$G$4&A2&$G$5然后对于每一行输入公式进行字符串拼接 之后可以将表格复制到 Excel 转 json 中获取相应的 json 文件，就不需要一个个做啦 ww 做完后将其复制到 joe.owo.json 就好了注：我这里是将JSON格式化后的结构，建议格式后进行添加，不容易出错，而且看着不会眼睛疼（ 压缩代码太伤眼了 ）三、上传表情包文件将重命名后的表情包文件上传到 Joe/assets/owo 文件夹中，当然你也可以上传到其他地方，只要能访问到就行然后在打开网站查看效果就好啦～表情包资源当然其实这篇文章最重要的就是五套表情包的资源啦，资源的链接在下面，需要的话就拿去哦～>v< {hide}五套表情包合集{cloud title="五套表情包合集" type="lz" url="https://www.lanzoux.com/b728187" password=""/}{cloud title="五套表情包合集" type="wy" url="https://share.weiyun.com/5kOMsvz" password=""/}{cloud title="阿鲁表情包" type="default" url="https://file.fuuuy.cn/s/ihhf78" password=""/}{/hide}
『原创』『教程』搭建在线VSCode，部署Code-Server并配置反向代理实现域名访问
前言最近学习web开发，一边看视频一边练习，码代码、记笔记，实属有些不亦乐乎但是无奈本子配置不高，每次同时打开vscode+Chrome，本子风扇呼呼作响不说，手里还像捧着个暖宝宝，实在不快突然想起之前看到过的开源vscode—— code-server ，索性自己也来搭建一个web版的vscode成果展示教程开始一、下载code-server源代码其实codeserver有很多种安装方式，但是我这里使用的是通过宝塔进行本地安装Docker安装虽然简单，但是后期维护和修改会很难受，所有我就采用本地安装吧{card-default label="下载code-server源码" width=""}官方github下载： code-server 国内镜像下载： code-server 3.12.0-linux-amd64.tar.gz code-server-4.1.0-linux-amd64.tar.gz code-server-4.1.0-linux-arm64.tar.gz code-server-4.1.0-macos-amd64.tar.gz {/card-default}二、运行code-server1、上传下载的文件到服务器直接将下载好的文件上传到自己的服务器，当然你也可以先使用宝塔添加一个网站然后上传到该网站对应的目录下2、解压文件3、运行code-server直接在解压的文件夹内点击终端进入终端然后在终端输入以下代码直接启动./bin/code-server --host 0.0.0.0 --port 8080如图所示就是已经完成配置.进入浏览器，输入服务器公网ip，加上刚才我们指定的端口号进入,显示欢迎界面输入密码进入4、修改密码在第一次开启code-server时，会在服务器 根目录-root-.config-code-server下生成一个配置文件打开后可以修改 host:端口 和 密码 ，这里建议把host改为 0.0.0.0 以能够使用外网访问如果不想使用密码，在 启动命令 中加 --auth none 即可无需密码进入。成功访问。到这里，我们就基本完成了 code-server 的部署。存在的问题虽然我们已成功部署了 code-server 服务，但有几个问题仍然不可避免！我们使用 终端 连接的方式启动 code-server，一旦断开连接，那么 code-server 就不可以再使用了code-server 自签的证书被浏览器提示不安全域名 + 端口的访问方式实在是太麻烦，而且还会暴露端口，不安全优化 code-server 服务一、问题11、创建开启脚本直接在code-server同目录下创建一个 start.sh 文件，打开将以下代码复制进去{hide}export PASSWORD="123456" #端口可以自己指定，其他不改，后台运行 nohup ./bin/code-server --port 8080 --host 0.0.0.0 --auth password > run.log 2>&1 & echo $! > save_pid.txt{/hide}2、创建关闭脚本创建一个 stop.sh 文件，将以下代码复制进去kill -9 'cat save_pid.txt' # 关闭这个进程，关闭code-server服务这样一来我们就得到了开启和关闭的脚本文件3、启动开启脚本在同目录文件夹下打开终端输入以下代码，就可以直接启动code-server并保持后台./start.sh启动后不会有反馈，可以直接关闭当前终端，然后会发现同目录下生成了 run.log 文件打开 run.log 即可看到运行日志二、问题2{callout color="#38bdff"}必须先添加 SSL 证书，然后设置反向代理{/callout}该步骤结合第三步，先添加一个站点，设置好域名，不需要任何环境，php 版本设置为纯静态，然后在面板的 SSL 中申请 Let’s Encrypt 免费 SSL 证书即可。三、问题3这里我们改变默认端口进行访问，并且使用 Nginx 反向代理修改端口：我们可以选择合适的端口开启 code-server，如: ./code-server --port 288651、创建反向代理点击刚才在宝塔 添加的网站-反向代理-添加反向代理 输入你的 代理名称、目标URL {callout color="#f0ad4e"}代理名称：code-server（随便填）目标URL：你的外网IP:端口{/callout}此时你就可以直接使用你的域名进行访问了，但是可能会报错 Error: WebSocket close with status code 1006 别急，这是正常现象，因为你的Nginx没有使用WebSocket代理2、修改反向代理的配置文件点击反向代理里的 配置文件 进行修改在如下位置加入以下代码 {hide}{tabs}{tabs-pane label="代码"}为了实现反向代理，博主查询了大量资料，尝试了很多教程都没有成功最后还是我自己对官方给的反向代理代码进行比对后，进行提取才成功因为不懂Nginx，所以绕了很多弯路，方法也是自己琢磨出来的所以如果你成功了，不妨进行打赏，感谢你的支持！proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Accept-Encoding gzip;{/tabs-pane}{tabs-pane label="位置"}{/tabs-pane}{/tabs}{/hide}然后再返回你的域名，你会发现可以正常访问了结语虽然code-server还达不到vscode的强大，但是已经可以方便很多了，至少对我来说，我的渣本再也不会呼呼作响了。{bilibili bvid="bv1uL411P7VN" page=""/}
『修复』『插件』Typecho文章内容分页插件修复版（适配Joe编辑器）
前言最近在学习web开发，每天跟着教学视频学习，我觉得每一个都是重点，所以有很多学习笔记我将学习笔记放在了自己的博客，一是为了记录自己学习内容，二是为了复习方便但是最近学习DOM的时候，发现有很多要点，而我又不想将其分篇来写，所以导致一篇文章有很多内容内容一多，阅读的时候就很不方便，因为滚动条变小了，而且一直翻不到底也很容易让人放弃所以我就去寻找有没有将文章分页的方法，好不容易找到一个方法，但无奈自己才疏学浅无法将其应用到typecho上来只好退而求其次，寻找有么有现成的方法或者插件，功夫不负有心人，终于还是让我找到了一款插件但是版本很老，是2010年的一款插件，已经不支持typecho1.1了索性到google去找找，没想到意外发现了一位大佬修复了兼容1.1的问题可是由于版本较早，且当年互联网的技术和审美不如现在，所以虽然能用也还是存在一些小问题，比如支持第三方编辑器时，快捷插入键失效且显示在页面底部于是自己动手修复了一下，并对样式进行了一些修改，虽不够完美，但起码适配当前主题成果展示{tabs}{tabs-pane label="前端展示"}{/tabs-pane}{tabs-pane label="编辑器展示"}{/tabs-pane}{/tabs}插件下载本插件主要适配Joe主题，如其他主题需要使用，可以自行修改博主也可以提供一些小的技术支持，喜欢的话不妨打赏博主，万分感谢！
DOM（文档对象模型）1、DOM的简介（1）什么是DOM：DOM：文档对象模型（Document Object Model） （2）模型：（3）节点：节点的类型节点的属性例： 我是一个按钮 （4）事件（Event）事件：就是用户和浏览器之间的交互行为可以在事件对应的属性中设置一些js代码，当事件被触发时，这些代码将会执行onclick 点击一次、ondblclick点击两次可以为按钮的对应事件绑定处理函数的形式来响应事件，这样当事件被触发时，其对应的函数将会被调用 我是一个按钮 （5）文档的加载浏览器在加载一个页面时，是按照自上向下的顺序加载的，读取到一行就运行一行将js代码编写到页面的下部是为了可以在页面加载完毕后再执行js代码onload事件会在整个页面加载完毕后才触发可以为window绑定一个onload事件，可以确保代码执行时所有的DOM对象都已经加载完毕了 点我一下 2、DOM查询（1）获取元素节点window.onload = function(){ //为id为btn01的按钮绑定一个单击响应函数 var btn01 = document.getElementById("btn01"); btn01.onclick = function(){ var bj = document.getElenmentById("bj"); //打印bj //innerHTML 通过这个属性可以获取到元素内部的html代码 alert(bj.innerHTML); }; //为id为btn01的按钮绑定一个单击响应函数 var btn02 = document.getElementById("btn02"); btn02.onclick = function(){ //查找所以li节点 //getElementsByTagName()可以根据标签名来获取一组元素节点对象 //这个方法会返回一个类数组对象，所有查询到的元素都会封装到对象中 //即使查询到的元素只有一个也会封装到一个对象中 var lis = document.getElenmentsByTagName("li"); //打印lis //alert(lis); //变量lis for(var i=0; i<lis.length; i++){ alert(lis[i].innerHTML); } }; //为id为btn03的按钮绑定一个单击响应函数 var btn03 = document.getElementById("btn03"); btn03.onclick = function(){ //查找name=gender的所有节点 var inputs = document.getElenmentsByNmae("gender"); //alert(inputs.length); for(var i=0; i<inputs.length; i++){ //对于自结束标签，innerHTML无效 //alert(inputs[i].innerHTML); //如果需要读取元素节点属性直接使用：元素.属性名 //class属性不能采用这种方式，读取class属性时需要使用：元素.className alert(inputs[i].value); alert(inputs[i].name); alert(inputs[i].className); } }; };（2）图片切换的练习 <mata charset="UTF-8"> 上一张 下一张 （3）获取元素节点的子节点window.onload = function(){ //为id为btn04的按钮绑定一个单击响应函数 var btn04 = document.getElementById("btn04"); btn04.onclick = function(){ //获取id为city的元素 var city = document.getElementById("city"); //查找#city下所有的li节点 var lis = city.getElementsByTagName("li"); for(var i=0; i<lis.length; i++){ alert(lis[i].innerHTML); } }; //为id为btn05的按钮绑定一个单击响应函数 var btn05 = document.getElementById("btn05"); btn05.onclick = function(){ //返回id为city的节点 var city = document.getElementById("city"); //返回#city下所有子节点 //childNodes属性会获取包括文本节点在内的所有节点 //根据DOM标准，标签与标签之间的空白也会当成文本节点 //但是IE8及以下的浏览器，不会将空白文本当成子节点 var cns = city.childNodes; //alert(cns.length); // for(var i=0; i<cns.length; i++){ // alert(cns[i]); // } //children属性可以获取当前元素的所有子元素 var cns2 = city.chileren; alert(cns2.length); }; //为id为btn06的按钮绑定一个单击响应函数 var btn06 = document.getElementById("btn06"); btn06.onclick = function(){ //获取id为phone的元素 var phone = document.getElementById("phone"); //返回#phone的第一个子节点 //phone.childNodes[0]; //firstChild属性可获取到当前元素的第一个子节点（包括空白文本节点） var fir = phone.firstChild; //firstElementChild属性可以获取当前元素的第一个子元素，IE8及以下不支持 // fir = phone.firstElementChild; alert(fir.innerHTML); }; };（4）获取元素节点的父节点和兄弟节点//定义一个函数，专门为指定的元素绑定单击函数 /* 参数 idStr 要绑定单击响应函数的对象的id属性值 fun 事件的回调函数，当单击元素时，该函数将会被触发 */ function myClick(idStr,fun){ var btn = document.getElementById("idStr"); btn.onclick = fun; }; window.onload = function(){ //为id为btn07的按钮绑定一个单击响应函数 myClick("btn07",function(){ // 获取id为bj的节点 var bj = document.getElementById("bj"); // 返回#bj的父节点 var pn = bj.parentNode; // alert(pn.innerHTML); // innerText 该属性可以获取到元素内部的文本内容，会去除html标签 alert(pn.innerText); }); //为id为btn08的按钮绑定一个单击响应函数 myClick("btn08",function(){ // 获取id为Android的元素 var and = document.getElementById("android"); //返回id为Andrid的前一个兄弟元素(也可能获取到空白文本) var ps = and.previousSibling; // 获取前一个元素兄弟（不包含空白文本），IE8以下不支持 var pe = and.previousElementSibling alert(ps.innerHTML); alert(pe.innerHTML); }); // 读取#username的value属性值 myClick(btn09,function(){ // 获取id为username的元素 var um = document.getElementById("username"); // 读取um的value属性值 // 文本框的value属性值，就是文本框中填写的内容 alert(um.value); }); // 读取#username的value属性值 myClick(btn10,function(){ // 获取id为username的元素 var um = document.getElementById("username"); // 设置um的value属性值 um.value = "今天天气真不错"; }); // 返回#bj的文本值 myClick(btn11,function(){ // 获取id为bj的元素 var bj = document.getElementById("bj"); // alert(bj.innerHTML); // alert(bj.innerText); // 获取bj中的文本 // var fc = bj.firstChild; // alert(fc.nodeValue); // 与上面相同 alert(bj.firstChild.nodeValue); }); };{nextPage/}（5）全选练习 全选练习 你爱好的运动是？ 全选/全不选 足球 篮球 羽毛球 乒乓球 （6）DOM查询的其他方法 我是box1中的div 我是box1中的div 我是box1中的div 我是box1中的div （7）DOM增删改 Untitled Document 你喜欢哪个城市? 北京 上海 东京 首尔 创建一个"广州"节点,添加到#city下 将"广州"节点插入到#bj前面 使用"广州"节点替换#bj节点 删除#bj节点 读取#city内的HTML代码 设置#bj内的HTML代码 创建一个"广州"节点,添加到#city下 （8）添加删除记录-删除 添加删除记录练习 Name Email Salary Tom tom@tom.com 5000 Delete Jerry jerry@sohu.com 8000 Delete Bob bob@tom.com 10000 Delete 添加新员工 name: <input type="text" name="enmName" id="empName" email: <input type="text" name="email" id="email" salary: <input type="text" name="salary" id="salary" Submit {nextPage/}（9）添加删除记录-添加 添加删除记录练习 Name Email Salary Tom tom@tom.com 5000 Delete Jerry jerry@sohu.com 8000 Delete Bob bob@tom.com 10000 Delete 添加新员工 name: <input type="text" name="enmName" id="empName" email: <input type="text" name="email" id="email" salary: <input type="text" name="salary" id="salary" Submit （10）添加删除记录-修改 添加删除记录练习 Name Email Salary Tom tom@tom.com 5000 Delete Jerry jerry@sohu.com 8000 Delete Bob bob@tom.com 10000 Delete 添加新员工 name: <input type="text" name="enmName" id="empName" email: <input type="text" name="email" id="email" salary: <input type="text" name="salary" id="salary" Submit （11）添加删除记录-a的索引问题 添加删除记录练习 Name Email Salary Tom tom@tom.com 5000 Delete Jerry jerry@sohu.com 8000 Delete Bob bob@tom.com 10000 Delete 添加新员工 name: <input type="text" name="enmName" id="empName" email: <input type="text" name="email" id="email" salary: <input type="text" name="salary" id="salary" Submit {nextPage/}（12）操作内联样式 点我一下 点我一下2 （13）获取元素的样式元素.currentStyle.样式名getComputdeStyle()方法 点我一下 getStyle方法 点我一下 （14）其他样式相关的属性HTML DOM Element 对象 练习 欢迎亲爱的用户注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 亲爱的用户，请仔细阅读以下协议，如果不仔细阅读就无法注册 我已仔细阅读 15、事件对象 {nextPage/}练习：跟随鼠标移动 (16)事件冒泡事件的冒泡：指事件的 向上 传导，当后代元素上的事件被触发时，其祖先元素的 相同事件 也会被触发在开发中，大部分的事件冒泡都是有用的。如果不希望发生事件冒泡可以通过事件对象来取消冒泡可以将事件对象的canceBubble=true用来取消冒泡 我是box1 我是span （17）冒泡的应用—事件的委派事件委派：将事件统一绑定给元素的祖先元素，这样当后代元素上的事件触发时，会一直冒泡到祖先元素，从而通过祖先元素的响应函数来处理事件事件委派是利用了冒泡，通过委派可以减少事件绑定的次数，提高程序的性能 添加超链接 我是P元素 超链接一 超链接二 超链接三 （18）事件的绑定 点我一下 （19）事件的传播事件的冒泡和捕获阶段{alert type="success"}微软公司认为事件是由内向外传播，也就是当事件触发时，应该先触发当前元素上的事件，然后再向元素当前元素的祖先元素上传播，也就是事件在冒泡阶段执行网景公司认为事件是由外向内传播，也就是当前事件触发时，应该先触发当前元素的最外层的祖先元素的事件，然后再向内传播给后代元素w3c综合了两个公司的方案，将事件传播分成了三个阶段捕获阶段：在捕获阶段时从外（最外层祖先元素）向内（目标元素）进行捕获，但是默认此时不会触发事件目标阶段：事件捕获到目标元素，捕获结束，开始在目标目标元素上触发事件冒泡阶段：事件从目标向他的祖先元素传递，依次触发祖先元素上的事件如果希望在捕获阶段就触发事件，可以将addEventListener()的第三个参数设置为true一般不会希望在捕获阶段触发事件，所以这个参数一般都是false{/alert}
『原创』『教程』首页及文章页滚动广告栏
前言因为之前在很多网站上都能看到广告，虽然但是，这对很多博主来说也是一笔额外的收入，我一直是入不敷出！:@(吐血倒地) 然后我看到了执念博客的首页广告栏，虽然曝光确实大，但是用户体验极其不好，因为要翻很多广告才能翻到文章，就像这样：所以我就想到了滚动广告，一个广告的位置，能够显示多条广告成果展示{tabs}{tabs-pane label="首页"}{/tabs-pane}{tabs-pane label="文章页"}{/tabs-pane}{/tabs}教程开始灵感及相关代码来自于Joe主题的首页轮播图一、添加后台打开 functions.php 添加以下代码{tabs}{tabs-pane label="代码"}$JADPost = new Typecho_Widget_Helper_Form_Element_Textarea( 'JADPost', NULL, NULL, '文章页顶部广告', '介绍：用于设置文章页顶部广告 格式：广告图片 || 跳转链接 （中间使用两个竖杠分隔） 注意：如果您只想显示图片不想跳转，可填写：广告图片 || javascript:void(0) 其他：一行一个，一行代表一个轮播广告图' ); $JADPost->setAttribute('class', 'joe_content joe_post'); $form->addInput($JADPost);{/tabs-pane}{tabs-pane label="代码位置"}因为有位小伙伴放错了位置，所以再贴一张图{/tabs-pane}{/tabs}这是文章页的代码，因为首页广告主题自带了二、添加滚动广告栏{tabs}{tabs-pane label="首页"} 因为首页已经有广告位了，所以直接替换就行了将主题 index.php 的以下代码直接替换为新代码{collapse}{collapse-item label="代码位置" open}{/collapse-item}{collapse-item label="新代码" open}{hide} <?php $index_ad = []; $index_ad_text = $this->options->JIndex_Ad; if ($index_ad_text) { $index_ad_arr = explode("\r\n", $index_ad_text); if (count($index_ad_arr) > 0) { for ($i = 0; $i < count($index_ad_arr); $i++) { $img = explode("||", $index_ad_arr[$i])[0]; $url = explode("||", $index_ad_arr[$i])[1]; $index_ad[] = array("img" => trim($img), "url" => trim($url)); }; } } ?> <?php if (sizeof($index_ad) > 0) : ?> <?php foreach ($index_ad as $item) : ?> <a class="item" href="<?php echo $item['url'] ?>" target="_blank" rel="noopener noreferrer nofollow"> <img width="100%" class="image lazyload" src="<?php _getLazyload() ?>" data-src="<?php echo $item['img'] ?>" /> <?php endforeach; ?> 广告 <?php endif; ?> {/hide}{/collapse-item}{/collapse}{/tabs-pane}{tabs-pane label="文章页"}文章页直接在主题的 post.php 文件内合适的地方加入以下代码{collapse}{collapse-item label="代码位置" open}{/collapse-item}{collapse-item label="代码" open}{hide} <?php $JADPost = []; $JADPost_text = $this->options->JADPost; if ($JADPost_text) { $JADPost_arr = explode("\r\n", $JADPost_text); if (count($JADPost_arr) > 0) { for ($i = 0; $i < count($JADPost_arr); $i++) { $img = explode("||", $JADPost_arr[$i])[0]; $url = explode("||", $JADPost_arr[$i])[1]; $JADPost[] = array("img" => trim($img), "url" => trim($url)); }; } } ?> <?php if (sizeof($JADPost) > 0) : ?> <?php foreach ($JADPost as $item) : ?> <a class="item" href="<?php echo $item['url'] ?>" target="_blank" rel="noopener noreferrer nofollow"> <img width="100%" class="image lazyload" src="<?php _getLazyload() ?>" data-src="<?php echo $item['img'] ?>" /> <?php endforeach; ?> 广告 <?php endif; ?> {/hide}{/collapse-item}{/collapse}{/tabs-pane}{/tabs}三、修改广告栏样式{tabs}{tabs-pane label="首页"} 直接在 Joe/assets/css 打开 joe.index.min.css 然后在最后添加以下代码.joe_index__ad .swiper-container{height: 180px!important;border-radius: var(--radius-inner);}.joe_index__ad .swiper-container .icon{position:absolute;z-index:1;top:10px;right:10px;font-size:12px;background:rgba(0,0,0,0.25);padding:2px 5px;border-radius:2px;color:#ebebeb;pointer-events:none}@media (max-width: 768px){.joe_index__ad .swiper-container{height: 120px!important}.joe_index__ad .swiper-container .image{height: 120px;object-fit: cover;border-radius: var(--radius-inner);}}{/tabs-pane}{tabs-pane label="文章页"}直接在 Joe/assets/css 打开 joe.post.min.css 然后在最后添加以下代码.joe_post__ad .swiper-container{height: 180px!important;margin-top:15px;border-radius: var(--radius-inner);}.joe_post__ad .swiper-container .icon{position:absolute;z-index:1;top:10px;right:10px;font-size:12px;background:rgba(0,0,0,0.25);padding:2px 5px;border-radius:2px;color:#ebebeb;pointer-events:none}@media (max-width: 768px){.joe_post__ad .swiper-container{height: 120px!important}.joe_post__ad .swiper-container .image{height: 120px;object-fit: cover;border-radius: var(--radius-inner);}}{/tabs-pane}{/tabs}四、添加滚动效果{tabs}{tabs-pane label="首页"}首页因为引入了滚动效果，所有不需要设置，会直接调用首页轮播图的滚动效果但是会根据首页轮播图的滚动方式滚动，效果不太好，暂时没想到比较好的解决方法{/tabs-pane}{tabs-pane label="文章页"}首先在主题的 post.php 文件内 标签内加入以下代码 然后再在 Joe/assets/js 打开 joe.post_page.min.js 然后在最后添加以下代码if(0!==$(".joe_post__ad .swiper-container").length){let e="vertical";new Swiper(".swiper-container",{keyboard:!1,direction:e,loop:!0,autoplay:!0,mousewheel:!0,pagination:{el:".swiper-pagination"},})}添加位置{/tabs-pane}{/tabs}教程结束大功告成，快刷新你的网站看看效果吧！