scrollTop

作者:kun10 发布时间:June 20, 2011 分类:JavaScript

scrollTop
项目里面用了这样的一句话

var theScrollTop = document.documentElement.scrollTop || document.body.scrollTop;

scrollTop属性是什么? 有些情况下,“元素中内容”的高度会超过“元素本身”的高度,这时候我们有时就会用到scrollTop
初始状态下,“内层元素的上边界”和“外层元素的上边界”重合,没有任何内容超过“外层元素的上边界”,此时scrollTop属性的值为0。
当向下拖动滚动条时,超过“外层元素的上边界”的内容会逐渐增多,scrollTop值就等于这些超出的部分。
在项目中我使用scrollTop计算页面的滚动量。

当html文档头部包含有“文档类型声明”时,需要用document.documentElement.scrollTop获得正确的值,而document.body.scrollTop的值为0
当html文档头部不包含任何“文档类型声明”时,需要用document.body.scrollTop获得正确的值,而document.documentElement.scrollTop的值为0

上面是网上抄来的一段,实际使用的时候
在FF下面页面滚动的时候,document.body的scrollTop不会变化,始终为0
而在ie和webkit下面,documentElement的scrollTop不会变化,始终为0
所以,
使用document.documentElement.scrollTop || document.body.scrollTop;来做页面卷过的高度还是挺好的。
记一下

JSHint简介

作者:kun10 发布时间:May 15, 2011 分类:JavaScript

JSHint介绍

翻译自www.jshint.com
JSHint(注意不是jslint:))是一个由javascript社区驱动开发的用于检查javascript代码错误和问题的工具,有了他,可以使你保持一个良好的编码风格。你可以很简单的配置它以适应你目前的一个编码风格。
目前JSHint的源码可以在github上面找到。

JSHint文档

如何使用JSHint

JSHint是一个全局的函数,他接受两个参数,

JSHint(source,options);

一个是代码source,另一个是options(选项)
第一个参数可以是一个字符串或者是一个字符串数组。如果是字符串,则他会被\n和\r分割,如果传入的参数是数组,就要保证数组的每一项是一行代码。
因此源码参数可以是javascript代码或者是一个json形式。如果所有的检测都ok,JSHint会返回true,否则就返回false。
当返回false的时候,你可以用JSHint.errors来获取错误信息或者用JSHint.data()来获取lint的信息。
如果要了解更多,参见源代码
使用JSHint,你可以在js文件的开始设定选项,例如

/*jshint evil:true, boss:true */

而设定global参数可以告诉JSHint,全局的变量配置。
例如

/*global DISQUS: true, jQuery: false */

以上的这个例子是告诉JSHint,DISQUS是你自己声明的全局变量,而jQuery是你引入的全局变量

JSHint和JSLint有什么区别?


JSHint是JSLint的一个分支(fork),他比JSLint更加的便捷。用来约束你的代码质量和编码风格。
每个人都有不一样的编码习惯和风格,JSHint通过配置可以适应于各种情况。

