WPTheme Java JavaScript…Yeah~!
Mar 18

有人喜欢把首页做成奇形怪状,不正常地显示新近文章,正如一个CMS。或者有人想专门做一个页面用来像首页那样显示新近文章的列表,如http://guitarbean.com/blog-updates,就不显示文章分类列表,而正如正常的博客首页那样显示最新文章。为了这个效果,这里有一个令人兴奋的解决方案

一个错误的方案:

1、把archive.php或index.php当成页面,在新建页面中把“Page Template”指向它。可惜这样做的结果等同与指向page.php,所建立的页面只会显示单个页面内容。

一些不错的解决方案(均需建立页面):

1、alexking.org的articles插件。有了这个插件,你可以显示一个漂亮的article list。这个列表有文章归类,但显示的不是全部文章,因为需要给文章添加一个额外的key=article和value=1。这不是正常的首页效果,算是半个site map吧。

2、使用Rob Marsh, SJRecent Posts 插件,类似的还有中文 WordPress 工具箱 。放一个recent post到某个页面中……之后的不说自明了吧,只是所显示的也只是文章标题而已。

3、wordpress.org.cn上找到的一个帖子 ,不过得把代码改改:

<?php
/*
Template Name: guid
*/
?>
<?php get_header(); ?>
<div id="content" class="widecolumn">
<?php $posts = get_posts( "numberposts=10" ); ?>
<?php if( $posts ) : ?>
<?php foreach( $posts as $post ) : setup_postdata( $post ); ?>
<div class="post">
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<small><?php the_time('F jS, Y'); ?></small>
<div class="entry">
<?php the_content(); ?>
</div>
<p class="postmetadata">Posted in <?php the_category(', '); ?></p>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
<?php get_footer(); ?>

这样再把页面指向它(guid)就可以了。不过经我测试发现,使用这个方法得到的文章不是以时间的新到旧排序的,而是以旧到新排序的,得到的列表很不合意。在codex.wordpress.org上查get_posts,说默认是以时间新到旧排序的,可是我再怎么添加修改参数也实现不了,可能因为我的本地机是wordpress 2.3.3吧。不管怎么说,这个方法离目标只有一步之遥,只要再改正时间排序问题和可以使用像pagebar这样能进行分页就成功了。

一个令人兴奋的解决方案——query_posts & The_Loop

这里,只要在合适地地方添加一句:<?php query_posts(”paged=$paged”); ?>

步骤:

1、拷贝一个index.php(或archieves.php)并改名为其它名,如list_post.php;

2、找到<?php while (have_posts()) : the_post(); ?>,在之前加这行 <?php query_posts(”paged=$paged”); ?>,如
<?php query_posts("paged=$paged"); ?>//取得posts
<?php while (have_posts()) : the_post(); ?>

3、在页面最顶部添加
<?php
/*
Template Name: List Posts
*/
?>

以把这个文件标识为List Posts。注意,这代码最好紧跟<?php get_header(); ?>,不要有空行,最好如:

<?php
/*
Template Name: List Posts
*/
?><?php get_header(); ?>

4、新建一个页面,如blog-updates,把Page Template指向它,什么内容也不用写,就OK了!

原理:为了能显示Wordpress的文章列表,最好的是使用The Loop ,在The Loop中就可以使用像the_title()啊,the_content()之类的Template_Tags和分页信息了。而在index.php和archves.php中,都有一个默认的全局魔术变量,这个魔术变量常常变器法地变化着自身:在首页中,是一个默认的最新文章列表,在存档中是当前分类或日期的文章列表,而在单个post或者page中就是单个文章了。而使用query_posts正好能更改这个魔术变量成为想要的。如query_posts(”paged=$paged”)就是把它变为当前页的文章列表。

参考文献:

[1]http://codex.wordpress.org/The_Loop

[2]http://codex.wordpress.org/User:JamesVL/query_posts

[3]http://codex.wordpress.org/Category:Template_Tags

[4]http://wordpress.org.cn/viewthread.php?tid=7143&page=1&fromuid=15469#pid33133

Aug 25

  主题标志:

style-theme


  主题下载:sugarsign-jet-black-p.zip

  主题截屏:

