JavaScript有个叫“变量提升”的特性,意为:
在函数里声明的所有变量会被提升到函数顶部声明(但不涉及到赋值)。
示例:
var a=0; !function(){ alert(a); var a=1; }()
在函数外声明了变量a=0,之后在函数里重新声明了a=1。
在这中间我们弹出a,它的值不是0,而是undefined。这就是变量提升导致的。发生变量提升之后,函数里声明的a被提升到函数顶部声明了(但这并不涉及到赋值),所以代码实际上相当于这样:
var a=0; !function(){ var a; alert(a); a=1; }()
所以如果函数外已经声明了一个变量,那么就不要在函数内重复声明它,这样将会触发变量提前,可能会造成一些问题。
如果需要在函数内重复声明,那么将这些变量在函数顶部先声明但不赋值(就是写得和变量提升后的实际代码一样),可以让代码更直观。
其实这个概念是我昨天发布了搜索bilibili评论工具时,8q给我指出的。今天看书很巧的也看到了这个地方,弄清楚了。
JavaScript中的变量提升
此工具已失效!
我用JavaScript写了一个小工具,在b站视频播放页面执行,可以在当前视频的所有评论里查找指定用户发出的评论。
举个例子:你(或是别人)在某视频下发了一条评论,但没记住楼层。现在,如果你想要在众多评论里找到自己(或其他某个人)发的评论,可以使用本工具。
本工具可以搜索完所有的楼层,但查找楼中楼时,本工具只能查找到每个楼中楼的前5条回复(所以对于楼中楼,可能会有遗漏)。
如果你有油猴扩展,可以到UserScript安装页面安装此用户脚本。
如果你没有油猴扩展,你可以手动执行代码。下面提供两种执行方式:
1.控制台执行以下代码,它会远程加载js文件来执行:
var newscript=document.createElement("script"); newscript.src="/f/bilibili_comment_search.js"; document.body.appendChild(newscript);
这种方法的话,由于我的js的url是http的,所以在B站的https页面里无法执行,可以在地址栏把b站这个页面的网址手动改成http的。
2.下载js文件,然后手动复制其代码到控制台执行。
代码执行之后,在视频上方会出现“查找评论”的文字:
点击它,输入想查找的用户的id(就是打开TA主页时网址里的数字)。之后,每当找到这个人发的一条评论,就会在控制台输出该评论的楼层信息。
注意要在控制台看哦~我们可以根据页数和楼层数提示去找到这条评论。
如果工具搜索完了所有评论,会弹出搜索到了几条结果。如果你想中途停止搜索,点击视频上方的提示文字即可。
Read More →
在bilibili评论区搜索某人评论的工具
假设现在获得了一些格式化的时间/日期字符串,如何用JavaScript对其排序呢?
理想的办法就是用Date.parse()方法将这些字符串解析为时间,直接比较它们的毫秒数。示例如下:
function sortDate(sortby) { return function(object1, object2) { var value1 = Date.parse(object1); var value2 = Date.parse(object2); if(value1>value2){ return (sortby==="desc")?-1:1; }else if(value1<value2){ return (sortby==="desc")?1:-1; } } } var a=["2017/4/20","2016/6/3","2016/7/1","2016/7/27","2017/8/4","2016/10/13","2016/12/27","2017/1/14","2017/2/3","2017/2/3","2017/2/3","2017/2/3","2017/2/3","2017/2/3","2017/2/3","2017/3/1","2017/3/1","2017/3/1","2017/3/1","2017/3/1","2017/3/1","2017/3/1","2017/3/23","2017/3/31","2017/5/19","2017/5/19","2017/6/2","2017/6/24","2017/6/24","2017/6/24","2017/9/1","2017/9/5","2017/12/12","2018/2/19","2018/9/26","2017/5/19","2017/3/9","2017/7/14","2017/5/19","2017/5/19"]; a.sort(sortDate("desc"));
结果如下:
上例定义了一个sortDate函数,我们在数组的sort方法里将它作为参数。如果不手动设置排序参数为desc,那么这个函数将始终按升序排序。
标准的时间/日期格式如下:
"2017/4/20 16:20:30"
当然,只用一部分,或者改变下连接符,也是可以解析的。
Read More →
JavaScript对日期排序
这蛋疼的玩意……
更蛋疼的是这网站的备案根本不是我去备的……
好了不扯废话了,这封邮件意思是这样的:
这个域名是通过阿里云备案的,因此这个域名必须使用阿里云旗下的服务器(这个是正常的)。
现在在阿里云的服务器上找不到有这个域名的内容,所以被判定为空壳网站,将要被注销备案。
其实网站是有内容的,只是没放在阿里云上。但管局只看你在阿里云上有没有内容,不管你是不是放在了其他地方。(所以说备案备的是主机,不是域名)
你问我这个域名为什么会这样,我可以回答无可奉告,但你又不高兴。其实这个域名是快速备案弄的。网站从来就没放在阿里云的服务器上(我们也没有阿里云的服务器),但是备案的人走的是阿里云。现在似乎是事情败露的感觉?
实际上要解决的话,不需要我们把整个网站都迁移到阿里云上面去。我们可以买一个最低配置的空间或服务器,然后只解析一个无关紧要的二级域名上去就行了,这样不会影响我们网站的正常运转。当然,解析的这个二级域名里还得放些页面,不能是一个空站。这样就可以通过它的检查了。
其实阿里云和其他大部分主机商有个区别。我们提交备案时管局会记录我们服务器的ip。在其他主机商那里,如果你换了一台服务器(即使还是他们家的服务器),但ip变了,就得做变更备案。阿里云则不然,只要你服务器是在阿里云旗下,ip变了也不用做变更备案(至于是不是阿里云会在后台自动做变更,我不知道)。这算是个方便的地方吧。
关于在阿里云备案的“空壳网站”被注销备案的问题
前天换掉了某网站上的两张图,但是在浏览器里看死活就刷新不过来。就算把这张图片删掉也还是能打开。
后来ping了一下域名,ip竟然不是我们服务器的ip。
我去百度云加速里查看解析记录,发现解析的是对的。
于是我就去问客服小哥,他们说ping到的ip是他们百度的节点ip。
我忽然间明白过来了,图片没改变是百度缓存导致的吧。
于是我去清除了下cdn缓存,果然好了。
这问题折腾了我一个小时,心好累。
被百度云加速CDN缓存坑惨了的我在伤心过后决定控诉它
如果我们启用了WordPress的固定链接,那么每篇文章都会有一个短链接和一个固定链接。短链接是数字id,固定链接则是根据我们预设的格式生成的。
如本文有以下两个链接可以打开:
获取WordPress文章的短链接http://www.saber.love/获取wordpress文章的短链接
由于短链接是不会变的,而固定链接却可以被修改,所以发布网址时,使用短链接更加可靠。
以前WordPress在编辑文章时有个获取短链接按钮,现在没有了。我照网上说的一些方法也没能让它显示出来。不过仍然有两个办法可以看到短链接:
1.编辑文章时点击预览,在预览页面的url里包含有文章id。发布过的文章、没有发布的文章,都可以这么看。
2.在文章的前台页面里,也保存有短链接。我们可以执行如下代码获取它:
document.querySelectorAll("link[rel=shortlink]")[0].href
获取WordPress文章的短链接
因为JavaScript水平太渣,以前我都是用JQuery来做ajax。现在看了些资料,感觉原生的写法也不难,而且兼容性也已经不错了,所以跟着练一练。
同步的ajax请求:
var xhr=new XMLHttpRequest(); xhr.open("get","http://saber.我爱你/demo/checknew.php",false); xhr.send(null); if (xhr.status===200) { alert(xhr.responseText); }else{ alert("发生了异常,状态码为"+xhr.status+","+xhr.statusText); }
返回的数据里有如下属性:
responseText:作为响应主体被返回的文本。
responseXML:如果响应的内容类型是"text/xml"或"application/xml",这个属性中将保存包含着响应数据的XML DOM 文档。
status:响应的HTTP 状态。
statusText:HTTP 状态的说明。
异步的ajax请求:
var xhr=new XMLHttpRequest(); xhr.onreadystatechange=function(){ if (xhr.readyState===4) { if (xhr.status===200) { alert(xhr.responseText); }else{ alert("发生了异常,状态码为"+xhr.status+","+xhr.statusText); } } } xhr.open("get","http://saber.我爱你/demo/checknew.php",true); xhr.send(null);
检测状态的部分也可以这样写:
xhr.onload=function (argument) { if (this.status == 200) { //…… } }
异步请求除了在xhr.open里将最后的参数设置为true之外,在接收数据时也和同步请求不同。异步请求通过检查xhr对象的readyState属性来判断请求处在哪个阶段。当readyState为4时,表示接收到了数据,并且数据可用。
我们通过onreadystatechange事件来检测readyState的值,当值为4时即可对数据进行处理。
另外,在接收到响应之前还可以调用abort()方法来取消异步请求。即xhr.abort(); 。
原生Ajax的简单实例
php中最常用的截取文字的函数是substr(),但是在该函数中,中文占用2个或3个长度,所以可能把汉字截断,产生乱码。
有一个办法是使用mb_substr()来截取文字。这样确实可以,因为mb_substr()把所有文字都当做一个长度,所以截取中文时是整个字截取的,不会乱码。但mb_substr()的长度计算方法和substr()不同,有时候反而不能用它。经过一番苦搜,我找到了用php的ord()函数来截取文字的办法。
这种方法的字数计算方法和substr()一致,但不会导致汉字被截断.如果指定的长度会截断汉字,它会把因截断而产生的残缺汉字扔掉(以最后截取出来的长度有可能会比指定的长度少一两位。)。
另外它的参数也只有两个,一个是字符串,一个是截取长度。没错,它不能指定起始位置。
GBK版本:
function gb2312_substr($str, $limit) { $restr =''; for($i=0;$i< $limit-3;$i++) { $restr .= ord($str[$i])>127 ? $str[$i].$str[++$i] : $str[$i]; } return $restr; }
UTF-8版本:
function utf8_substr($str, $limit) { $restr = ''; for($i=0;$i< $limit-3;$i++) { $restr .= ord($str[$i])>127 ? $str[$i].$str[++$i].$str[++$i] : $str[$i]; } return $restr; }
php截取中文不乱码的代码
function http_status($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_NOBODY, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 5); curl_exec($ch); $status = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return $status; }
可以用这个函数来获取url请求的状态码,判断404很方便→_→
不过如果测试p站图片url的话,还得加上refer信息来绕过防盗链。
一个下载器搞得我找了好多php的东西,心好累。
php获取url的状态码
先吃我大鼻孔
今天我在改进pixiv下载器,想把tag信息保存到文件名里。前两天我研究了“windows中文件名最大长度的问题”,也是为这个做准备。我很快把获取tag的代码写好了,也在php里限制了文件名最大长度。但是做完之后感觉有点不对劲。怎么不对劲呢?下载图片的失败几率比以前大大提高了。错误都是:
Warning:fopen() Invalid argument
那么到底文件名哪里不对呢?这问题折腾了我五六个小时,我下班都没回去,坐在办公室里还在研究这个问题。天见可怜,我终于还是找到了问题的真相。
问题还是出在长度上。
windows计算文件名(包括路径)都是按【字数】算的,也就是说,不管你是中英混合还是怎么的,都能写满256个字。
我以为用php去创建文件也可以这样,于是我在php里用mb_strlen()函数去计算字数,这个函数也是把一个文字当做一个长度算。结果我这样做是错的,php虽然也会限制文件名和路径长度之和不能超过256个字符,但它真的只是字符长度,不是字数。所以php里操作文件时,涉及到文件名长度,要使用strlen()函数。
strlen()的计算方法是,英文占一个字符,而中文字符在gbk编码中算两个字符,在utf8编码中算三个字符。还好我使用的gbk编码,否则能用的字数要更少了。
下面这个路径在php的gbk编码中算做256长度(字节?):
F:\wamp\www\t/pixivimg/专辑1422_ 【一无所有的“死亡回归”!】Re 从零开始的异世界生活特辑 /56938050_p0_tag-ナツキスバル,Re ゼロから始める異世界生活,スバル,菜月昴,ゼロから始める異世界生活,リゼロ,リゼロ500users入り,Re ゼロから始める異世界00usersxxxxxxx入り.jpg
当然,用windows的计算方式,刚到170个长度。
好吧……为了在有限的长度里多给tag腾腾地方,我把文件名里很多东西都去掉了。标题啊,日期啊什么的都扔了,只留下图片id和tag。现在的文件名是这样的:
19566474_p0-よんでますよ、アザゼルさん。,十点じゃ足りません!,ふつくしい,なにこれ綺麗,サラマンダーwwwwww,一体だけ浮いてるw,まんまですよ、マンダはん,アザゼルさん1000users入り,キャプショ.jpg
这个长度已经接近极限了。心好累,感觉不会再爱了。