JSHint的适用环境

  • 浏览器环境(browsers)
  • Node.js
  • jQuery
  • ES5
  • CouchDB
  • Prototype.js
  • Mootools.js
    • JSHint的选项配置

      asi

      如果是真,JSHint会无视没有加分号的行尾,
      自动补全分号一直是Javascript很有争议的一个语法特性。默认,JSHint会要求你在每个语句后面加上分号,但是如果你认为自己理解了asi(automatic semicolon insertion),你可以抛弃JSHint对分号的检查。

      bitwise

      如果为真,JSHint会禁用位运算符
      Javascript允许位运算,但是他却没有整型,位运算符要把参与运算的数字从浮点数变为整数,并在运算后再转换回来。这样他们的效率就不如在别的语言中那么高。

      boss

      很霸气的选项,如果为真,那么JSHint会允许在if,for,while里面编写赋值语句。
      一般来说,我们会在循环、判断等语句中加入值的比较来做语句的运行条件,有时候会把==错写成赋值的=,通常,JSHint会把这个认定为一个错误,但是开启这个选项的化,JSHint就不会检查判断条件中的赋值 ,你是boss,你说的算:)。

      curly

      如果为真,JSHint会要求你在使用if和while等结构语句时加上{}来明确代码块。
      Javascript允许在if等结构语句体只有一句的情况下不加括号。不过这样做可能会让你的代码读起来有些晦涩。

      debug

      如果为真,JSHint会允许代码中出现debugger的语句。不过建议你最好在检测代码前去掉debug的语句。

      eqeqeq

      如果为真,JSHint会看你在代码中是否都用了===或者是!==,而不是使用==和!=。
      我们建议你在比较0,''(空字符),undefined,null,false和true的时候使用===和!===。

      eqnull

      如果为真,JSHint会允许使用"== null"作比较。
      == null 通常用来判断一个变量是undefined或者是null(当时用==,null和undefined都会转化为false)。

      evil

      如果为真,JSHint会允许使用eval
      eval提供了访问Javascript编译器的途径,这有时很有用,但是同时也对你的代码形成了注入攻击的危险,并且会对debug造成一些困难。
      记住,Function构造函数也是另一个‘eval’,另外,当传入的参数是字符串的时候,setTimeout和setInterval也会类似于eval。

      forin

      如果为真,那么,JSHint允许在for in 循环里面不出现hasOwnProperty,
      for in循环一般用来遍历一个对象的属性,这其中也包括他继承自原型链的属性,而hasOwnProperty可以来判断一个属性是否是对象本身的属性而不是继承得来的。

      immed

      如果为真,JSHint要求匿名函数的调用如下:

      (function(){
      //
      }());
      

      而不是

      (function(){
      //bla bla
      })();
      

      laxbreak

      如果为真,JSHint则不会检查换行。
      Javascript会通过自动补充分号来修正一些错误,因此这个选项可以检查一些潜在的问题。

      maxerr

      设定错误的阈值,超过这个阈值jshint不再向下检查,提示错误太多。

      newcap

      如果为真,JSHint会要求每一个构造函数名都要大写字母开头。
      构造器是一种使用new运算符来创建对象的一种函数,new操作符会创建新的对象,并建立这个对象自己的this,一个构造函数如果不用new运算符来运行,那么他的this会指向全局对象而导致一些问题的发生。

      noarg

      如果为真,JSHint会禁止arguments.caller和arguments.callee的使用
      arguments对象是一个类数组的对象,它具有一个索引值。arguments.callee指向当前执行的函数(这个在ES5的严格模式中被禁用了),而arguments.caller指向调用当前函数的函数(如果有的话),并且,他并不是在所有的Javascript实现里面都有。

      noempty

      如果为真,JSHint会禁止出现空的代码块(没有语句的代码块)。
      如果为真,JSHint会禁用构造器,以避免一些问题。
      JSLint中会主动禁用构造器的方式以避免一些潜在问题,但其实很多构造器的使用并非有害,例如如下的调用

      new JsUIWindow();
      //注意这个调用是没有把构造器的结果赋值给变量的
      

      因此,我们需要使用构造器的时候可以禁用这个选项。

      nomen

      如果为真,JSHint会禁用下划线的变量名。
      很多人使用_name的方式来命名他们的变量,以说明这是一个私有变量,但实际上,并不是,下划线只是做了一个标识。
      如果要使用私有变量,可以使用闭包来实现。

      onevar

      如果为真,JSHint期望函数只被var的形式声明一遍。

      passfail

      如果为真,JSHint会在发现首个错误后停止检查。

      plusplus

      如果为真,JSHint会禁用自增运算和自减运算
      ++和--可能会带来一些代码的阅读上的困惑。

      regexp

      如果为真,JSHint会不允许使用.和[^...]的正则,
      因为这样的正则往往会匹配到你不期望的内容,并可能会应用造成一些危害。

      undef

      如果为真,JSHint会要求所有的非全局变量,在使用前都被声明。
      如果你不在一个本地作用域内使用var的方式来声明变量,Javascript会把它放到全局作用域下面。这样会很容易引起错误。

      sub

      如果为真,JSHint会允许各种形式的下标来访问对象。
      通常,JSHint希望你只是用点运算符来读取对象的属性(除非这个属性名是一个保留字),如果你不希望这样可以关闭这个选项。

      strict

      如果为真,JSHint会要求你使用use strict;语法。
      Strict 模式是ES5里面的一个新特性,他允许你把一个程序或者函数放在一个“严格”的作用域中。可见Resig写的一篇关于严格模式的blog
      严格模式做了几件事情,
      1、他可以捕获一些错误和异常
      2、当我们进行一下“不安全”的操作时,他会抛异常,例如访问全局变量。
      3、他会禁止你使用一些奇淫技巧,或者不良的代码编写。

      white

      如果为true,JSHint会依据严格的空白规范检查你的代码。

      转载请注明出处~