screenshoot

  主题下载:sugarsign-jet-black-p.zip

  主题介绍:

  • 外观?墨色主题,从截图中已经看到了呢,至于为什么叫它“墨”,也不晓得呢,总之是与之前的peachblow同一系列的;
  • 其它功能或特性,请参考PeachBlow主题
  • 提供主题中LOGO的PSD文件。

  主题下载:sugarsign-jet-black-p.zip

  另外有一个集成花花写的flickr图片显示插件Pagebar插件的版本,请点击sugarsign-jet-black-plugs.zip下载。

Aug 22

  Update:已更正一处无关皮毛的JS小BUG,但也请点击下载最新的文件哦!
  主题标志:

style-theme


  主题下载:sugarsign-peachblow.zip

  主题截屏:

Peachblow screenshoot

  主题下载:sugarsign-peachblow.zip

  主题介绍:

  • 由截屏可知,物如其名,主题的主体色泽为桃红,至于为什么为做成桃红?突然想到的,在PS下把色相一拉,就变了;
  • 文章字体大小为14px,其它的为12px;字体大小统一为12px;
  • 支持则栏自定义;
  • 集成花花写的flickr图片显示脚本。如果要集成此脚本,请下载sugarsign-preachblow-plus.zip
  • 评论内容、评论人及Email的JS动态判断;
  • google集成分析判断:对本地和以登陆用户不加载google分析代码;
    注意:主题中的google分析号为本博的,须自行修改foot.php文件。
  • wordpress版本要求 wordpress 2.x系列;
  • 主题文件占用空间约为72KB;
  • 可直接上传到yo2中使用
  • 提供主题中LOGO的PSD文件,点击logo-preachblow.zip下载。

  主题下载:sugarsign-peachblow.zip

  Update:修正在非widget下搜索按钮不能正常显示的问题,并且提供logo的PSD文件下载。这个LOGO的PSD文件中只要同时把三个图层的同时文字修改为自己想要的,并输出为gif文件放到images/文件夹下即可。

  另外有一个集成花花写的flickr图片显示插件Pagebar插件的版本,请点击sugarsign-preachblow-plus.zip下载。

Jul 01

  模拟私有属性

  好的,让我们看看闭包是怎么帮助我们模拟私有成员的吧。通常来说,一个函数内部的本地变量在外部是无法访问的。一旦函数创建,其内部所有的本地变量就消失了。但是,当其本地变量被闭包捕获后,它又复活了。这就是在JavaScript中模拟私有属性的关键之处。请看下面的Person类:

function Person(name, age) {
this.getName = function() { return name; };
this.setName = function(newName) { name = newName; };
this.getAge = function() { return age; };
this.setAge = function(newAge) { age = newAge; };
}

参数name和age对于Person构造函数来说属于本地变量。当Person返回时,假定参数name和age已经消失了,但当他们被4个内部函数捕获后,就复活回来了。而这4个内部函数是作为Person对象的方法而存在的,而name和age就严格地通过这4个方法来访问。所有你可以这样做:

var ray = new Person("Ray", 31);
alert(ray.getName());
alert(ray.getAge());
ray.setName("Younger Ray");
// Instant rejuvenation!
ray.setAge(22);
alert(ray.getName() + " is now " + ray.getAge() + " years old.");

在构造函数中的本地函数也可以在构造时,不进行初始化,如下:

function Person(name, age) {
var occupation;
this.getOccupation = function() { return occupation; };
this.setOccupation = function(newOcc) { occupation =
newOcc; };
// accessors for name and age
}

请注意,这些私有成员与我们在C#中所期望的稍有所不同。在C#中,类的仅有成员可以访问到它的私有成员。但在JavaScript中,必须通过拥有私有成员的、形成闭包的方法(这些方法与通常的公共方法稍有区别,我们称之为特权方法)。所以在Person的系列公共方法中,你仍然需要通过它的特权方法来访问它(Person)的私有成员:

Person.prototype.somePublicMethod = function() {
// doesn't work!
// alert(this.name);
// this one below works
alert(this.getName());
};

Douglas Crockford就是第一个发现(或者公开发表)这个用闭包来模拟私有成员的方法。他的主页javascript.crockford.com中就有大量的关于JavaScript的信息,如果你对JavaScript有兴趣的话,我推荐你上去看一看。


