代码相关:各种和代码有关的文章

Html多个引号重叠使用冲突解决办法

今天写个按钮,传递参数时,遇到个障碍,代码如下<a onclick="insertAtCursor('[btn url=""][/btn]');">按钮</a>url="" 中的引号,会导致解释错误,正常来说遇到引号冲突都是加 / 解决,然而并不适合这种情况。解决方法用html实体字符替换掉冲突引号, " 换成 &quot; 即可如<a onclick="insertAtCursor('[btn url=&quot;&quot;][/btn]');">按钮</a>如果是但引号冲突, ' 换成 &apos; 即可,ie 好像不支持建议使用数字形式的如 &#39;。什么是html实体字符?实体字符是 html 预留的一些字符,因为在 html 语法中有些你想输出符合会被浏览器判定为标签进行渲染,所以为了避免这种情况,就有了实体标签。比如有的时候你在 html 中使用了很多空格,但是html渲染出来就只有一个有效空格,这时候就可以用空格的实体字符 &nbsp; 解决,还有个实际用途,比如在 markdown 编辑器下,两个空格可能会被识别成markdown语法,那么你想段前空两格就可以放两个 &nbsp;&nbsp;引用实体字符,可以引用实体字符的字符名字,如 &apos; ,也可以引用实体编号如 &#39; ,实体编号各个浏览器兼容比较好,但是不利于记忆。更多实体字符可以参考w3c https://www.w3school.com.cn/tags/html_ref_entities.ht...

阅读文章
php7的isset和empty的变化

php5.6我判断变量是这样if(empty($this->fields->d)){} if(isset($this->fields->d)){}而php7测试这样怎么判断都是Flase,后来通过查资料发现php7在这个判断上做了些变化。php7判断的时候会依次判断,php5.6则是预加载后判断!也就是说php5.6判断是先执行$this->fields->d然后在对结果进行判断。而php7则是把$this->fields->d当做一个变量进行判断,而没有执行它。知道原理后就可以很好的写出兼容的判断代码了。将$this->fields->d赋值于一个变量,然后对这个变量进行判断就可以了!。$d=$this->fields->d; if(empty($d)){} if(isset($d)){}参考https://learnku.com/laravel/t/3021/isset-is-not-right-after-upgrading-ph...

阅读文章
网站夜间模式的实现

整体流程夜间模式开关按钮:用来手动切换夜间模式的,会存储cookie。自动夜间模式:当cookie为空时,浏览器时间大于22点小于6点时会自动进入夜间模式,并存储cookie。后端配合:php判断是否有cookie,有的话直接输出夜间css,避免切换页面时网页闪烁。具体操作引入黑夜 css <link href="dark.css" rel="alternate stylesheet" type="text/css" title="dark">有title熟悉rel属性值同时包含alternate stylesheet的<link>作为备选样式CSS文件加载,默认不渲染。切换夜间模式的 js 函数function switchNightMode(){ var night = document.cookie.replace(/(?:(?:^|.*;\s*)night\s*\=\s*([^;]*).*$)|^.*$/, "$1") || '0'; if(night == '0'){ document.querySelector('link[title="dark"]').disabled = true; document.querySelector('link[title="dark"]').disabled = false; document.cookie = "night=1;path=/" console.log('夜间模式开启'); }else{ document.querySelector('link[title="dark"]').disabled = true; document.cookie = "night=0;path=/" console.log('夜间模式关闭'); } }指定时间进入夜间模式(function(){ if(document.cookie.replace(/(?:(?:^|.*;\s*)night\s*\=\s*([^;]*).*$)|^.*$/, "$1") === ''){ if(new Date().getHours() > 22 || new Date().getHours() < 6){ document.querySelector('link[title="dark"]').disabled = true; document.querySelector('link[title="dark"]').disabled = false; document.cookie = "night=1;path=/" console.log('夜间模式开启'); }else{ document.cookie = "night=0;path=/" console.log('夜间模式关闭'); } }else{ var night = document.cookie.replace(/(?:(?:^|.*;\s*)night\s*\=\s*([^;]*).*$)|^.*$/, "$1") || '0'; if(night == '0'){ document.querySelector('link[title="dark"]').disabled = true; console.log('夜间模式关闭'); }else if(night == '1'){ document.querySelector('link[title="dark"]').disabled = true; document.querySelector('link[title="dark"]').disabled = false; console.log('夜间模式开启'); } } })();php 后端判断 cookie 进行加载 css<link href="dark.css" rel="<?php if($_COOKIE['night'] != '1'){echo 'alternate ';} ?>stylesheet" type="text/css" title="dark">适配 Mac 的 Dark Mode因为没有js的判断方法,所以需要插入段,css然后用js判断css的变化,来监控是否进入夜间模式插入 csshtml { content: ""; } /* Light mode */ @media (prefers-color-scheme: light) { html { content: "light"; } } /* Dark mode */ @media (prefers-color-scheme: dark) { html { content: "dark"; } }前端使用 JS 检查const mode = getComputedStyle(document.documentElement).getPropertyValue('content'); if(mode == '"dark"'){alert('进入夜间模式');}最后在dark.css里重写一些元素的背景色文字色等等。参考1,link rel=alternate网站换肤功能最佳实现2,给博客添加夜间模式3,prefers-color-scheme: CSS Media Que...

阅读文章
SQL笔记二(GROUP BY)

刚刚修复了typecho的CateFilter插件某种情况下会重复输出文章的bug,就是用的GROUP BY语法。我修的过程其实一点都不了解GROUP BY,因为百度搜索sql去重复的时候推荐了这个我就用了。然后想起来自己写过《SQL笔记一》的文章,而且文章过去挺久的了,所以我就想是时候再水一篇文章了。然后就百度查GROUP BY到底是干嘛的,搜到了各种优秀例子,各种说明,我都没看懂!然而,突然看到了个非常浅显的例子我就懂了。GROUP BY就是分组函数比如 现有 性别 男 3 人 体重 50KG/60KG/70 性别 女 2 人 体重 40KG/30KG 这时 你用到GROUP BY进行分组select sum(体重) ,性别 from 表明 group by 性别 ;则能得到结果 男 180女 70等于说 是按照你所GROUP BY的东西进行分组 ,然后再对分组内的东西进行操作就是这么个简单的例子,我们就可以理解这个函数的作用了,也能理解为什么他们够去除重复行。比如这个例子按某性别列的值分组,那么值相等的为一组,所以就排除掉了其他的上面是GROUP BY接单列的例子,那么多列又是什么样呢?姓名班级性别分数张11班男60张21班女70张31班男80张41班女80张52班男70张62班女60张72班男80select 班级,性别,AVG(分数) as 平均分 from test group 班级,性别得出的结果是班级性别平均分1班男701班女752班男752班女60这样就好理解多...

阅读文章
SQL笔记一(exists和not exists)