javascript的Array-like对象

作者:kun10 发布时间:May 3, 2011 分类:JavaScript

什么是javascript里面的ArrayLike对象?
一切都是源于看YUI的Array部分,Y.Array()方法本身就能把对象转化为数组的方法,接受一个叫arraylike的参数。
其实arraylike我们经常会遇到,函数的arguments对象就是一个最常见的arraylike对象。
我们可以在firebug里面console.log一个函数的arguments对象,会发现他是一个对象,不是会发现他带有一个length属性。
但是我们却不能用普通的数组的方法来操作arguments对象
比如:

arguments.pop();//arguments.pop is not a function

很奇特吧?其实arraylike的对象还不只arguments对象一个
document.getElementsByTagName(), document.images, document.childNodes这几个货都是arraylike的对象。
既然这些对象是arraylike的,我们自然很渴望使用array的方法来操作他们。
方法很早就有人写了。

var newArray = Array.prototype.slice.call(arguments);

原理:
Array.prototype.slice: The original slice method that is given to all arrays via the prototype chain. We can’t call it directly though, because when it runs internally, it looks at the this keyword, and calling it here would make this point to Array, not our arguments variable.
Array.prototype.slice.call(): call() and apply() are prototype methods of the Function object, meaning that they can be called on every function in javascript. These allow you to change what the this variable points to inside a given function.

中文注解:
Array.prototype.slice是Array原型上面的slice方法,因为Arraylike对象不是array,所以直接使用slice是无效的,因此我们要把我们的arguments对象作为this,传入slice方法中。如何传入slice方法,我们使用call方式来把arguments作为this传给slice做处理。call和apply是Function构造函数对象的原型方法,因此我们可以对任意的函数使用。this最终被函数处理成一个数组。

这在非IE的情况下面好使,因为在IE下面domnodelist不被认为是对象,对于IE我们只能使用慢一点的方法了。

var newArray = [];
for(var i = 0;i< arguments.length;i++){
    arr.push(arguments[i]);
}
return newArray;

此时newArray就是一个数组对象。
我们可以对他pop(),push()等等等等。。。
参考:
http://nfriedly.com/techblog/2009/06/advanced-javascript-objects-arrays-and-array-like-objects/(这篇更靠谱点。。。)
http://shifteleven.com/articles/2007/06/28/array-like-objects-in-javascript

YUI发布YUI Test1.0.0 beta2版本

作者:kun10 发布时间:May 1, 2011 分类:JavaScript

原文地址:here
译者:qiaofu
去年我们发布了YUI test 的1.0beta1版本,之后我们便进行了反馈的收集,bug的修补以及补充新特性。今天我很高兴的宣布我们的beta2版本也发布了,这将是我们在通用版本前的最后一个版本。新的beta2版本的发布拥有一些新的核心功能,例如对Node.js的初步支持。所有的这一切都是为了创建一个更完整的测试解决方案,方便你在任何地方进行javascript的测试。

核心的变化


基于来自YUI社区的反馈,我们对YUI Test的核心做了一些补充。首先是加入了测试用例对象的初始化(init())和销毁的方法(destroy()),而在此之前,我们一直用setUp和tearDown来做数据的初始化和销毁。在传统的xUnit形式的测试框架中,setUp用来在每一个测试前运行,而tearDown则是运行于每一个之后。init和destroy则是分别运行于测试用例对象中所有setUp()方法之前和tearDown方法之后,并都只运行一次。这两个方法有利于管理整个贯穿于整个用例对象的数据。例如:

var testCase = new YUITest.TestCase({
     name: "TestCase Name",     
     //---------------------------------------------                                              
     // init and destroy     
     //---------------------------------------------
     init : function () {
         this.data = { 
             name : "Nicholas",
             age : 28
         };     
     },     
     destroy : function () {
         delete this.data;
     },
     //---------------------------------------------     
     // Tests     
     //---------------------------------------------
     testName: function () {
          YUITest.Assert.areEqual("Nicholas", this.data.name, "Name should be 'Nicholas'");
     },
     testAge: function () {
          YUITest.Assert.areEqual(28, this.data.age, "Age should be 28");
     }
});

另一个变化是“上下文数据”(context data)特性的引入。当一个测试(testRunner)开始,他会创建一个对象,这个对象会被传递到每一个init方法、setUp方法、destroy方法以及tearDown方法和test方法里面,默认情况这个对象是空的。你可以利用他在多个测试用例对象和方法之间共享一些数据。例如:

var testSuite = new YUITest.TestSuite({
     name: "Test Suite Name",
     setUp: function(data){
         data.topLevel = 1;
     }
}); 
testSuite.add(new YUITest.TestCase({
     name: "First Test Case",
     init: function(data){
          data.foo = "bar";
     },
     testValueOfFoo : function (data) {
          YUITest.Assert.areEqual("bar", data.foo);
          //数据来自init
     },
     testValueOfTopLevel: function(data){
          YUITest.Assert.areEqual(1, data.topLevel);
          //数据来自测试套件
     }
});
testSuite.add(new YUITest.TestCase({
     name: "Second Test Case",
     testValueOfFoo : function (data) {
         YUITest.Assert.areEqual("bar", data.foo);
         //数据来自第一个测试用例的init
     },
     testValueOfTopLevel: function(data){
         YUITest.Assert.areEqual(1, data.topLevel);
         //数据来自测试套件
     }
});

当然最关键的一点,如何使用好上下文数据取决于你自己,即便不用它你也可以很好的完成测试的工作。

针对Node.js的YUI Test


在YUI test beta2里面,我们增加了对Node.js的支持,你可以利用如下命令安装

~:npm install yuitest

一旦安装完成,你就可以传入测试文件和被测试文件的路径,进行测试。

~:yuitest testfile.js path/to/test

在浏览器中写javascript测试和在Node.js里面写javascript测试的区别在于,浏览器端的js测试,你需要在测试页面中引入yui test文件,Nodejs中你需要require引入YUItest。而利用一下的形式你可以在浏览器端和Node.js端用同一套脚本

(function(){
     //define local version of YUITest based on what's available.
     var YUITest = this.YUITest || require("yuitest");//引入YUITest,这句是关键
     var testCase = new YUITest.TestCase({
         //test case details
     });
     YUITest.TestRunner.add(testCase);
})();

如果是浏览器端引入yuitest文件,那么this.YUITest应该会指向window对象下面的YUITest,否则就是用NodeJs的require方式来引入yuitest。
不过有一点要注意的是,Node.js环境里面并没有Dom,因此dom部分很可能在node.js下面抛出异常(译者YY:这一点或许安装了Node.js的jsdom会解决问题)

展望通用版本


要达到GA版本我们还有很多要做,还有很多的bug要修复,定制更好的说明文档以及跟进社区里面提及的重要点。blablabla...

YUI3的guid和stamp方法

作者:kun10 发布时间:April 24, 2011 分类:JavaScript

YUI3里面有一个stamp函数和guid方法
guid方法是用来给一个特定的dom元素来添加一个对于yui的特定的id
guid: function(pre) {
var id = this.Env._guidp + (++this.Env._uidx);
return (pre) ? (pre + id) : id;
},

_guidp是一个前缀,默认定义为‘Y’
_uidx是一个环境上面的变量,用来记录数字

guid很明显的,通过拼接生成一个唯一的id

stamp方法是用来读取一个对象的id的

stamp: function(o, readOnly) {
        var uid;
        if (!o) {
            return o;
        }

        // IE generates its own unique ID for dom nodes
        // The uniqueID property of a document node returns a new ID
        if (o.uniqueID && o.nodeType && o.nodeType !== 9) {
            uid = o.uniqueID;
        } else {
            uid = (typeof o === 'string') ? o : o._yuid;
        }

        if (!uid) {
            uid = this.guid();
            if (!readOnly) {
                try {
                    o._yuid = uid;
                } catch (e) {
                    uid = null;
                }
            }
        }
        return uid;
    },

里面做了一个对IE的处理。ie会对每一个dom元素加上一个uniqueID,默认读取ie的uniqueID或者yuid。

图解学习JavaScript第二部分翻译

作者:kun10 发布时间:January 28, 2011 分类:JavaScript

图解学习JavaScript第二部分翻译



原文分三篇,第一篇是说一些JavaScript的基础特性,第二篇是说JavaScript向对象的一些思路,第三篇是把JavaScript和Ruby做了对比。
我比较在意的第二部分。翻译一下试试。
原文地址:
http://howtonode.org/object-graphs-2


图解学习之二



第一篇幅用图描述了Javascript的语法,这篇我会讲解三种JavaScript用于对象创建的技巧,分别是

  • 构造器+原型
  • 纯原型链
  • 对象工厂


我希望本文能够帮助人们理解每一个技巧的优点和缺点。


一、传统JavaScript构造器



我们先来创建一个简单的包含原型的构造器,这是你在原生JavaScript里面能找到的和类最相近的东西。他很强大。
但是,他又与传统的类语言有区别。



如下:


function Rectangle(width, height) {
  this.width = width;
  this.height = height;
}
Rectangle.prototype.getArea = function getArea() {
  return this.width * this.height;
};
Rectangle.prototype.getPerimeter = function getPerimeter() {
  return 2 * (this.width + this.height);
};
Rectangle.prototype.toString = function toString() {
  return this.constructor.name + " a=" + this.getArea() + " p=" + this.getPerimeter();
};  


现在,我们再来创建一个新的类叫做Square,他继承于Rectangles。为此,Square的构造器的原型要继承父类的原型。
然后我们会演示如何重写getPerimeter方法。

function Square(side) {
  this.width = side;
  this.height = side;
}
Square.prototype.__proto__ = Rectangle.prototype;
Square.prototype.getPerimeter = function getPerimeter() {
  return this.width * 4;
}; 


最后的调用也很简单,只要用new来创建一个实例。

var rect = new Rectangle(6, 4);
var sqr = new Square(5);
console.log(rect.toString())
console.log(sqr.toString()) 


传统构造器方式注意点:






对于上面的例子,注意rect实例和Square.prototype并不一样,虽然他们都是继承于Rectangle原型的简单对象,JavaScript的对象是一串链式的调用。
唯一特殊的对象是function,它们获取参数,并且掌握着内部执行的代码和作用域。


二、纯原型链式



我们依然来实现上面的例子,但我们这次不使用构造函数,这次我们只用原型链式继承。



我们先来定义一个Ractangle的原型作为我们所有对象的基础。

var Rectangle = {
  name: "Rectangle",
  getArea: function getArea() {
    return this.width * this.height;
  },
  getPerimeter: function getPerimeter() {
    return 2 * (this.width + this.height);
  },
  toString: function toString() {
    return this.name + " a=" + this.getArea() + " p=" + this.getPerimeter();
  }
}; 


现在我们再来定义一个子对象,它叫Square,并且重写了一些方法。

var Square = {
  name: "Square",
  getArea: function getArea() {
    return this.width * this.width;
  },
  getPerimeter: function getPerimeter() {
    return this.width * 4;
  },
};
Square.__proto__ = Rectangle;


然后我们就来看看创建具体的对象,我们在原型对象的基础上创建新的对象,并手工的修改它们的本地属性。

var rect = Object.create(Rectangle);
rect.width = 6;
rect.height = 4;
var square = Object.create(Square);
square.width = 5;
console.log(rect.toString());
console.log(square.toString());


输出:

Rectangle a=24 p=20 Square a=25 p=20


继续看图:






它并不如构造器+原型的方式来的强大,但是它直接易懂,如果你熟悉一个原型链式继承的语言,你会觉得很熟悉。


三、对象工厂



这是我很喜欢的方式————用一个工厂函数来创建对象的方式。它的不同在于,我只用简单的调用一个函数,它每次返回一个新的对象,而不是用一个原型对象供所有构造函数共享。



下面是一个很简单的MVC系统,controller函数接受表示model和view的两个参数,并输出一个新的controller对象。
这个过程中所有的状态都存贮在作用域的闭包里面

function Controller(model, view) {
  view.update(model.value);
  return {
    up: function onUp(evt) {
      model.value++;
      view.update(model.value);
    },
    down: function onDown(evt) {
      model.value--;
      view.update(model.value);
    },
    save: function onSave(evt) {
      model.save();
      view.close();
    }
  };
}


使用时只要简单的代入参数运行一下这个function。注意,现在我们不用先把工厂函数绑定给某个对象就可以直接传递函数给事件handlers(setTimeout)。
因为工厂函数没有在内部使用this,没有必要再去混淆this的值。

var on = Controller(
  // Inline a mock model
  {
    value: 5,
    save: function save() {
      console.log("Saving value " + this.value + " somewhere");
    }
  },
  // Inline a mock view
  {
    update: function update(newValue) {
      console.log("View now has " + newValue);
    },
    close: function close() {
      console.log("Now hiding view");
    }
  }
);
setTimeout(on.up, 100);
setTimeout(on.down, 200);
setTimeout(on.save, 300);

//输出
View now has 5
View now has 6
View now has 5
Saving value 5 somewhere
Now hiding view


上图:






此图对应了上面的调用过程,注意,我们可以通过工厂函数的隐藏作用域获取到两个匿名对象,也就是说,我们可以从工厂函数的闭包里面获取到model和view。

批量添加和管理事件处理

作者:kun10 发布时间:January 22, 2011 分类:JavaScript

引入behavior对象


在做日常的过程中,释然为我们大家制定了一个behavior对象。
他的作用就是用来统一的管理页面里面需要的事件绑定。
我们先看一下这个behavior对象的调用:

behavior.add(JSON);
K.ready(function() {
    behavior.apply();
});
以上用于添加事件

JSON的格式如下:
{
    'selector': func,
    'selector': {
        'event1':func1,
        'event2':func2
    }
}


这样的一个调用使得我们可以专注于对函数功能的编写,而不用再过于关注对dom对象的事件绑定的逻辑。


在没有这个对象的之前,我们写事件处理很容易随自己的想法写一大片的功能代码。
就像这样。

E.on(ele, 'click', function(){
    //里面写满了各种各样的处理逻辑,长的不得了。    
});    


这样在写的时候会让我们觉得很爽,但是我们却不愿意回头再整理这样的代码。


原因:
里面的事件处理特别长,要是里面再调用点别处(甚至别的文件的代码),有时候读代码都费劲。
事件处理函数编写零散,尤其多人合作的时候代码更是可能写到不一样的地方,难以归宗管理。

behavior的实现



behavior的实现主要依据它要达到的功能。

首先它要对事件进行集体的管理、其次它要对dom元素进行批量的事件绑定。



所以大体可以这样,这里我们把behavior对象通过对象来实现。

behavior = {
    add: func(JSON){},
    _events: {},
    apply: func(){}
}


我们用_events来做事件函数列表管理,再用add来对dom元素进行统一的事件添加管理。


最后使用apply方法把事件和对应的元素对应绑上。


如上所说add方法的作用是给dom元素和事件函数做一个映射。它接受的参数是一个json对象。


我们先做一些约定:

  • 如果用户直接对元素绑定了函数,就表示dom元素载入完成时执行函数
  • 如果用户指定了元素触发函数的事件,就对该元素绑定事件。


约定behavior使用的JSON的格式如下:

{
    'selector': func,
    'selector': {
        'event1':func1,
        'event2':func2
    }
}    


下面我们来分析add方法,add方法就是处理json对象,并把找到的dom元素和事件函数做关联

add: function(obj){
    //that用来保存behavior的活动对象
    var that = this;
    //K表示KISSY对象
    //K.each是用来遍历一个对象的属性的方法
    //当然这个对象我们上面做了约定!
    //所以在解析它的时候我们可以写的简单一些
    //如果我们要接受更加随意的格式,就要在解析对象的容错
    //上面下更多的功夫
    K.each(obj, function(one, name) {
        var el = D.query(name);//找到符合的元素,这里的name就是传入的selector

        if (K.isFunction(one)) {
            events = {
                'load': one//直接写函数的话就是用
            }
        } else {
            //如果是对象,就直接赋给events
            events = one;
        }

        that._events = events;//关联的结果保存在_events里面
    });

    return that;
}


之后就是使用apply对象来集中的绑定元素事件,apply准备放在K.ready事件里面触发。

apply: function() {
    //KISSY.ready 不能传送作用域,所以不能使用 this
    var that = behavior;

    K.each(that._events, function(one, name) {
        var el = D.query(name);
        if (el.length > 0) {
            //真正要做绑定了,先找到要绑定的元素
            //把每一个函数绑定到元素上面
            //之前的one就保存了元素的事件和对应的函数
            K.each(one, function(fn, eventType) {
                 
                if('load' === eventType) {
                    //因为已经是domready了,直接运行函数
                    fn(el);
                } else {
                    //使用KISSY的Event来绑定事件函数    
                    E.on(el, eventType ,fn);
                }
            });
        }
    });
}    


这样我们可以实现对事件函数的统一管理和统一添加。
也可以专注于对事件处理的函数编写。
另外在事件函数内部,我们也应该对用得较多的功能块使用函数封装来复用。



本例里面使用了KISSY API的each方法,ready方法,KISSY的Event对象和Dom对象。了解更多KISSY点

jsdoc简明使用教程

作者:kun10 发布时间:December 18, 2010 分类:JavaScript

发现自己没有去用过jsdoc,于是找今天这个时间看看。

其实jsdoc的使用并不难。

jsdoc的主页:http://jsdoc.sourceforge.net/

jsdoc的下载地址:http://code.google.com/p/jsdoc-toolkit/

在安装jsdoc之前你要保证你安装过来jre1.6.0 for windows或者是jre 1.5.9 for linux

下载下来,加压压缩包到D:\jsdoc目录,或者是你喜欢的地方

这就算安装好了jsdoc。

下面就说说使用吧!按我们存放的jsdoc的路径,我们这样运行jsdoc

java -jar D:\jsdoc\jsrun.jar D:\jsdoc\app\run.js -a -e=GBK -t=D:\jsdoc\templates\jsdoc -d=..\..\docs mycode.js

mycode.js就是你的js文件的目录路径
-e 是js文件的编码
-d 是jsdoc对应的docs的文件夹
这样就会生成对应的docs

如果你想给一定的目录结构生成docs,你可以这样写jsdoc命令,把js文件的路径替换成一系列路径

..\..\src\core\ ..\..\src\util\ ..\..\src\widget\

这样我们其实可以编写一个简单的dat文件来简单的批量处理创建docs的任务
如下:

java -jar jsrun.jar app/run.js -a -t=templates\jsdoc -e=GBK -d=..\..\docs ..\..\src\core\ ..\..\src\util\ ..\..\src\widget\

很简单吧。

其实要生成漂亮的文档靠的还是你的良好的注释
具体的格式参考这里:http://jsdoc.sourceforge.net/

js创建iframe缓存问题

作者:kun10 发布时间:November 30, 2010 分类:JavaScript

和网友讨论一个问题
iframe缓存静态资源,但是没有什么结论,反而因为一个demo总结了另一个小tip

如果你用js创建iframe,那么可能在某些情况下面会出现页面被缓存的其情况

测试demo:http://lab.zipeng.info/test-js-iframe.html

刷新页面的方式对js创建的iframe的影响

浏览器F5或者是刷新按钮强刷浏览器地址栏输入
FF3.6.12缓存刷新刷新
FF4.0b6刷新刷新刷新
chrome7刷新刷新刷新
IE6缓存刷新刷新
IE7缓存刷新刷新
IE8缓存刷新刷新

再次记一下

placeholder一点tip

作者:kun10 发布时间:October 17, 2010 分类:JavaScript

周末抽空做了做chrome extension
在做option.html的时候,使用了input标签来做插件的参数的输入设置,出于新技术的一个尝鲜,给input标签加了一个placeholder属性。
像这样的:

<input id="theIp" type="text" placeholder="请填上服务器的ip" value=""/>

之后我写了一个按钮并运用localStorage来存储这个input的值,然后企图在页面再次载入的时候在input里面显示这个值。

经过了测试,页面在载入的时候的确利用js重写了这个input的value属性,用console查看就是这样的

<input id="theIp" type="text" placeholder="请填上服务器的ip" value="11.11.11.11"/>

但是此时浏览器里面的input依然显示着placeholder的值。照理说value填入了值placeholder就应该没有了。

很费解,找了半天原因,最后点击了input,发现value出来了。

于是在页面载入的时候添加了一段代码

theinput.focus();
theinput.blur();

这样子页面载入后用js修改input的value,placeholder就能除去。

纠错


-----update最新修改 2010/10/17-----
造成这样的原因是因为当时我使用了setAttribute来设定input的value属性,使用了这样的方式,就得用以上的技巧来消除placeholder的影响。如果直接对input.value赋值,如果有值,placeholder自动会消失。这也说明value的设定上面两种方式还是有差异的。
--------------------------------

  1. 1
  2. 2