缘网大杀器

脚本由来

这个脚本可是好老好老了,大概1年半前写的吧。那个时候人还在深圳出差,晚上回宾馆无聊就开始折腾这个。最初的时候我只是写了一个去广告的样式,将 缘网 一些根深蒂固的悬浮广告隐藏掉,让页面干净点。可惜好景不长,缘网改动了页面结构,结果我的样式就失效了。在校内使用的同学在98的帖子后面反馈,我马上用Firebug查看,改样式,又可以用。接下来的好几天,就这样一直在拉锯战,不知道是我RP不好,刚好遇到缘网在改页面还是其它原因,至今我也不大清楚了。

后来,我也厌倦了经常要改样式,而且纯粹样式在缘网页面下稳健性太差了,因为缘网的页面几乎没有一个有id或者class属性的元素,定位某个元素基本上都需要使用父子兄弟等选择器,结果就是缘网一改就挂。最后,我将该脚本分成两个部分:一部分是用Greasemonkey或者Scriptish安装的用户脚本;另外一部分是用Stylish安装的用户样式。

用户样式中首先将页面的所有内容全部隐藏:

/* Hide anything first */
body > * { display: none !important; }

继续阅读

天气预报脚本 Weather Forecast

脚本地址: http://j.mozest.com/zh-CN/userscript/script/9/ (主脚本)
脚本依赖: http://userscripts.org/scripts/show/99374 (天气图标)
脚本最新版本:0.8.3
安装要求:Firefox + Scriptish或者Firefox + Greasemonkey

简介

本脚本目前仅支持Firefox浏览器,通过webxml网站提供的Webservice API获得天气数据,数据来源于中国气象局。它的数据大概每隔2.5小时左右自动更新一次,包括大约340多个中国主要城市和60多个国外主要城市三日内的天气预报数据。

根据web服务提供网站的接口文档说明:

免费用户24小时内查询不超过50次并且获取二次数据大于间隔 600ms。官方数据2.5小时更新一次,本脚本也是按照2.5小时的间隔作缓存处理,因此在该间隔时间内, 若再次查询则返回缓存的信息。因此以上规定对我们使用该服务不会造成影响。

以下分别介绍脚本的使用方法、用户配置及错误反馈等内容。

继续阅读

JavaScript 面向对象编程一:类型系统

本系列均参考了大量网上相关的内容,并基于此总结并归纳,作为个人笔记,也供同样与我一样初涉JavaScript面向对象编程的同学一同学习讨论。

前言

网上有非常多的介绍JavaScript类型的内容,关于类型的分类众说纷纭,各执一词,一些矛盾的观点往往会让我们感到非常困惑。后来我仔细想了 想,与其在这种泥苦苦挣扎,还不如就近找一根救命稻草抓住。当然,这种观点可能比较激进,但是有时候确实需要做些取舍与选择。选择一种你觉得相对比较正 确,并且可以接受的答案。

类型系统

本文的类型分类依据来源于aimingoo的博客中关于JavaScript类型的几篇博客文章[1][2][3]

Javascript有两套类型系统:基础类型系统与对象类型系统。

继续阅读

Chrome 的 Content Scripts 扩展开发

这篇博客以讲解Chrome的 Content Scripts 扩展开发过程为主,并在该过程中穿插与Greasemonkey用户脚本的比较。本人初次尝试Content Scripts类型的扩展,有不足之处,请不吝指出。

前言

现在使用Chrome浏览器的用户越来越多,在写用户脚本的时候有时候必须得同时考虑多个浏览器的兼容情况(当然比起前端开发要简单多了)。我一般仅考虑Firefox和Chrome两个浏览器,原因有以下几个:

  1. 相比之下,两者的用户群体比较大,因为会寻找用户脚本的朋友一般都在用这些浏览器,很少是IE的,至少是同样采用Webkit内核的搜狗、傲游等。
  2. 两者的内核中对JavaScript的实现相对比较遵循W3C规范,因此只要尽量避免使用特定于某个浏览器的功能,一般的情况脚本都可以通用。
  3. 两者的用户脚本格式比较接近,前期是Chrome兼容Firefox的Greasemonkey扩展的格式,现在两者估计很多地方都是互相借鉴的。

继续阅读

浅谈 JavaScript 刷新页面

本文的所有代码在Firefox 11 beta + Scriptish 0.1.7环境作为用户脚本执行,某些行为可能会与普通的页面脚本不一致。

问题引出

在写CC98 Reply Improved脚本的时候,遇到一个场景是在帖子回复成功后,页面自动刷新,并且当引用或者编辑回复时,希望可以返回到当前被引用或者编辑的帖子楼层。在98中每个楼层都有一个锚链接(anchor), 这些锚链接的名称为数字,从0~9,其中1表示第一楼,2表示第二楼……0表示第十楼。假设当前的帖子链接为:

/dispbbs.asp?boardID=39&ID=3841624&star=20&page=1

则要跳转到第5楼,则需要在浏览器输入地址

dispbbs.asp?boardID=39&ID=3841624&star=20&page=1#5

其中#5这部分称为hash(我不大清楚中文应该叫什么)。

我们知道当在浏览器地址栏中输入与当前页面地址不同的目标地址时,浏览器会为我们载入目标页面;当目标地址与页面地址相同时,则页面不会刷新。即使上文所介绍的hash部分的内容不一样,页面同样不会刷新,而只是会在页面内部跳转到该hash值所指定的锚链接位置。假设帖子地址为:

dispbbs.asp?boardID=39&ID=3841624&star=20&page=1#5

若将末尾的#5改成#6,页面会跳到第6楼帖子而不会刷新,一般情况下这是可以接受的默认行为。

问题解决

回到最初的场景需要,在帖子回复之后需要刷新并跳转到相应的楼层,会遇到以下几种情况:

  1. 目标地址与当前地址不同。
  2. 目标地址与当前地址完全相同。
  3. 目标地址与当前地址仅hash部分不相同。

其中,第一种情况和第二种情况的解决方法比较简单,分别使用location.hreflocation.reload()即可解决:

location.href = targetURL;  // 第一种:将目标地址赋值给location.href
location.reload();   // 第二种:直接刷新本页面

然后,第三种情况相对比较麻烦,若以第一种的方法考虑,页面并不会刷新。因此需要寻找另外一种方法:在将页面地址改变后再打开新的页面地址。我想到的方法是两种,分别为:

// 第一种方法,使用setTimeout推迟刷新时间
location.href = targetURL;
setTimeout(function () {
    location.reload();
}, deferTime);

// 第二种方法,监听hashchange事件
location.href = targetURL;
window.addEventListener('hashchange', function () {
    location.reload();
}, false);

第一种方法依赖deferTime这个时间的设置,这个值设置得太小页面依然不会刷新,太大则会延迟刷新的动作,用户感觉不佳。

第二种方法监听hashchange事件(当地址的hash部分变化时会触发该事件),当地址的hash部分变化时,首先将当前页面的地址设置成目标楼层地址,此时页面并不会刷新,因此需要在事件监听函数中执行刷新动作,因为此时页面地址已经是目标楼层的地址,刷新后可以达到最初需要中提到的效果。

但是若一直监听hashchange事件,则任何一次hash变化都会执行我们设定的hashchange事件处理函数,因此这算是一个副作用,解决的方法是使用jQuery中的.one()方法来注册事件处理函数,该处理函数只会执行一次,执行完后自动取消监听。脚本中与此相关的代码片断为:

 function replySuccess() {

    // ..... 省略前文代码

    /* Fix: 回帖后地址不刷新 */
    /* 当URL Hash部分变化时, 刷新页面 */
    $(window).one('hashchange', function () {
        location.reload();
    });

    if (equalURL(location.href, url)) // 地址相同则直接刷新
        location.reload();
    else // 否则, 更换地址栏地址
        location.href = url;
}

/* 判断两个地址是否相同 */
function equalURL(lhs, rhs)
{
    /* 标准化 */
    lhs = getRelativeURL(lhs).toLowerCase();
    rhs = getRelativeURL(rhs).toLowerCase();

    return (lhs == rhs);
}