A列的值部分相同,根据B列的值的大小排除A列重复值SELECT * FROM `typecho_comments` t where not exists(select * from `typecho_comments` where cid = t.cid and created > t.created) //根据typecho,评论表实操,查询每篇文章的最新一条评论这个是根据百度的列子改的,然后就发现了个不熟悉的东西exists(翻译:存在)exists: (sql返回结果集,为真),说白了就是exists(条件),满足括号里面条件的结果就从里面返回结果not exists:(sql不返回结果集,为真)而not exists(条件),满足括号里面条件的结果就排除掉例子如下: 表A ID NAME 1 A1 2 A2 3 A3 表B ID AID NAME 1 1 B1 2 2 B2 3 2 B3 表A和表B是1对多的关系 A.ID => B.AIDSELECT ID,NAME FROM A WHERE EXIST (SELECT * FROM B WHERE A.ID=B.AID) 执行结果为 1 A1 2 A2 原因可以按照如下分析 SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=1) ---> SELECT * FROM B WHERE B.AID=1有值,返回真,所以有数据SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=2) ---> SELECT * FROM B WHERE B.AID=2有值,返回真,所以有数据SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=3) ---> SELECT * FROM B WHERE B.AID=3无值,返回假,所以没有数据NOT EXISTS 就是反过来 SELECT ID,NAME FROM A WHERE NOT EXIST (SELECT * FROM B WHERE A.ID=B.AID) 执行结果为 3 A3 =========================================================================== EXISTS = IN,意思相同不过语法上有点点区别,好像使用IN效率要差点,应该是不会执行索引的原因SELECT ID,NAME FROM A  WHERE ID IN (SELECT AID FROM B) NOT EXISTS = NOT IN ,意思相同不过语法上有点点区别SELECT ID,NAME FROM A WHERE ID NOT IN (SELECT AID FROM B) 例子来源:https://www.cnblogs.com/1234abcd/p/5525417.ht...

阅读文章
php查看B站互相关注的好友

B站跟微博越来越像了,被网友戏称“B博”,但是有个小细节跟微博还有点差异,在B站我的关注里,只能看到,xxx已关注,而看不到“互相关注”的字样!如下图,右侧那么如何自行的查下自己关注的人里哪些人也关注了我呢?在b站https://api.bilibili.com/x/web-interface/card?mid=7530883&jsonp=jsonp&article=true这个api里能够查询到,自己都关注了哪些人,所以利用这一点,挨个查询自己关注的人里是否有自己即可。上php代码<?php header('Access-Control-Allow-Origin:*'); $id=$_SERVER["QUERY_STRING"]; $reg = '/^[0-9][0-9]*$/'; if(preg_match($reg,$id)){ // 从文件中读取数据到PHP变量 $json_string = file_get_contents('https://api.bilibili.com/x/web-interface/card?mid='.$id.'&jsonp=jsonp&article=true'); // 把JSON字符串转成PHP数组 $data = json_decode($json_string); //定义我的关注数量,定义我关注的人的数组 $num=$data->data->card->attention; $att=$data->data->card->attentions; echo '<p>这些与你b站互关了:</p>'; //for循环挨个查询 for($i=0;$i<$num;$i++){ $json_string = file_get_contents('https://api.bilibili.com/x/web-interface/card?mid='.$att[$i].'&jsonp=jsonp&article=true'); $data = json_decode($json_string); $tatt=$data->data->card->attentions; if (in_array($id, $tatt)) { echo $att[$i].'-'.$data->data->card->name.'<br>'; } } }else{echo "非法参数";} ?>访问http://你的域名/hg.php?7530883即可,其中hg换成你的php的文件名,而7530883换成你的b站id即可。效果图如下:代码效率比较低,垃圾博主不会优化...请各位大佬指路....

阅读文章
php如何对preg_replace匹配的内容进行MD5/base64加密?

前言其实yodu模板友链页面很早就考虑直接写友链者的邮箱,然后模板自动输出gravatar头像,然而因为模板采用的是正则匹配输入的内容,然后进行替换格式,然而匹配的内容如何进行MD5加密呢?这个问题困扰我很久了,今天看到友链禾令奇的文章,瞬间解决了我的疑问,不愧是dalao代码base64的话同理,为了加强学习,代码部分用的是截图,建议你们手敲一遍如果想看专业点的解释,请点击下方的声明链接声明:文章关键代码转自https://www.helingqi.com/archives/website-outside-chain-transformation-record.ht...

阅读文章
php获取网易云音乐地址

网易云官方有个这个东西http://music.163.com/song/media/outer/url?id=id.mp3,将id换为歌曲id进行访问就会302到歌曲地址。其实这就可以拿来直接用了,但是他默认的都是http渠道的而非https,即使你访问https://music.163.com/song/media/outer/url?id=id.mp3最后他跳转到的也是http的音乐链接。其实他本身是支持https的,只是全都默认http,这就很难受,所以我用php写了个小工具。<?php $id=$_SERVER["QUERY_STRING"]; $reg = '/^[0-9][0-9]*$/'; if(preg_match($reg,$id)){ $url = 'http://music.163.com/song/media/outer/url?id='.$id.'.mp3'; $headers = get_headers($url, TRUE); //print_r($headers); $url = $headers['Location']; $url = str_replace("http:","https:",$url); if($url=="https://music.163.com/404"){ header("Location: https://music.163.com/song/media/outer/url?id=".$id.".mp3"); exit; }else{ header("Location: ".$url.""); exit; } }else{ echo "非法参数"; } ?>访问php?id即可302转到https渠道的音乐链接。大家可以看到里面有个if判断,判断是否是404的,因为部分音乐可能因为xx原因,用这个php获取不到,获取不到就会返回404地址,如果返回这个的话,就302跳转到原来默认的http渠道链接。00:...

阅读文章
Fusion app解决安卓8以上首页面长按卡死问题【原创】

前言截至2018年6月17日fusionapp首页面安卓8手机长按都会卡死那么如何从用户方面来解决这个问题呢?经过测试只有首页面长按会卡死,子页面并不会……所以我就有个思路,用子页面代替掉首页面,避开bug区域具体操作如下:步骤一:在首页面的启动项里面加入退出页面() 进入子页面("伪装首页")这样用户打开app后直接就跳到子页面了,看不到首页【如果你首页面用的和我一样都是标签栏模板,请务必在组件→标签栏项目保留至少一项,不要全部删除,全部删除会报错哈】步骤二:建一个子页面,名字为“伪装首页”,然后在这个伪装首页的启动项里面加入shijian=0 function onKeyDown(code,event) if string.find(tostring(event),"KEYCODE_BACK") ~= nil then if shijian+2 > tonumber(os.time()) then 退出程序() end 弹出消息("再按一下退出键退出程序") shijian=tonumber(os.time()) return true end end因为首页面点击两次返回键会退出程序,而“伪装首页”没这个功能,所以启动项里面加上这个,伪装成何首页一样的效果步骤三:在“伪装首页”中设计你的首页面即可哈,如果要程序启动图的话,在原本的首页上开启启动图功能就行,代码不会影响启动图功能的。总结下其实这个解决方案几个月前我就弄出来了,当时直接用到自己做的博客客户端上了,然后源码也发fusionapp群里了,今天比较无聊,就把这一块的代码抽出来,写个文章...

阅读文章
php抓取一言数据

本来我博客的一言,都是来自https://github.com/kokororin/hitokoto/blob/master/hitokoto.json的,400多条的样子。刚刚自己有点不满足这些了,于是就像自己能不能试着扒一下一言的数据呢。从https://hitokoto.cn/status这个页面发现一言数目1461,应该就是一共的数量吧???直接请求https://v1.hitokoto.cn就可以获得一条一言的json然后开始弄$nr='[<br>'; //用于拼接内容,使其变成json格式 //设置超时参数 $opts=array( "http"=>array( "method"=>"GET", "timeout"=>3 ), ); $context = stream_context_create($opts); //超时这个部分我不懂,在网上随便复制的 for($i=0;$i<1461;$i++){ //设置循环变量,让其循环1461次 $json_string =file_get_contents('https://v1.hitokoto.cn/', false, $context); //抓取一条一言的json内容 $data = json_decode($json_string); //对JSON数据进行解码,转换为PHP变量 $id = $data->id; //定义id为一言json的id $a= array(); //创建一个空数组 $isin = in_array($id,$a); //判断一言id是否存在数组中,用来过滤重复抓取的一言数据 if($isin){ $i--; //如果存在,则i-1,然后重新执行for循环 }else{ array_push($a,$data->id); //不存在,将一言id存在数组里 $data_json = json_encode($data); //转为json格式 $dh=',<br>'; if($i==0){$dh='';} $nr=$nr.$dh.$data_json; //拼接内容,使其跟json格式对应 } } echo $nr.'<br>]'; //循环结束,输出最终内容刚写完的瞬间,内心只剩下了“完美”二字,然而我一运行,转圈圈...转圈圈...然后就404了。然后我内心依旧剩下两个字“垃圾”。然后我就将循环次数由1461改成了300,准备分批抓取,手动将抓取结果存txt,同时将这300条的数据id都输出出来,然后手动添加到原本建立的空数组中,然后进行第二批抓取...然后第三批...等等...最后我抓了1500条数据,我就不抓了累了,不过官方不是说就1461条数据吗?好奇怪!然后用https://www.bejson.com/验证了下格式,没啥问题就o...

阅读文章
css两端对齐布局

先上个Demo<!DOCTYPE html><html><head><title>两端对齐</title></head> <style type="text/css"> *{margin: 0;padding: 0;font-size: 18px;} .zuoyou{text-align:justify;text-align-last:justify;} ul{text-align:justify; text-align-last:justify;} li{display:inline-block;} </style> <body> <div class="zuoyou">这是一段测试文字</div> <ul> <li>第一</li> <li>第二</li> <li>第三</li> </ul> </body></html>实际效果一、div下的文本左右两端对齐让<div class="zuoyou">这是一段测试文字</div>这段文字左右端对齐,最开始只用text-align:justify;发现并没有效果,后来查资料说这个东西要求文字超过一行,于是就又加了句text-align-last:justify;。text-align:justify;→句子除了倒数第一句外,其他句子两端对齐text-align-last:justify;→句子的倒数第一句两端对齐二、列表元素的两端对齐这里那ul li举例,其中text-align:justify;和text-align-last:justify;同上,li的display:inline-block;是让三个li标签在同一行。display:inline-block;→不独占一行的块级元素注意li标签和li标签之间需要有回车或者空格,demo中三个li标签,用了一个空格和一个回车,测试都没问题。也就是说不能这么写<li>第一</li><li>第二</li><li>第三</li>要这么写<li>第一</li> <li>第二</li> <li>第三</li>不仅如此,对于IE8浏览器,列表元素不能处在font-size:0的环境下,至少code>font-size:1px,因为IE8浏览器font-size:0或直接把换行空格或普通空格抹掉而无法实现两端对齐效果。如果纠结ie6/7的话,可以看看真正大佬的文章http://www.zhangxinxu.com/wordpress/2011/03/displayinline-blocktext-alignjustify%E4%B8%8B%E5%88%97%E8%A1%A8%E7%9A%84%E4%B8%A4%E7%AB%AF%E5%AF%B9%E9%BD%90%E5%B8%83%E5%B1%8...

阅读文章
纯CSS显示JS/HTML等源代码行数