To be Continued…

Jun 24

  闭包

  我并没有刻意的去学习JavaScript,我必须快速上手。因为我觉得,我已经为这个现实的AJAX应用,在没有学习过JavaScript的情况下,做了充分的准备。一开始,我觉得我已经在程序员中下降了几个层次。(JavaScript!我的C++程序员朋友们会什么看呢?) 但当我平复了当初的反抗后,我开始意识到JavaScript其实是一个强大的,富有表现力和简洁的语言。JavaScript的特色,它可以自豪地说,那些其它的更流行的编程语言现在才刚刚开始支持。

  JavaScript的其中一个更高级的特性就是对闭包的支持,而C#2.0则是通过匿名函数来实现的。闭包是这样的一个运行时现象,一个内部函数(在C#叫匿名函数)可以访问它的外部函数的变量。很显然,这样做的意义不大,除非它的内部函数不知何故地可以访问外部函数的领域。让我们举个例子来讲清楚它。

  假设你想对一系列的数字进行过滤,只有大于100的数才能通过,而其它的就被滤掉了。你可以像Figure 8这样写一个函数。

  但现在,你又想写一个新的过滤标准,假设这次要求数值必须大于300,这样写:

var greaterThan300 = filter(
function(x) { return (x > 300) ? true : false; },
someRandomNumbers);

  接着,你又需要对大于50,25,10,600等的数值进行过滤。这下子,聪明的你不会不意识到,它们都有一个共同的谓语:”大于”,所不同的只是数值。因此,你可以这样写一个函数把数字列出来:

function makeGreaterThanPredicate(lowerBound) {
return function(numberToCheck) {
return (numberToCheck > lowerBound) ? true : false;
};
}

然后这样写:

var greaterThan10 = makeGreaterThanPredicate(10);
var greaterThan100 = makeGreaterThanPredicate(100);
alert(filter(greaterThan10, someRandomNumbers));
alert(filter(greaterThan100, someRandomNumbers));

  让我们来看看过个被makeGreaterThanPredicate返回的内部匿名函数。这个匿名函数使用了lowerBound变量,这可是一个传到makeGreaterThanPredicate的变量啊。根据作用域的规则,这个变量lowerBound的作用域超出了makeGreaterThanPredicate存在时的范围。但在这个例子中,匿名内容函数仍然可以访问到变量lowerBound,即使makeGreaterThanPredicate已经存在很久了。这就是我们所说的闭包–因为内部函数可以超范围地访问到所定义它的环境(函数)里的封闭区域(包括所有参数和变量)。

  在开始的时候,包闭也不见得是什么大不了的事情。但如果使用得当,就可以在把你的思想转化为代码的时候,为之添加进新的趣味。JavaScript的闭包的一个最有趣的应用就是:我们可以用它来模拟类的私有变量。

To be Continued…


参考文献:

  1. Java 理论与实践: 闭包之争
  2. 跨越边界: 闭包
  3. javascript语言中的闭包
  4. 在Javascript中,什么是闭包(Closure)


Jun 21

  原型
  原型对象是JavaScript面向对象编程的中心概念。其称谓来源于JavaScript中对象的创建,都是作为一个现有的样例(即原型)的副本。这个原型对象的任何属性和方法,都会作为这个现有的原型构造器所创建的对象的属性和方法出现的。也可以说这些对象都从它的原型那里继承了所有属性和方法。例如当你这样样创建一个Dog对象的时候:

var buddy = new Dog("Buddy");

那个被buddy引用的对象从它的原型继承了所有属性和方法,尽管简单的一行代码可能并不足以看清原型的来源。对象buddy的原型来自一个构造函数的原型(在这个例子中,就是函数Dog)。

  在JavaScript中,每个函数都有一个指向到原型对象的,叫”prototype”的属性。反过来,这个原型对象又会有一个叫”constructor”的属性,它指向回函数本身。这是一种环形的映射关系。为了更好地理解这个环形关系,请看插图 Figure3

