Javascript Timeout Hacks

Our first user script simply displays an alert saying “Hello world!” when it is executed.

Example: Display the “Hello world!” alert

Although this code looks obvious enough, and does exactly what you would expect, Greasemonkey is actually doing a number of things behind the scenes to ensure that user scripts do not interact badly with other scripts defined by the original page. Specifically, it automatically wraps your user script in an anonymous function wrapper. Ordinarily you can ignore this, but it will eventually creep up and bite you in the ass, so you may as well learn about it now.
One of the most common ways this can bite you is that variables and functions that you define in a user script are not available to other scripts. In fact, they are not available at all once the user script has finished running. This means that you will run into problems if you are expecting to be able to call your own functions later by using the window.setTimeout function, or by setting string-based onclick attributes on links and expecting Javascript to evaluate your function names later.
For example, this user script defines a function helloworld, then attempts to set a timer to call it one second later.

Example: Bad way to delay calling a function

This will not work; no alert will be displayed. If you open JavaScript Console, you will see an exception displayed: Error: helloworld is not defined. This is because, by the time the timeout expires and the call to helloworld() is evaluated, the helloworld function no longer exists.

If you need to reference your user script's variables or functions later, you will need to explicitly define them as properties of the window object, which is always available.

Example: Better way to delay calling a function

This works as expected: one second after the page loads, an alert pops up proudly displaying “Hello world!

However, setting properties on window is still not ideal; it's a bit like using a global variable when a local one will do. (Actually, it's exactly like that, since window is global and available to all scripts on the page.) More practically, you could end up interfering with other scripts that were defined on the page, or even other user scripts.
The best solution is to define an anonymous function yourself and pass it as the first argument to window.setTimeout.

Example: Best way to delay calling a function


What I'm doing here is creating a function without a name (an “anonymous function”), then immediately passing the function itself to window.setTimeout. This accomplishes the same thing as the previous example, but it leaves no trace, i.e. it's undetectable to other scripts.
I find that I use anonymous functions regularly while writing user scripts. They are ideal for creating “one-off” functions and passing them as arguments to things like window.setTimeout, document.addEventListener, or assigning to event handlers like click or submit.

C#的疑问

一个C#睡前故事

从 前,在南方一块奇异的土地上,有个工人名叫彼得,他非常勤奋,对他的老板总是百依百顺。但是他的老板是个吝啬的人,从不信任别人,坚决要求随时知道彼得的 工作进度,以防止他偷懒。但是彼得又不想让老板呆在他的办公室里站在背后盯着他,于是就对老板做出承诺:无论何时,只要我的工作取得了一点进展我都会及时 让你知道。彼得通过周期性地使用“带类型的引用”(原文为:“typed reference” 也就是delegate??)“回调”他的老板来实现他的承诺,如下:

接口

现在,彼得成了一个特殊的人,他不但能容忍吝啬的老板,而且和他周围的宇宙也有了密切的联系,以至于他认为宇宙对他的工作进度也感兴趣。不幸的是,他必须也给宇宙添加一个特殊的回调函数Advise来实现同时向他老板和宇宙报告工作进度。彼得想要把潜在的通知的列表和这些通知的实现方法分离开来,于是他决定把方法分离为一个接口:

委托