代码如下.code { padding: 10px 10px 10px 40px; font-size: 13px; line-height: 18px; background-color: #eee; font-family: "Lucida Console", Consolas, Monaco; white-space: pre-wrap; word-break: break-all; position: relative; overflow: hidden; } .code::before { content: '01.\A 02.\A 03.\A 04.\A 05.\A 06.\A 07.\A 08.\A 09.\A 10.\A 11.\A 12.\A 13.\A 14.\A 15.\A 16.\A 17.\A 18.\A 19.\A 20.\A 21.\A 22.\A 23.\A 24.\A 25.\A 26.\A 27.\A 28.\A 29.\A 30.\A 31.\A 32.\A 33.\A 34.\A 35.\A 36.\A 37.\A 38.\A 39.\A 40.\A 41.\A 42.\A 43.\A 44.\A 45.\A 46.\A 47.\A 48.\A 49.\A 50.\A 51.\A 52.\A 53.\A 54.\A 55.\A 56.\A 57.\A 58.\A 59.\A 60.\A 61.\A 62.\A 63.\A 64.\A 65.\A 66.\A 67.\A 68.\A 69.\A 70.\A 71.\A 72.\A 73.\A 74.\A 75.\A 76.\A 77.\A 78.\A 79.\A 80.\A 81.\A 82.\A 83.\A 84.\A 85.\A 86.\A 87.\A 88.\A 89.\A 90.\A 91.\A 92.\A 93.\A 94.\A 95.\A 96.\A 97.\A 98.\A 99'; position: absolute; top: 10px; bottom: 10px; left: 0; text-align: right; background-color: #fbfbfb; color: #333; outline: 100px solid #fbfbfb; clip: rect(-100px 2em 9999px 0); /* IE9+ */ clip: rect(-100px 3.5ch 9999px 0); overflow: hidden; }CSS构建代码行数的原理如下:使用::before伪元素content属性生成,这样不用担心网页框选复制代码的时候行数序号会污染。使用A控制字符的换行。::before伪元素绝对定位在左侧,祖先元素设置overflow:hidden隐藏多余的行数。核心CSS代码示意如下:.code { position: relative; overflow: hidden; } .code::before { content: '01.\A 02.\A 03.\A 04.\A 05.\A 06.\A 07.\A 08.\A 09.\A 10.\A 11.\A 12.\A 13.\A 14.\A 15.\A 16.\A 17.\A 18.\A 19.\A 20.\A 21.\A 22.\A 23.\A 24.\A 25.\A 26.\A 27.\A 28.\A 29.\A 30.\A 31.\A 32.\A 33.\A 34.\A 35.\A 36.\A 37.\A 38.\A 39.\A 40.\A 41.\A 42.\A 43.\A 44.\A 45.\A 46.\A 47.\A 48.\A 49.\A 50.\A 51.\A 52.\A 53.\A 54.\A 55.\A 56.\A 57.\A 58.\A 59.\A 60.\A 61.\A 62.\A 63.\A 64.\A 65.\A 66.\A 67.\A 68.\A 69.\A 70.\A 71.\A 72.\A 73.\A 74.\A 75.\A 76.\A 77.\A 78.\A 79.\A 80.\A 81.\A 82.\A 83.\A 84.\A 85.\A 86.\A 87.\A 88.\A 89.\A 90.\A 91.\A 92.\A 93.\A 94.\A 95.\A 96.\A 97.\A 98.\A 99'; position: absolute; }对,方法比较傻,就是一口气把99行序号在CSS中埋伏好。CSS方法实现的优缺点优点:简单,高效,性能十足,即使代码变来变去布局也OK。缺点:支持的行数有限,例如上面的demo最多支持99行代码。如果代码行数惊人,例如上千行,则建议辅助JS去生成序号,例如构建一段包含content内容的<style>插入到页面中。兼容性方法至少IE9+浏览器支持,IE8浏览器理论上支持。声明:以上内容转自http://www.zhangxinxu.com/wordpress/2018/02/pure-css-js-html-code-line-number/下面说说我是如何将其投入使用的吧!1,如何解决上文提到的→支持的行数有限,例如上面的demo最多支持99行代码?我是直接用php循环语句写了个循环,直接输出了个支持到8000行的css代码,理论上足够够用了【因为基本上没人会在网页上写上万行代码!】,css文件最终定格60多k的大小(捂脸)。2,为什么想用纯css的?在给博客代码高亮换成prismjs时,prismjs官网虽然可以选择行号组建,但是总会出现些问题(博主忘记问题是啥了,毕竟过去好几天了),然后就百度纯css的看看有没有前辈折腾过,没想到还真有,而且文章还挺新鲜的(2018年发表的),于是就想尝鲜3,感受文章开始处的padding-left 40px参数是给行号挪位置的,最初弄时可以设置的小一点,这样就方便看行号是否和代码对应上,没有错位!.code::before的top参数和bottom参数和.code的padding的top和bottom参数一...

阅读文章
最近痴迷Fusion app,于是给自己博客搞了个app

Fusion appFusion App 是一款将网页转成应用的app,而又不同于一般的转换,他具有丰富的模板,全面的图标仓库,还支持插入JavaScript,同时还可以用alua语言编写事件,函数之类的,还有元素删减功能。app作者还在b站演示了定制的酷安客户端...还有就是兼容性,貌似是安卓5.0起步酷安地址:https://www.coolapk.com/apk/cn.coldsong.fusionapp作者b站地址:https://space.bilibili.com/37644610其实我是在typecho群看到有人提到的这个app的,当时是测试版,就着手研究了下,挺有意思的,折腾了几个晚上。现在已经发布正式版了,功能更加强大了,于是乎决定发个文章分享下成果。QQ爹客户端如上图,这个app仿照了b站客户端的配色,支持博客的搜索功能,检查更新功能,分享功能,捐赠功能,联系作者qq功能等等。下载地址:https://qqdie.com/areyouok/qqdie1.4.5.apk过程皮肤:因为觉得在客户端中,点击文章下一页会很不文雅,所以专门用插件为了客户端写了个皮肤,支持滚动无限加载的,原理很简单,就是针对特定的ua开放插件皮肤【参考bufannaowap插件】,然后配合fusion app的ua自定义功能来实现的。因为是自己针对性写的皮肤,所以fusion app的元素删减功能,我都没用上哈哈哈。检查更新功能:参考了fusion app群里面的代码,然后自己写了一份,不得不说群里人的思路确实清奇,居然利用qq收藏链接来写,更新检测地址,腾讯的东西必然稳定的一逼哈哈哈!返回顶部按钮:悬浮的返回顶部按钮本来我是用默认的语法写的,后来发现他并没有平滑滚动,于是直接用JavaScript写的,毕竟我的皮肤还是加载了jq的,所以也就几行代码就ok了!捐赠功能和联系QQ:这两个功能直接在appdemo中超改的,就不叙述原理了QAQ。彩蛋功能:我不知道为啥痴迷彩蛋功能,于是也写了个简单的彩蛋,是一段音频,音频放到了drawable文件夹下,然后通过代码放出来,具体怎么触发,就不赘述了。体会:这玩意用来做视频解析app客户端真是绝配,虽然在自身app中全屏播放视频还是有点问题的,但是我相信未来会更好总结我觉得你们下我客户端概率很低,但是下载fusion app的概率会很高,欢迎喜欢折腾的人入坑!还有就是要说,仿照了b站客户端的配色后,我的app真的很好看!!!ps:该文章已得到fusion app作者同意发布【寒歌:随...

阅读文章
至顶至底 (雷姆拉姆)z-blog插件

既《至顶至底 (雷姆拉姆)emlog插件》,《至顶至底 (雷姆拉姆)WordPress插件》,特此发布z-blog版本的插件。网页左右下角分别是拉姆和雷姆,点击就会触发至顶至底功能,插件需要加载jquery,因为貌似z-blog博客程序默认就加载了jquery所以插件并没有内置jquery下载链接: https://pan.baidu.com/s/1dGkmfzN 密码: tenh插件源码include.php<?php #注册插件 RegisterPlugin("lamuleimu","ActivePlugin_lamuleimu"); function InstallPlugin_lamuleimu() {} function UninstallPlugin_lamuleimu() {} function ActivePlugin_lamuleimu() { Add_Filter_Plugin('Filter_Plugin_Zbp_MakeTemplatetags', 'lamuleimu_js'); } function lamuleimu_js(&$template) { global $zbp; $zbp->header .= "<link rel=\"stylesheet\" href=\"{$zbp->host}zb_users/plugin/lamuleimu/style.css\" type=\"text/css\">\r\n"; $zbp->footer .= "<div id=\"updown\"> <div class=\"sidebar_wo\" id=\"leimu\"> <img src=\"{$zbp->host}zb_users/plugin/lamuleimu/leimu_1.png\" alt=\"雷姆\" onmouseover=\"this.src='{$zbp->host}zb_users/plugin/lamuleimu/leimu_2.png'\" onmouseout=\"this.src='{$zbp->host}zb_users/plugin/lamuleimu/leimu_1.png'\" id=\"audioBtn\"> </div> <div class=\"sidebar_wo\" id=\"lamu\"> <img src=\"{$zbp->host}zb_users/plugin/lamuleimu/lamu_1.png\" alt=\"拉姆\" onmouseover=\"this.src='{$zbp->host}zb_users/plugin/lamuleimu/lamu_2.png'\" onmouseout=\"this.src='{$zbp->host}zb_users/plugin/lamuleimu/lamu_1.png'\" id=\"audioBtn\"> </div> <script src=\"{$zbp->host}zb_users/plugin/lamuleimu/ud.js\"></script>\r\n"; }效果图吐槽 插件打包后居然是zba格式,应该是为了保护付费插件源码吧,感觉好腻害,其实zip压缩包也通用吧23...

阅读文章
至顶至底 (雷姆拉姆)WordPress插件

既《至顶至底 (雷姆拉姆)emlog插件》插件发布后,特此发布WordPress版本的插件。链接: https://pan.baidu.com/s/1dGkScvR 密码: fppk下载解压后将文件夹名字改成lamuleimu,然后传到插件目录启用插件即可。插件默认加载了 jq,如果你的模板本身就加载了 jq,可以到插件设置中关闭加载。插件源码index.php<?php /* Plugin Name: 拉姆雷姆至顶至底插件 Plugin URI: https://qqdie.com/archives/top-to-bottom-rem-ram-wp-plugin.html Description: 网页左右下角分别是拉姆和雷姆,点击就会触发至顶至底功能 Author: Jrotty Version: 1.1 Author URI: https://qqdie.com */ define('LL_VERSION', '1.1'); define('LL_URL', plugins_url('', __FILE__)); define('LL_PATH', dirname(__FILE__)); require LL_PATH . '/leimu.php'; //添加设置页面 add_action('admin_menu', 'll_options'); function ll_options() { add_menu_page('拉姆雷姆', '拉姆雷姆', 'manage_options', __FILE__, 'll_options_code'); } //注册设置 add_action('admin_init','ll_setting'); function ll_setting(){ register_setting('ll_setting_group','ll_options'); } function ll_options_code(){ ?> <div style=" margin: 20px 10px 5px 0; border: 2px solid #707070; padding: 10px; "> <form method="post" action="options.php"> <?php settings_fields('ll_setting_group'); $jqq = get_option('ll_options'); $input = isset($_POST['mid'])?$_POST['mid']:''; $type = isset($_POST['select'])?$_POST['select']:''; ?> <div> <input type="checkbox" name="ll_options[jq]" class="autoplay" value="1" <?php checked('1',$jqq['jq']); ?> /><span>加载jq</span> <p><b>当前状态:</b><?php if($jqq['jq']==1){echo"已加载jq";}else{echo"已关闭加载jq";}; ?></p> </div> <p> 该插件需要加载jq,如果你的模板已经引用了jq,则可以取消勾选!!!</p> <input type="submit" name="save" class="button" value="保存设置" /> </form> </div> <?php if ( isset($_REQUEST['settings-updated']) ){ echo '<div id="message" class="updated"><p>保存成功了哦!</p></div>'; }?> <?php } ?>leimu.php<?php add_action('wp_enqueue_scripts', 'll_scripts'); function ll_scripts() { wp_enqueue_style('yodu-bgm', LL_URL . '/style.css', array(), LL_VERSION, 'all'); } add_action('wp_footer', 'll_bar'); function ll_bar(){ $jqq = get_option('ll_options'); echo '<div id="updown"> <div class="sidebar_wo" id="leimu"> <img src="'.LL_URL .'/leimu_1.png" alt="雷姆" onmouseover="this.src=\''.LL_URL .'/leimu_2.png\'" onmouseout="this.src=\''.LL_URL .'/leimu_1.png\'" id="audioBtn"> </div> <div class="sidebar_wo" id="lamu"> <img src="'.LL_URL .'/lamu_1.png" alt="雷姆" onmouseover="this.src=\''.LL_URL .'/lamu_2.png\'" onmouseout="this.src=\''.LL_URL .'/lamu_1.png\'" id="audioBtn"> </div>'; if($jqq['jq']==1){ echo'<script src="'.LL_URL .'/jquery.js" type="text/javascript"></script>'; } echo'<script src="'.LL_URL .'/ud.js"></script> '; }因为之前搞过YoduBGM的WordPress版插件,所以这次就在YoduBGM的代码中魔改出来了,这样能到达快速成品的效果!(其实就是懒)效果图吐槽相比emlog版本的插件来说,这个更走心一点,多了个插件设置功能,通过设置可以选择是否加载J...

阅读文章
至顶至底(雷姆拉姆)emlog插件

《博客被人丢进了雷姆》,《左雷姆右拉姆至顶至底源码》在发布这两篇文章后,其实很多网友已经给自己博客加上了这个萌化插件,甚至有人做出了Discuz插件(http://addon.discuz.com/?@dye_tbm.plugin)其实我之前的文章也说了有时间抽空做个插件版本的,于是今天搞出来了emlog版本的插件链接: https://pan.baidu.com/s/1kWRtqsv 密码: mduv下载解压后将文件夹名字改成lamuleimu,然后传到插件目录启用插件即可。插件默认加载了jq,如果你的模板本身就加载了jq,可以到插件的lamuleimu.php文件16行中,根据里面的提示删除jq加载。插件源代码<?php /* Plugin Name: 拉姆雷姆至顶至底插件 Version: 1.0 Plugin URL: http://qqdie.com Description: 网页左右下角分别是拉姆和雷姆,点击就会触发至顶至底功能 ForEmlog:5.3.x Author: Jrotty Author Email: bssf@qq.com Author URL: http://qqdie.com */ !defined('EMLOG_ROOT') && exit('access deined!'); function lamu(){ echo '<link rel="stylesheet" href="'.BLOG_URL.'content/plugins/lamuleimu/lamu.css" type="text/css">'."\r\n"; echo '<script src="'.BLOG_URL.'content/plugins/lamuleimu/jquery.js" type="text/javascript"></script>'."\r\n";//如果模板加载了jq,此行就可以删除了 } function leimu(){ echo ' <div id="updown"> <div class="sidebar_wo" id="leimu"> <img src="'.BLOG_URL.'content/plugins/lamuleimu/leimu_1.png" alt="雷姆" onmouseover="this.src=\''.BLOG_URL.'content/plugins/lamuleimu/leimu_2.png\'" onmouseout="this.src=\''.BLOG_URL.'content/plugins/lamuleimu/leimu_1.png\'" id="audioBtn"> </div> <div class="sidebar_wo" id="lamu"> <img src="'.BLOG_URL.'content/plugins/lamuleimu/lamu_1.png" alt="雷姆" onmouseover="this.src=\''.BLOG_URL.'content/plugins/lamuleimu/lamu_2.png\'" onmouseout="this.src=\''.BLOG_URL.'content/plugins/lamuleimu/lamu_1.png\'" id="audioBtn"> </div> <script src="'.BLOG_URL.'content/plugins/lamuleimu/ud.js"></script> '."\r\n"; } addAction('index_head', 'lamu'); addAction('index_footer', 'leimu');开头写明插件名字,插件版本,插件发布地址,插件描述,插件适合的版本,作者名字,邮箱,链接。然后写了两个函数,一个插在头部,一个插在尾部。效果图如下吐槽emlog程序官网居然必须登陆才能下载,注册需要邀请码,邀请码要钱!还有就是居然不兼容php7及以上!...

阅读文章
只对支持amp加速的搜索引擎开放amp功能

在上篇文章《Typecho 添加 AMP 支持》说了给博客加amp功能,但是我没说弊端233,这次说下优缺点。优点:1,amp确实很快捷2,支持amp功能的搜索引擎(比如谷歌),会优先amp页面,也就是说对seo有利缺点:1,对于不支持amp的搜索引擎来说,amp页面内容与原文重复,属于重复文章,可能反而不利于seo。2,amp页面会被缓存到支持amp功能的搜索引擎上,也就是说文章被收录后,如果再次被修改amp页面可能反应迟钝。3,移动端搜索引擎带来的ip会减少,毕竟别人浏览搜索引擎上的amp页面,实际是缓存到搜索引擎服务器上的,所以并不会直接产出ip。其实只有缺点1比较致命,所以本次就提出两个方案,着重讲第一个方案。方案一:网站端判断来源,如果是谷歌的蜘蛛或者百度的蜘蛛就允许amp功能开启(谷歌搜索引擎和百度搜索引擎支持amp)用百度搜索了下两家搜索引擎的特征,分别是Googlebot和Baiduspider。而谷歌用来测试amp是否生效的ua信息被我抓出来了Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; Google-AMPHTML)百度的用来缓存amp页面的ua不知道,但是肯定包含Baidu所以只要往简单了判断也就行了有了这些就万事俱备了,开始写判断<?php $ua=$_SERVER['HTTP_USER_AGENT']; $ua=strtolower($ua); $ampok=strpos($ua,"baidu");$ampko=strpos($ua,"googlebot");$ampo=strpos($ua,"google-amphtml"); if($ampok !== false || $ampko !== false || $ampo !== false){ //此处为amp页的功能实现代码 } ?>在调试过程中你可以安个Chrome插件User-Agent Switcher调试过程中来回切换UA会方便许多.感谢尚寂新提到的插件,省了好多力气。方案二:使用robots.txt来禁止所有搜索引擎来收录amp页面,然后只允许百度或者谷歌来收录amp页面(谷歌搜索引擎和百度搜索引擎支持amp)[只是一种思考,不知道对于seo是否真的有作用]题外话雅虎也支持amp,但是雅虎好像废了,搜狗也说支持amp,但是站长平台下,并没有看到amp的影子。故此文只提到谷歌and百...

阅读文章
续instantclick实现的全站无刷新

上次在《instantclick 实现的全站无刷新》中大致说了一下实现方式,但是随着大家对文章的关注,我发现有些细节被我遗漏了,同时也发现了存在的问题,下面就接着上篇文章在说一说。搜索功能这样的非超链接怎么实现不刷新上篇文章的代码不兼容火狐浏览器,所以将上篇文章中提到的这个代码$.extend({ getKey: function() { if(event.keyCode==13){ $('#soux').get(0).click(); } }, })改为$.extend({ getKey: function() { var theEvent = window.event || arguments.callee.caller.arguments[0]; var code = theEvent.keyCode; if(code == 13){ $('#soux').get(0).click(); } }, })instantclick的情况添加ajax评论需要将typecho的模板header.php中的<?php $this->header('); ?>改成<?php $this->header('commentReply='); ?>干掉模板自动输出的评论相关的js代码然后手动将刚刚屏蔽的代码加入到comments.php里面<script type="text/javascript"> (function () { window.TypechoComment = { dom : function (id) { return document.getElementById(id); }, create : function (tag, attr) { var el = document.createElement(tag); for (var key in attr) { el.setAttribute(key, attr[key]); } return el; }, reply : function (cid, coid) { var comment = this.dom(cid), parent = comment.parentNode, response = this.dom('<?php echo $this->respondId(); ?>'), input = this.dom('comment-parent'), form = 'form' == response.tagName ? response : response.getElementsByTagName('form')[0], textarea = response.getElementsByTagName('textarea')[0]; if (null == input) { input = this.create('input', { 'type' : 'hidden', 'name' : 'parent', 'id' : 'comment-parent' }); form.appendChild(input); } input.setAttribute('value', coid); if (null == this.dom('comment-form-place-holder')) { var holder = this.create('div', { 'id' : 'comment-form-place-holder' }); response.parentNode.insertBefore(holder, response); } comment.appendChild(response); this.dom('cancel-comment-reply-link').style.display = ''; if (null != textarea && 'text' == textarea.name) { textarea.focus(); } return false; }, cancelReply : function () { var response = this.dom('<?php echo $this->respondId(); ?>'), holder = this.dom('comment-form-place-holder'), input = this.dom('comment-parent'); if (null != input) { input.parentNode.removeChild(input); } if (null == holder) { return true; } this.dom('cancel-comment-reply-link').style.display = 'none'; holder.parentNode.insertBefore(response, holder); return false; } }; })(); </script&g...

阅读文章
YoduBGM一款WordPress背景音乐插件

YoduBGM 1.1.0是一款简洁 (简陋) 风格的背景音乐播放器,需要主题支持 pjax 技术,否则页面切换歌曲会断掉。背景音乐播放器那么多了为什么还要开发呢?而且还这么丑?答:其他的背景音乐播放器只能支持常规的 pjax 模板,而这个还支持使用instantclick.js的网站介绍:音乐默认不自动播放,需要点击音乐图标才会播放,第二次点击则暂停,首次播放是随机播放列表中的一首歌曲,然后顺序播放。>这个图标点击后会播放列表的下一首歌曲。插件后台可以设置音乐自动播放,可以添加歌曲,并且附带网易云音乐的解析器。下载地址:WordPress:yodubgm.ziptypecho版:https://github.com/jrotty/YoduBGMtypecho发布页面:《YoduBGM 一款 typecho 背景音乐插件》常见问题问:为什么有的时候只有两个框框而没有图标?(typecho可能遇到的问题,wp博客未知)答:图标载入的字体文件,只有用后台绑定的域名访问才会显示,比如程序后台绑定的是 qqdie.com, 那么用 www.qqdie.com 进行访问就会出现没有图标的情况,建议将 www.qqdie.com 的域名重定向到 qqdie.com 上。这样怎么访问都会访问到程序绑定的域名上,图标也会完美显示了。题外话:这是我的第一个WordPress博客程序的插件,其实本人对于wp真的不怎么了解,于是采用了拆蜜汁路易的音乐插件来学习的,过程中感觉最迷糊的就是wp插件设置那里,起初我怎么写都存不到数据库中,后来发现自己写错个字母233,也是醉...

阅读文章
APlayer Typecho插件兼容instantclick.js

超级推荐用这个大佬写的aplayer插件地址:https://github.com/MoePlayer/APlayer-Typecho然后在预加载重载函数里写上loadMeting();即可如果遇到切换页面音乐不停止的问题,再重载函数里再补充这条语句if (typeof aplayers !== 'undefined'){ for (var i = 0; i < aplayers.length; i++) { try {aplayers[i].destroy()} catch(e){} } }↓以下文章内容已弃用APlayer Typecho插件https://github.com/FaithPatrick/APlayer-Typecho-Plugininstantclick 3.0.1版兼容方法来自https://muguang.me/php/typecho-theme-apollo.html将预加载的执行代码<script data-no-instant> InstantClick.init(); </script>改为<script data-no-instant> if (!window.audios) { audios = []; for (var i = 0; i < APlayers.length; i++) { audios[i] = APlayers[i].audio; } } InstantClick.on('change', function (isInitialLoad) { for (var i = 0; i < APlayers.length; i++) { audios.push(APlayers[i].audio); } for(var i = 0; i < audios.length; i++) {if(audios[i]){audios[i].pause()}}; }); InstantClick.init(); </script> <script>var APlayerOptions = [];</script>//如果无效果尝试删掉这行instantclick 3.1.0版兼容[不完美]这个是我参考上边的瞎弄弄出来的,虽然完全看不懂QAQ。。。打开插件的plugin.php将里面的<script> var len = APlayerOptions.length; for(var i=0;i<len;i++){ if(document.getElementById('player' + APlayerOptions[i]['id'])) { APlayers[i] = new APlayer({ element: document.getElementById('player' + APlayerOptions[i]['id']), narrow: false, preload: APlayerOptions[i]['preload'], mutex: APlayerOptions[i]['mutex'], autoplay: APlayerOptions[i]['autoplay'], showlrc: APlayerOptions[i]['showlrc'], music: APlayerOptions[i]['music'], theme: APlayerOptions[i]['theme'] }); //APlayers[i].init(); } } </script>改为<script data-no-instant>//就是这里有修改,其他都没动 var len = APlayerOptions.length; for(var i=0;i<len;i++){ if(document.getElementById('player' + APlayerOptions[i]['id'])) { APlayers[i] = new APlayer({ element: document.getElementById('player' + APlayerOptions[i]['id']), narrow: false, preload: APlayerOptions[i]['preload'], mutex: APlayerOptions[i]['mutex'], autoplay: APlayerOptions[i]['autoplay'], showlrc: APlayerOptions[i]['showlrc'], music: APlayerOptions[i]['music'], theme: APlayerOptions[i]['theme'] }); //APlayers[i].init(); } } </script>将预加载的执行代码<script data-no-instant> InstantClick.init(); </script>改为<script data-no-instant> if (!window.audios) { audios = []; for (var i = 0; i < APlayers.length; i++) { audios[i] = APlayers[i].audio; } } InstantClick.on('change', function(isInitialLoad) { if (isInitialLoad === false) { var len = APlayerOptions.length; for(var i=0;i<len;i++){ if(document.getElementById('player' + APlayerOptions[i]['id'])) { APlayers[i] = new APlayer({ element: document.getElementById('player' + APlayerOptions[i]['id']), narrow: false, preload: APlayerOptions[i]['preload'], mutex: APlayerOptions[i]['mutex'], autoplay: APlayerOptions[i]['autoplay'], showlrc: APlayerOptions[i]['showlrc'], music: APlayerOptions[i]['music'], theme: APlayerOptions[i]['theme'] }); //APlayers[i].init(); } } for (var i = 0; i < APlayers.length; i++) {audios.push(APlayers[i].audio);} for(var i = 0; i < audios.length; i++) {if(audios[i]){audios[i].pause()}}; } }); InstantClick.init();</script&g...

阅读文章
instantclick实现的全站无刷新

instantclick是什么?instantclick是一个预加载的js文件,就是能提前加载网页内容的东西,他有几种模式,第一种就是鼠标放在超链接上就开始预加载,第二种就是鼠标放上去xx毫秒后(时间可自定义)进行预加载,第三种就是鼠标点击后进行预加载。项目官网:http://instantclick.io/项目地址:https://github.com/dieulot/instantclick使用这个预加载js因为前两种方式可能比较浪费资源,所以我们使用鼠标点击后进行预加载方式,代码类似如下<script src="instantclick.min.js" data-no-instant></script> <script data-no-instant>InstantClick.init('mousedown');</script>注:我使用的是instantclick3.1.0的版本。这里不着重讲instantclick的使用方法,建议去官网查阅搜索功能这样的非超链接怎么实现不刷新在香菇的点拨之下,我们强行将搜索功能表单模式变成了超链接,效果如下因为搜索结果地址一般为是站点地址加search加搜索内容如https://qqdie.com/search/搜索的内容/所以如上图所示,我们将搜索图标的超链接写为搜索地址https://qqdie.com/search/然后用js获取这个地址A,再将图标上的超链接清空,防止没有搜索内容却直接点击图标的情况。随后在事实获取输入框的内容B,然后将A和B拼接,就获得了最终地址C,然后将地址C添回图标的超链接地址上,这是我们点击图标就可以在预加载的条件下实现搜索内容了,代码如下:var bb=$("#soux").attr("href");//获取搜索地址 $("#soux").attr("href",""); //清空默认地址 $('#keyword').bind('input propertychange', function () { var aa=$("input[name=s]").val();//获取输入框内容 $("#soux").attr("href",bb+aa); //将拼接好的地址重新添加 });当然,这还不太完美,万一喜欢按回车呢,在监控下回车,在input上加上 onkeypress="$.getKey();",然后js代码上写上这个监控函数$.extend({ getKey: function() { if(event.keyCode==13){ $('#soux').get(0).click(); } }, })至此结束评论也不兼容呢然后找到了个可用的ajax评论的js,自己改了改就用上了,然后在友人C的帮助下,修复了评论嵌套的问题,然后他又提出个问题如果你启用了评论分页功能,由于typecho显示最新评论总是在第一页,所以当用户不在第一页发出了母评论,用户是看不到评论的,因为评论是在第一页最后我根据上边搜索功能的原理,用了几行代码修复了这个问题,最终ajax的评论js代码如下function ajaxc() { var txt_1 = '必须填写用户名', txt_2 = '必须填写电子邮箱地址', txt_3 = '邮箱地址不合法', txt_4 = '必须填写评论内容'; $body = (window.opera) ? (document.compatMode == "CSS1Compat" ? $('html') : $('body')) : $('html,body'); var comments_order = 'DESC', comment_list = '.comment-list', comments = '.comment-num', comment_reply = '.comment-reply', comment_form = '#comment-form', respond = '#comments', textarea = '#textarea', submit_btn = '.submit', new_id = '', parent_id = ''; click_bind(); $(comment_form).submit(function() { // 提交 $(submit_btn).attr('disabled', true).fadeTo('slow', 0.5); /* 预检 */ if ($(comment_form).find('#author')[0]) { if ($(comment_form).find('#author').val() == '') { toastr.info(txt_1); msg_effect('#error'); return false; } if ($(comment_form).find('#mail').val() == '') { toastr.info(txt_2); msg_effect('#error'); return false; } var filter = /^[^@\s<&>]+@([a-z0-9]+\.)+[a-z]{2,4}$/i; if (!filter.test($(comment_form).find('#mail').val())) { toastr.info(txt_3); msg_effect('#error'); return false; } } var textValue = $(comment_form).find(textarea).val().replace(/(^\s*)|(\s*$)/g, ""); //排除空格 if (textValue == null || textValue == "") { toastr.info(txt_4); msg_effect('#error'); console.log("内容为空"); return false; } $(submit_btn).addClass("active"); $('#loading').show(); $.ajax({ url: $(this).attr('action'), type: $(this).attr('method'), data: $(this).serializeArray(), error: function() { toastr.info("提交失败,请重试!"); msg_effect('#error'); return false; }, success: function(data) { //成功取到数据 //console.log(data); $(submit_btn).removeClass("active"); $('#loading').slideUp(); try { if (!$(comment_list, data).length) { toastr.info("提交失败,可能输入内容不符合规则!"); msg_effect('#error'); return false; } else { new_id = $(comment_list, data).html().match(/id=\"?comment-\d+/g).join().match(/\d+/g).sort(function(a, b) { return a - b }).pop(); // TODO:找新 id,如果在第二页评论的话,找到的ID是有问题的! if ($('.page-navigator .prev').length && parent_id == ""){ new_id = ''; var dd=$(".prev a").attr("href");//获取上页地址 $(".prev a").attr("href",""); //将地址清空 dd=dd.replace(/comment-page-(.*?)#comments/, "comment-page-1#comments");//将获取的地址页码改为1 $(".prev a").attr("href",dd); //将地址放回去 $('.prev a').get(0).click(); //点击这个超链接 }//判断当前评论列表是否在第一页,并且只会在母评论时候才会生效 console.log("new id " + new_id); msg_effect("#success"); //插入评论内容到当前页面 if (parent_id) { data = $('#li-comment-' + new_id, data).hide(); // 取新评论 if ($('#' + parent_id).find(".comment-children").length <= 0) { $('#' + parent_id).append("<div class='comment-children'><ol class='comment-list'></ol></div>"); } if (new_id)//new_id不为空的时候才会插入 $('#' + parent_id + " .comment-children .comment-list").prepend(data); console.log('该评论为子评论,parent_id:' + parent_id); parent_id = ''; //console.log(data); } else { data = $('#li-comment-' + new_id, data).hide(); // 取新评论 //console.log('该评论为母评论'); if (!$(comment_list).length) //如果一条评论也没有的话 $(respond).append('<div class="info-com">仅有<span class="comment-num">0<\/span>条评论<\/div><ol class="comment-list"><\/ol>'); // 加 ol $(comment_list).prepend(data); //console.log('评论内容:'); //console.log(data); } $('#li-comment-' + new_id).fadeIn(); // 显示 var num; $(comments).length ? (num = parseInt($(comments).text().match(/\d+/)), $(comments).html($(comments).html().replace(num, num + 1))) : 0; //console.log($('#comments h4').length); // 评论数加一 TypechoComment.cancelReply(); $(textarea).val(''); $(comment_reply + ' a, #cancel-comment-reply-link').unbind('click'); click_bind(); // 新评论绑定 $(submit_btn).attr('disabled', false).fadeTo('slow', 1); if (new_id){ $body.animate({scrollTop: $('#li-comment-' + new_id).offset().top - 50}, 500); }else{ $body.animate({scrollTop: $('#comments').offset().top - 50}, 500); } } } catch(e) { //alert('评论ajax错误!请截图并联系主题制作者!\n\n' + e); window.location.reload(); } } // end success() }); // end ajax() return false; }); // end $(comment_form).submit() function click_bind() { // 绑定 $(comment_reply + ' a').click(function() { // 回复 //$body.animate({scrollTop: $(respond).offset().top - 180}, 400); //console.log($(this).parent().parent().parent().parent()); parent_id = $(this).parent().parent().parent().parent().parent().parent().attr("id");//parent()数量根据模板而定,否则评论嵌套可能有问题 console.log("parent_id:" + parent_id); $(textarea).focus(); }); $('#cancel-comment-reply-link').click(function() { // 取消 parent_id = ''; }); } function msg_effect(id) { // 出错 $(submit_btn).attr('disabled', false).fadeTo('', 1); } } ajaxc();注:上述代码中提示功能使用了jquery通知插件toastr,如果你不想使用可将上述代码中的 toastr.info改成alert代码参考文章:原作者文章:http://www.iyanlei.com/typecho_ajax_comment.html友人C文章:https://www.ihewro.com/archives/691/注意本文中的所有代码都依靠jquery,且本文内容预加载模式只有选择第三种方法才能实现全站无刷新。相关文章已经有了更新《续 instantclick 实现的全站无刷...

阅读文章
css视口单位vw,vh的妙用(embed篇)

视频demo 如上视频[av9214469],使用的是embed标签,大家都知道embed的播放器很难自适应,不是过分拉伸改变视频比例,就是写死播放器长宽,导致不能随网页大小的变化自由变换尺寸。前天,在往博客上折腾B站视频时,无意间灵机一动,想到了个好主意,就是使用vw单位,配合使用calc。只需级行css就解决了核心css代码,锁死视频比例16:9embed { height: calc(9 * 100vw/ 16);width: 100%; }宽度设置为100%,宽度铺满父级div【假设父级div就是真个屏幕】,高度设置为屏幕的宽度乘以9/16。因为刚刚【假设父级div就是真个屏幕】这样假设了下,实际用起来肯定是多种情况的,比如我的博客电脑端是有侧边栏的,文章的div也是有边距的,而手机端只有边距没有侧边栏。其实只需要做个数学题就好。这里我得电脑端测栏加边距的宽度大约是330px,手机端的边距太小就忽略不算了对应的css就是这样@media only screen and (min-width:768px){ embed{height: calc(9 * (100vw - 330px)/ 16); width: 100%;} } @media only screen and (max-width:767px){ embed{ height: calc(9 * 100vw/ 16);width: 100%;} }其实就是对于电脑端设备,在宽度设置上,提前减去330px,然后在乘9/16。原理就是这样,因为我也没有去仔细计算我的模板边距测栏宽度总和是多少,所以比例不可能特别精准,还有就是现在iframe同样可以用上述方法。本来,文章写道这里就应该结束了,但是突然想到了香菇社长那个超宽的屏幕,仅仅是上述代码肯定会导致一个问题,视频高度可能会超出屏幕的高度。怎么办呢?想了一下,觉得这样比较简单!在电脑端css加入下面的东东max-height:100vh;/*限制视频高度最大不能超过浏览器窗口高度*/ max-width:calc(16 * 100vh/ 9);/*限制视频宽度最大不能超过浏览器窗口高度的16/9*/这样不管屏幕多奇葩,应该也能保证视频播放器尺寸16:9了哈!如果想要其他尺寸对应的数字改一下就好了。至于有黑边问题,这个原因有很多,视频素材比例问题?embed播放器尺寸问题?...

阅读文章
instantclick兼容Prismjs插件

最近yodu模板的用户要求我兼容typecho的Prismjs代码高亮插件,其实在《pjax(InstantClick) 常用的重载函数》中我就提到了Prismjs的pjax重载代码,但是经测试,还是有问题,于是今早又折腾了下,找到了方法。插件方面改动打开Prismjs代码高亮插件的Plugin.php文件在第58行找到<script>var pres = document.getElementsByTagName('pre');改成<script data-no-instant>var pres = document.getElementsByTagName('pre');在第64行找到<script src="' . $jsUrl . '"></script>改成<script src="' . $jsUrl . '" data-no-instant></script在第66行找到<script defer="defer" src="' . Helper::options()->pluginUrl . '/Prismjs/line-number-wrap-fix.js' . '"></script>改成<script defer="defer" src="' . Helper::options()->pluginUrl . '/Prismjs/line-number-wrap-fix.js' . '" data-no-instant></script>就是挨个加data-no-instantinstantclick模板方面调整在重载函数里添加 if (typeof Prism !== 'undefined') { Prism.highlightAll(true,null);}这样,代码高亮就完全好使了但是随后又发现行号会不显示,于是想在重载下行号的函数,整理下就是如下代码 if (typeof Prism !== 'undefined') {<?php if (Helper::options()->plugin('Prismjs')->showln): ?> var pres = document.getElementsByTagName('pre'); for (var i = 0; i < pres.length; i++){ if (pres[i].getElementsByTagName('code').length > 0) pres[i].className = 'line-numbers';}<?php endif; ?> Prism.highlightAll(true,null); }php部分判断插件是否使用了显示行号,使用就重载行号函数;因为是对插件进行了判断,所以如果没启用插件,直接用上面代码会导致网站错误50...

阅读文章
CSS视口单位的一次深度使用

什么是视口单位?在CSS规范中,有4种类型的可用视口单位:vw — 1vw 等于视口宽度的 1%vh — 1vh 等于视口高度的 1%vmin — vw 和 vh 中的较小值vmax — vw 和 vh 中的较大值视口,即浏览器屏幕大小,1vw 等于浏览器宽度的 1%,100vw 即整个浏览器的宽度。简单来说,它和px,rem一样就是个单位,适当的使用这种单位有时候能出奇效。注:IE9使用vm代替vmin。它不支持vmax。澄清:1vmax等于1vh在纵向模式,而在横向模式下,1vmax将等于1vw。个人建议:使用视口给元素设置宽高时,为了避免比例不协调,使用同一个单位比较好,如vmin、vmax。兼容性IE9+局部支持,chrome/firefox/safari/opera支持,ios safari 8+支持,android browser4.4+支持,chrome for android39支持博主使用情况我在 https://tool.qqdie.com/ 上就深度使用了这个单位,甚至字体大小都用这个设置的。费了很久的时间去调试,现在在我电脑上看已经感觉可以了但是,如果你的显示器很大,那么字体也会超乎寻常的大还有就是高度设置成100vh在一些手机浏览器上显示上有些奇怪,100vh应该是铺满全屏,但是在手机浏览器上却可以滚动,相当于高度设置多了,猜测原因是视口可能计算了手机整个屏幕的视口,而不是浏览器视口。yodu模板上只有一处使用了视口单位,因为写模板时已经忘记这个单位了,后来因为模板有个地方不是很美观求助香菇时,他提到了这个才想起来,于是用上了下。博主评价正常写模板建议还是主要用px,rem等传统单位,视口单位作为辅助单位比较好。视口单位,解决某些问题会有奇效,但是如果作为主要单位使用时会很坑....

阅读文章