figure3
Figure3
每个函数的原型都有一个Constructor属性

  现在我们知道了,当一个函数(就拿上面的Dog的例子来说)使用”new”关键字来创建对象时,所得的结果对象就将会继承到Dog.prototype的属性。在Figure3,我们会看到,Dog.prototype对象有一个指回Dog函数的constructior属性。因此,每一个Dog对象(从Dog.prototype继承来的)也同样会有一个指回Dog函数的constructior属性,代码就 Figure 4 确认了这一点。Figure 5描述了在构造函数、原型对象以及他们所建立的对象之间的关系。

figure5
Figure 5
实例均从Prototype那里继承而来

  有的人可能已经注意到Figure 4中调用了两个函数hasOwnProperty 和isPrototypeOf 。它们从哪里来的呢?它们并不来自Dog.prototype。事实上Dog.prototype还有其它的像toString、toLocaleString和valueOf这样的函数供我们调用,但它们都不来自Dog.prototype。这就像是.NET Framework有System对象那样,是一个道理。(在.NET Framework中)Object类是所有类的根基,JavaScript就有一个类似的是所有原型的根基:Object.prototype。(Object.prototype的原型是null。)

  切记,在这个例子中的Dog.prototype就是一个对象,是通过对Object构造器函数的调用来创建的,虽然这并非显式的:

Dog.prototype = new Object();

  所以,就像Dog的实例继承自Dog.prototype那样,Dog.prototype继承自Object.prototype。这就使得所有Dog实例都从Object.protoype那里继承到其属性和方法了。
  所有的JavaScript对象都有一条以Object.prototype为终点的继承链。注意,目前为止我们所看到的这些继承都是发生在实时对象中的继承。这点与大家平时的继承概念有所区别,并不是在当类在声明时发生在类之间发生的。所以JavaScript的类的继承更具有动态性。这点是通过简单的算法来实现的:当你访问一个对象的属性/方法时,JavaScript会查看这个属性/方法是否在对象中定义有的。如果不是,则检查对象的原型;再不是的话,就检查对象的原型的原型,就这样一直检查下去,直到Object.prototype为止。插图 Figure 6就是个处理过程的关系图了。


Figure 6
Figure 6 toString()方法在原型链中的分析过程(点击查看大图)

  从这种JavaScript动态的属性访问及函数调用,可以得到以下几个推论:

  • 对原型对象的改变也对继承它的对象可见,即使(继承它的)这些对象已经被建立了;
  • 如果你为对象建立一个名为X的属性/方法,与其同名的在原型对象的属性/方法会从中隐藏起来。对于Dog.prototype实例来说,你可以定义一个toString方法去重载掉Object.prototype的toString方法;
  • 改变是单向,从原型到其子对象,但不能相反。

  Figure 7就举例说明了这个推论。 Figure 7同样展示了一个解决我们之前所遇到的,冗余方法的对策。除了为每个对象使用独立的函数对象外,你可以通过把方法放进原型里让其它对象去共享它。在这个例子中,方法getBreed 就被 rover和spot共享到了–总之就直到你在spot中把toString给重载掉(译者注:例子中重载掉的是getBreed才对)。之后,spot就有了自己版本的getBreed方法了,不过rover对象和后来的用new GreateDane创建的对象都是共享同一个getBreed方法,即在GreatDane.prototype对象中定义的那个方法。

To be Continued…

Jun 20

  不用类的构造函数

  正如我们注意到的,关于JavaScript面向对象编程的最奇怪之处就是,JavaScript不像C#或C++那样有类。在C#中,当你这样写:

Dog spot = new Dog();

会得到一个Dog类所实例化的对象。但JavaScript没有类可以让我们入手。最接近的方法是,你可以像这样定义一个构造函数:

function DogConstructor(name) {
this.name = name;
this.respondTo = function(name) {
if(this.name == name) {
alert("Woof");
}
};
}
var spot = new DogConstructor("Spot");
spot.respondTo("Rover"); // 不是这个
spot.respondTo("Spot"); // 啊,就是它了

那么,这里到底发生了什么事呢?让我们先把DogConstructor函数的定义放一边,来看看下面这行:

var spot = new DogConstructor("Spot");

这里”new”所做的事其实很简单。首先,它创建一个新的空对象,然后随之而执行的就是函数的调用,同时,这个函数的”this”的值就变成这个新的空对象了。换个说法,上面的用”new”操作符的那一行代码,可以相似地看作下面这两行:

// create an empty object
var spot = {};
// call the function as a method of the empty object
DogConstructor.call(spot, "Spot");

  正如你所见,在DogConstructor里,对函数进行初始化,就会把”this”关键字映射到对象上。这样,你就有了一个为对象创建模板的方法了!无论何时,只要你用”new”去调用构造函数,得到的结果就是一个完全初始化了的对象。这听起来是不是和类一样呢?事实上,在JavaScript中,构造函数的名就是你所要模拟成的类的名,所以在上面的例子中你只要把构造函数命名为Dog就可以了:

// 把这个想像成Dog类
function Dog(name) {
// 实例的变量
this.name = name;
// 实例的方法
this.respondTo = function(name) {
if(this.name == name) {
alert("Woof");
}
};
}
var spot = new Dog("Spot");

  在上面的Dog的定义中,我定义了一个名为name的实例级的变量。每一个使用Dog作为构造器创建的对象都有各自的实例级变量name(就像之前注意到的,这是通向对象字典的入口)。这也是我们所期望的,每一个对象都需要有自己的实例副本去保持它的状态。同样,每个实例同样拥有自己的respondTo方法副本,这真是一个浪费;你只需要一个respondTo 实例共享到所有Dog实例就行了!为了解决这个问题,我们可以在Dog的外部定义respondTo 方法,就像这样:

function respondTo() {
// respondTo 的定义语句
}
function Dog(name) {
this.name = name;
// 把函数作为实例的方法附上
this.respondTo = respondTo;
}

  这样,所有Dog的实例(即所有用Dog构造函数创建的实例)都可以共享到同一个respondTo实例了。但随着方法的数量的增长,这种情况就会变得越来越难以维持。你在基础代码中大量停用全局函数后,事情只会变得更糟糕,因为你的”类”也变得越来越多,特别是这些类的方法名非常相似的时。更好的处理方法是使用原型对象,这也正是文章下一部分要讨论的话题。

To be Continued…

Jun 20

  JavaScript函数是最初的类

  在很多编程语言中,函数和对象通常被看作两个不同的事物。在JavaScript,他们的区别很模糊–一个JavaScript的函数就是一个关联了可执行代码的真正的对象。想想一个普通的函数是这样的:

function func(x) {
alert(x);
}
func("blah");

  这就是在JavaScript中字义函数的方法。但我们也可以像下面那样定义一个函数,即定义一下匿名的函数然后赋值给一个变量func

var func = function(x) {
alert(x);
};
func("blah2");

  或者甚至这样,使用Function 构造器:

var func = new Function("x", "alert(x);");
func("blah3");

  这个例子告诉我们,函数本质就是一个支持function调用操作符的对象。最后一种使用Function构造器的定义方法并不常用,但为趣味性提供了可能。因为,可能你也意识到,对Function构造器来说,函数主体只是一个字符串参数。这就意味着在运行时你也可以随意构造函数了。

  为了进一步证明函数就是一个对象,你可以试着给它添加一个属性,就像给其它JavaScript对象一样:

function sayHi(x) {
alert("Hi, " + x + "!");
}
sayHi.text = "Hello World!";
sayHi["text2"] = "Hello World... again.";
alert(sayHi["text"]); // displays "Hello World!"
alert(sayHi.text2); // displays "Hello World... again."

  作为一个对象,函数同样可以被赋值给变量,作为变量传递给其它函数,作为其它函数的返回值,以及作为其它对象的属性或数组的元素等。演算1 提供了这样的一个例子。

  根据这个思路,为对象添加方法就像选择一个名字然后把一个函数赋值给这个名字一样容易。现在我在一个对象中通过赋值匿名函数的方式定义了三个函数:

var myDog = {
"name" : "Spot",
"bark" : function() { alert("Woof!"); },
"displayFullName" : function() {
alert(this.name + " The Alpha Dog");
},
"chaseMrPostman" : function() {
// implementation beyond the scope of this article
}
};
myDog.displayFullName();
myDog.bark(); // Woof!

  函数displayFullName里面”this”关键字的使用方法对我们之中的C++/C#开发者最熟悉不过了–它是调用这个函数的对象的引用(使用Visual Basic的开发者也应该熟悉–在Visual Basic中它称为”Me”)。所以在上例中,displayFullName函数中”this”的值就是myDog对象。”this”的值不是静态的。调用不同的对象,它的值就会指向那个对象,就像 演算2 所示范那样。

  演算2的最后一行展示了把函数作为对象的方法调用的另一种方式。切记,JavaScript的函数就是一个对象。每一个函数都有一个名为call的方法,使得函数在调用时,会成为特定对象的方法来调用,而这个特定对象就是传到call方法的第一个参数。就是说,无论什么对象,只要作为call方法中的第一个参数,都会成为此函数的this的值。这是一个调用基于对象构造器的一个很有用的技巧,这点我们稍后会讨论到。

  有一点必须谨记,那就是一个带有this关键字的函数,在它没有自己的归属对象前,千万不要调用它。如果你这样做,就会破坏到最上层的全局命名空间,因为这样的调用中的”this”会指向到全局对象,这可是你的应用程序中的大灾难啊。例如下面的一个例子,它改变了JavaScript的全局函数isNaN。这样做显然是不推荐的!

alert("NaN is NaN: " + isNaN(NaN));
function x() {
this.isNaN = function() {
return "not anymore!";
};
}
// alert!!! trampling the Global object!!!
x();
alert("NaN is NaN: " + isNaN(NaN));

  到这里,我们看到过几种建立对象,和完善对象属性和函数的方法。但如果你注意到在上面的代码片段中,属性和方法都是hardcoded在对象定义自身(有待修正)。万一你想在对象的建立中得到更多的控制呢?例如基于一些参数计算对象属性值,或者初始化一些必须在运行时才有值的属性(有待修正),又或者为对象建立更多的实例等(有待修正),这些都是常见的需求了。

  在C#,我们使用classes来实例化对象。但JavaScript不同,因为它没有classes。在下一个部分会讲到一个取代classes的方法,利用函数来实现构造器,同时,我们会用到操作符”new”。

To be Continued…

Jun 19

  最近,我会见了一个有5年网络应用程序开发经验的程序员。她编写JavaScript已经有半年了,并认为她的JavaScript技巧很不错,但之后我很快地发现–她对JavaScript的了解可以说是一无所知。但我没有责备她这点。JavaScript在这种情况下显得很滑稽,它是一个让很多人(包括作者自己在之前也这样认为)都觉得自己已经很熟手了,因为他们都有着C/C++/C#或其它之前的编程经验了。

  在某种情况上,这个自我感觉并非无根据。使用JavaScript可以轻易的实现一些简单的应用。JavaScript入门的门栏很低;在使用这个编程语言进行编写之前不需要你了解太多的知识。甚至连一个非程序员也可以上手,并在他们的空闲时间为自己的主页写上很多有用的脚本。

  确实,在之前,我也常常只是利用MSDN® DHTML手册和我的C++/C#经验,以及对JavaScript的仅有认识上过日子的。直到当我在一个真正的AJAX应用程序上工作时,才发现我的JavaScript知识是多么匮乏。这个新一代的网络应用程序的复杂性和相关性要求我们使用一个完全不同的手段去编写JavaScript代码。这是一个严紧JavaScript应用程序!我们那种使用后就抛弃的传单式的脚本编写方式不再适用了。

  面向对象编程(OOP)是在很多JavaScript库中是一个非常流行的处理手段,它能使代码更易于管理和维护。JavaScript支持OOP,但它的实现方式与Microsoft® .NET Framework中的像C++、C#或Visual Basic®这样的编程语言的大有不同,所以熟悉这些编程语言的开发人员在开始时会觉得,OOP在JavaScript中显得很怪,而且与他们的直觉相反。这写的这篇文章主要是深入地讨论JavaScript怎样真正地支持面向对象编程和我们应当如何进行JavaScript面向对象开发。现在就让我们从对象(没其它了吧?)讲起吧。

  JavaScript 对象是字典

  在C++或C#中,当我们谈论对象时,总会提及到类和结构。对象所拥有的属性和方法,取决于把它实例化的模板(即类)。但那不是JavaScript对象的情形。在JavaScript,对象是一对对键名/键值的集合–可以想象成一个字典和字典的一串索引。我们可以通过熟悉的”.”(dot)操作符和”[]“操作符来获取和设置一个对象的属性,就像经典的查字典行为。请看下面一个代码小片段

var userObject = new Object();
userObject.lastLoginTime = new Date();
alert(userObject.lastLoginTime);

也可以这样写,同样正确:

var userObject = {}; // 与new Object()等价
userObject["lastLoginTime"] = new Date();
alert(userObject["lastLoginTime"]);

我们同样可以在定义lastLoginTime的时候给它赋值:

var userObject = { "lastLoginTime": new Date() };
alert(userObject.lastLoginTime);

  你看,现在它已经和C# 3.0的对象初始化器是多么相似。同样,如果你熟悉Python也会发觉,我们第二个和第三个代码片段中实例化lastLoginTime的方式正是在Python中指定字典的方式。唯一的区别是,JavaScript的对象/字典只接受字符串形式的键,而非Python的字典世界里的哈唏表对象(译者:指Python也可以接受字符串以外的对象作为键名,关于Python内容的翻译有待修正)。

  上面的例子同样显示出JavaScript对象比C++和C#对象更具有可扩展性。属性lastLoginTime不必预告声明–即时userObject并没有这个名字的属性,也会简单地添加到userObject上去。如果你还记得JavaScript对象是一个字典的话,这就不是什么令人吃惊的事–毕竟,我们总是添加新的索引键(包括键值)到字典中去。

  现在我们有了对象属性,那么对象的方法呢?再次说明,JavaScript与C++/C#是不同的。为了理解对象方法,下面让我们近距离观察JavaScript的函数。

To be Continued…

Jun 12

  网友们提供了很多显示在Flickr上储存的图片的方法,如:”还我 Flickr! 拯救 Flickr 大行动“。

  让Flickr显示的最好方法是替换IP的方法,因为稳定。其替换的内容如下:

http://farm1.static.flickr.com/ 换为 http://68.142.232.116/

http://farm2.static.flickr.com/ 换为 http://69.147.123.56/

  其中为Wordpress而做的花儿写的脚本就用这个方法,实现方法是在输出时替换IP。这样做的好处是不影响原有的数据,等Flickr解禁时,只要把花儿写的脚本去掉就可以了,嘿嘿。

  但在yo2上可用不了,因为无法安装插件,而且无法把插件直接放到主题文件中。估计是Yo2对下面这个语句实行了禁令:

add_filter('the_content', 'filter');

  我在做Wordpress主题时总是Hack很多,因为原有的Wordpress template tag满足不了复杂的主题结构,所以用别名的方法写了实现花儿写的脚本同样功能的函数。但这样做就只能用于博客的页面显示了,没有能像花儿写的脚本那样全面。于是我就干脆写个JS,把Flickr的IMG地址全部换成相应的IP。代码如下:

<script type="text/javascript">
function filckr_ip_replace(){
 var _images_inblog=document.getElementsByTagName("img");
 var _Regex=["http://farm1.static.flickr.com/","http://farm2.static.flickr.com/"];
 var _RepIP=["http://68.142.232.116/","http://69.147.123.56/"];
 if(!_images_inblog.length) return;
  for(var i=0;i<_images_inblog.length; i++){
  for(var n=0;n<_Regex.length;n++){
  if(_images_inblog[i] && _images_inblog[i].src && _images_inblog[i].src.indexOf(_Regex[n])>-1)
  _images_inblog[i].src= _images_inblog[i].src.replace(_Regex[n],_RepIP[n]);
  }
 }
}
filckr_ip_replace();
</script>

  Yo2用户只要把上面的代码放在footer.php中相应的位置即可。如果在footer.php中还有其它如google分析等其它外接的脚本的话,那最好把上面代码放在最前面。

  我这个blog就是用这个方法显示Flickr图片的。

  Update:推荐使用花儿写的脚本

  yo2上还有很多有用的插件,总之想方法把代码放到最后(相对的靠后)就行了。

Update:已经可以把花儿写的脚本放在header.php中,最好是<body>标签前面。但我认为花儿写的脚本中没必要把the_excerpt()也应用上去,因为the_excerpt()生成的是纯文字的文摘的形式,也没有什么图片内容了。详看codex上的the_excerpt()说明。

  PS:太久没写JavaScript,有点生疏了。

Pages: 1 2 Next