不幸的是,每当彼得忙于通过接口的实现和老板交流时,就没有机会及时通知宇宙了。至少他应该忽略身在远方的老板的引用,好让其他实现了IWorkerEvents的对象得到他的工作报告。(”At least he'd abstracted the reference of his boss far away from him so that others who implemented the IWorkerEvents interface could be notified of his work progress” 原话如此,不理解到底是什么意思:))

他的老板还是抱怨得很厉害。“彼得!”他老板吼道,“你为什么在工作一开始和工作进行中都来烦我?!我不关心这些事件。你不但强迫我实现了这些方法,而且还在浪费我宝贵的工作时间来处理你的事件,特别是当我外出的时候更是如此!你能不能不再来烦我?”

于是,彼得意识到接口虽然在很多情况都很有用,但是当用作事件时,“粒度”不够好。他希望能够仅在别人想要时才通知他们,于是他决定把接口的方法分离为单独的委托,每个委托都像一个小的接口方法:

静态监听者

这样,彼得不会再拿他老板不想要的事件来烦他老板了,但是他还没有把宇宙放到他的监听者列表中。因为宇宙是个包涵一切的实体,看来不适合使用实例方法的委托(想像一下,实例化一个“宇宙”要花费多少资源…..),于是彼得就需要能够对静态委托进行挂钩,委托对这一点支持得很好:

事件

不幸的是,宇宙太忙了,也不习惯时刻关注它里面的个体,它可以用自己的委托替换了彼得老板的委托。这是把彼得的Worker类的的委托字段做成public的一个无意识的副作用。同样,如果彼得的老板不耐烦了,也可以决定自己来激发彼得的委托(真是一个粗鲁的老板):

彼得不想让这些事发生,他意识到需要给每个委托提供“注册”和“反注册”功能,这样监听者就可以自己添加和移除委托,但同时又不能清空整个列表也不能随意激发彼得的事件了。彼得并没有来自己实现这些功能,相反,他使用了event关键字让C#编译器为他构建这些方法:

彼得知道event关键字在委托的外边包装了一个property,仅让C#客户通过+= 和 -=操作符来添加和移除,强迫他的老板和宇宙正确地使用事件。

收获所有结果

到这时,彼得终于可以送一口气了,他成功地满足了所有监听者的需求,同时避免了与特定实现的紧耦合。但是他注意到他的老板和宇宙都为它的工作打了分,但是他仅仅接收了一个分数。面对多个监听者,他想要“收获”所有的结果,于是他深入到代理里面,轮询监听者列表,手工一个个调用:

异步通知:激发 & 忘掉

同时,他的老板和宇宙还要忙于处理其他事情,也就是说他们给彼得打分所花费的事件变得非常长:

很不幸,彼得每次通知一个监听者后必须等待它给自己打分,现在这些通知花费了他太多的工作事件。于是他决定忘掉分数,仅仅异步激发事件:

异步通知:轮询

这使得彼得可以通知他的监听者,然后立即返回工作,让进程的线程池来调用这些代理。随着时间的过去,彼得发现他丢失了他工作的反馈,他知道听取别人的赞扬和努力工作一样重要,于是他异步激发事件,但是周期性地轮询,取得可用的分数。

异步通知:委托

不幸地,彼得有回到了一开始就想避免的情况中来,比如,老板站在背后盯着他工作。于是,他决定使用自己的委托作为他调用的异步委托完成的通知,让他自己立即回到工作,但是仍可以在别人给他的工作打分后得到通知:

宇宙中的幸福

彼得、他的老板和宇宙最终都满足了。彼得的老板和宇宙可以收到他们感兴趣的事件通知,减少了实现的负担和非必需的往返“差旅费”。彼得可以通知他们,而不管他们要花多长时间来从目的方法中返回,同时又可以异步地得到他的结果。彼得知道,这并不*十分*简单,因为当他异步激发事件时,方法要在另外一个线程中执行,彼得的目的方法完成的通知也是一样的道理。但是,迈克和彼得是好朋友,他很熟悉线程的事情,可以在这个领域提供指导。

他们永远幸福地生活下去……<完>

略懂 HTML 的朋友都知道,如果想让一个链接在新窗口中打开,通常的做法是利用 target=”_blank” 来设定 a 标签。例如:

  1. <a href="http://jennal.cn" target="_blank">Jennal.cn</a>

这种做法确实比较方便,但在 XHTML 1.0 Strict 中去掉了 target 属性,也就是说我们不能再利用 target 属性来控制链接的行为。虽然当今流行的浏览器在 XHTML 1.0 Strict 甚至 XHTML 1.1 下扔能正确执行 target=”_blank”,但这样的代码毕竟是不规范的,不推荐使用。
很自然,我们会想到用 Javascript 来解决这个问题,我通常是使用下面的方法:

  1. <a href="http://jennal.cn" onclick="window.open(this.href);return false;">Jennal.cn</a>

这样虽然可以满足要求,但是当链接很多的时候,代码就显得有些臃肿了。为了简化代码,我们应该用 DOM Event / DHTML 的方法来解决这个问题。今天我恰好在做一个网页,需要使用 XHTML 1.0 Strict,准备自己写一个这样的 Javascript。不过幸好我养成了万事先 Google 的坏习惯,还真让我找到了一个很完善的 Javascript 弹窗代码,这段代码不仅写的漂亮,通用性强,而且还考虑到了当今流行的浏览器按下组合键点击链接的情况,已经非常完善了。代码源头在这里,作者提供了源码下载和一个演示
这段代码的通用性非常强,作者原文中举例写的也很详细,其实最简单的用法就是为需要开新窗的链接添加 rel=”external” 属性,当然,你也可以自己定制根据 class 或其它什么属性来判断。

  1. <a href="http://jennal.cn" rel="external">Jennal.cn</a>

当然,在网页设计中,弹出新窗口在多数情况下应该尽量避免,只在可以提高用户体验的情况下才需要使用。此外,由于有些 Pop Window Blocker 会拦截 Javascript 弹出窗口,我们可以修改这段代码,通过判断窗口是否成功建立来给出关闭弹窗过滤的提示,相信可以使用户体验提升不少。
转自:http://blog.istef.info/2007/05/17/open-a-new-window-when-click-a-link-under-xhtml-10-strict/

php下载文件的函数

转自:http://www.ruofeel.cn/329.html

Javascript 刷新页面的几种方法

1    history.go(0)
2    location.reload()
3    location=location
4    location.assign(location)
5    document.execCommand('Refresh')
6    window.navigate(location)
7    location.replace(location)
8    document.URL=location.href

搞定一个很纠结的json问题,记录一下

今天被json编码中文搞死了。。。
json_encode中文的时候,会把每个中文字符encode成“\uxxxx”
而存进数据库的时候,“\”被屏蔽了,直接变成"uxxxx"
郁闷,我还以为是json_decode的问题。。。在网上查了一个下午资料都没解决
直到发现网上的文章都说json_encode是把中文encode成“\uxxxx”,我才顿悟。。。
经过一番实验,才发现问题出在存储到数据库的环节。。。
特此纪念一下
至于解决办法,当然是让"\"保留啦,把"\" replace成"\\"就可以啦~
还有一个问题,差点忘了,就是json_decode以后返回的不是array,而是stdclass,有一个很郁闷的问题,如果hash带下划线,如json['xx_yy']会出现很奇怪的问题,页面什么都不显示,也不报错,差点晕死。有一个办法解决,就是先foreach一下,把带下划线的存到一个array里面,或者直接整个转存成array。
//感谢软工的回复
由于已经是2年前写的博客,也没有写实际场景,我已经忘记json_decode是在什么场景下出现的问题。
如果我没有记错的话,当时json_decode还没有第二个参数。

PHP get remote ip address

Discuz!源代码分析[模板使用include template(discuz)]:./include/template.func.php

本帖不仅仅是分析文件,还把Discuz中模板解析这一原理分析了一下。转自www.discuz.net 作者:郭鑫
我记得我刚开始学PHP的时候,对模板解析实在是觉得很奇怪,不知道这个原理怎么实现的,后来看书看多了也明白有一个著名的Smarty在那,曾经也用过一段,不过感觉不是很好,就开始分析Discuz的模板技术是怎么实现的了,然后我把这个模板解析的代码分离出来了,觉得很好用,用了一段时间, Discuz的模板解析是用正则表达式替换一些模板中的规定的语言标记,然后呢,写到forumdata/templates中,再用include引用到index, forumdisplay等等中,和smarty的原理基本上相同,只是功能没有smarty那么多,smarty内建了一个cache来着…连个 User Guide都几百页…
  呵呵,不过现在基本上两个都没用过,正则表达式好是好用,不过正则的效率不是很高,以前看PHP技术文档的时候说能不用正则就尽量不要用,那东西烦着,现在做什么项目基本上用的是框架,MVC的模式,View中的代码一般不用模板解析出来,混杂php代码在里面,也觉得不错,OOP的开发效率比较高,很多地方重用代码是很开心的~!
  Discuz的模板解析要分析出来只要用到两个文件:./include/global.func.php和. /include/template.func.php,global只要一个函数就够了,template要全部的文件下面我就分开讲一下,会比较详细,大家耐心看:
Section One--./include/global.func.php---->template function

这个函数一共有三个传入参数:
$file 表示模板名
$templateid 表示模板id
$tpldir 表示模板目录

这个是把$tplrefresh作为一个全局变量,tplrefresh表示是不是刷新模板

$tpldir和$templateid赋值,如果没有传进来就用常量TPLDIR和TEMPLATEID给它们值

这里是把$tplfile(表示的是模板文件)和$objfile(表示的是要编译成的文件)赋值

防止TEMPLATEID不等于1且$templateid不等于1,而且模板文件不存在导致空白问题。
这里也可以算一个迭代,也可以不算,就是把1作为第二个参数再调用函数本身。

很巧妙的一段,Discuz的模板缓存就体现在这里,如果你没打开模板刷新的话(config.inc.php->$tplrefresh=0),这里就直接返回一个$objfile了,而这个文件是你第一次建论坛的时候就写入的,如果你不改模板的话,关了是能提高相当一部分效率的!反之,如果你打开了模板刷新的话就接着判断是不是模板文件的建立时间大于 forumdata/templates下的文件,是的话就引用./include/template.func.php写入模板文件到 forumdata/templates中,否则的话还是直接返回一个已经编译好的模板文件。
关于template.func.php文件中函数的分析在下面: