- 浏览: 367360 次
- 性别:
- 来自: 阿里巴巴
文章分类
- 全部博客 (207)
- Maven (5)
- Cassandra (2)
- Hadoop (3)
- LDAP (2)
- SOA (7)
- 认证、加密、安全 (6)
- 搜索引擎相关技术 (3)
- REST (7)
- 数据库 (11)
- Java 基础相关 (38)
- UML (1)
- Java NIO 框架 (3)
- javassist (1)
- Bean容器 (4)
- 网络编程 (1)
- NoSQL (4)
- XML、Json (1)
- JS (2)
- Google (6)
- Warp-MVC (2)
- 持久层 (2)
- sitebricks (1)
- MVC (6)
- CSS (2)
- JPA (2)
- RDBMS (5)
- cache (4)
- tomcat (1)
- 其它 (3)
- eclipse (1)
- bigpipe (1)
- RDBMS MySQL (1)
- MySQL (2)
- ant (1)
- 前端 (2)
- Groovy (1)
- linux (3)
- Scala (1)
- zookeeper (1)
- redis (2)
- 测试 (1)
- 监控 (1)
- mac (3)
- 区块链 (3)
- 工具 (1)
最新评论
-
masuweng:
好好好,辛苦了!!
Spring Data JPA 简单介绍 -
masuweng:
Spring Data JPA 简单介绍 -
zhangjianxinjava:
您好,大神本人小白一个最近在研究不知道可否 通过邮箱进行交流, ...
JAVA Metrics度量工具 - Metrics Core -
xzs603:
http://zhengdl126.iteye.com/blo ...
数据库水平切分的实现原理解析---分库,分表,主从,集群,负载均衡器 -
JavaStart:
运行mysql2redis 的install.sh 文件为何提 ...
mysql到redis的复制
JS学习
本文目的在于为Java或有语言基础的同学参于前端开发提供指导 语句如果它们在单独一行,那么结尾的分号可以省略。 注:为了一致性和避免错误(如压缩或merge带来的错误),我们要求所有语句都要加分号(块语句和函数申明语句后不需要分号) [注] 我们不能写出这样的句子 和Java相比,Javascript允许在标识符中使用$,所以很多库都用它来定义特殊作用的全局对象 像jQuery, Prototype, Mootools等框架使用$操作页面节点, 它仅是一个普通的函数 所以$可以用作有"特殊"含义的变量名 123, 0xf000, 0377(8进制) 可以使用Math对象进行常见的科学计算,见 http://w3schools.com/js/js_obj_math.asp 此外Javascript也定义了一些特殊的Number用于合适的需要, 如NaN, Number.MAX_VALUE, Number.MIN_VALUE, 注:当使用parseInt将字符串转成整型时, 请带上进制, 否则如果有前缀是0,会被当成8进制处理可能不符合预期需求 可以使用单引号或双引号两种形式 [String对象的方法请参考] false, null, undefined, 0, NaN, '' 在逻辑判断中都被当成 false 处理 申明式和语句式区别 jQuery对象是怎么造就的? 注: 使用Literal语法构造对象,而不是new Object() [Array的方法请参考] 注: **总是使用Literal语法构造数组, 而不是使用 new Array() ** 拼接字符串, 在Java中使用StringBuilder或StringBuffer拼接字符串,以减少临时对象的产生提高GC效率。 [注] 在Object/Array最后一个元素后面不能加逗号,尽管这在标准上允许,但是在IE6 7 浏览器下会报语法错误 所以可能在某些代码中发现以下写法以避免上述错误 不过我不推荐这样的形式,注意点就好,因为上述形式可能会带来其他隐患,并且可读性也不好。 变量在JS中是函数作用域的,而不是块作用域(C, Java, C#等是块作用域) 在函数作用域内定义的var都相当于在一开始定义一样 即一个函数执行时,引擎分两步操作 所以上述代码相当于这样: 这会让javascript虚拟机实现closure更方便,让内存模型更简洁 [最佳实践] 所以 函数尽可能得短小, 以满足前面两个条件 一句话: 总是使用 === 和 !==进行比较 因为 == 和 != 在比较时如有必要,会进行类型转换 [具体的比较规则请参考] ECMA262 11.9.3 如果不想看, 可能参考一条规则: null == undefined, 字符串和boolean都转成数字进行比较 一般情况下, this指向调用它的那个对象或者 GlobalObject, 在浏览器中为window 所以函数中的this指向和如何调用它有关系,和在哪里定义这个函数关系不大 至于call和apply的区别, 只是方法支持参数的区别, 功能一样 这里我们似乎看到了js面向对象的影子 如果function返回object, 则new 返回那个object, 否则返回引擎构造的那个object 函数内部除this外,还有一个对象就是arguments, 它是一个类数组,保存着函数的调用参数 我们可以对arguments进行迭代, 但如果我们要使用数组的方法操作它,就需要把它转化成数组 读取一个对象成员时, 会走prototype链, 设置一个对象成员时, 对prototype无影响 比如像这样: 所以我们可以用prototype对象来实现类, 以及用prototype链来实现继承 我们使用如下模板书写一个简单的类 JS是动态的语言, 可以很方面地实现对象的功能扩展, 所以比较少用继承 如果使用继承, 我会使用以下方法来实现, 因为代码较原型链方式来得更简单 在js中,变量是函数作用域的,这一点上面已讲过 这里的访问主要考虑嵌套函数的调用, 即一个非常重要的特性Closure 每次调用一个函数时, 执行函数代码前, Js执行引擎要做些准备工作, 其中会创建一个称为 Call Object的对象 JS的语言本身非常精简, 整个ECMA262规范只有200页, 其中有一半用来介绍了核心库的内容, 引擎核心内容总结如下: this会动态地指向BindObject, 所以又称为动态作用域. 我们对this属性的访问就是访问这个对象的属性. 变量的访问,其实是访问的是Call Object的属性, CallObject链根据词法结构就已确定, 所以又称为静态作用域,或“词法作用域” 对象属性(成员)的访问,遵循的是prototype链, 由于这个链在js中是可以直接访问的,所以又称为"明链" [如果对上述内容详细内容感兴趣可以参看] JS是一门动态灵活的语言, 不同的同学可能写出风格完全不同的代码. 首先需要参考: 前端CodeReview列表 如 Diy皮肤功能, Js文件名为 diy-skins.js 我们把文件中模块代码包含在一个自执行匿名函数中, 以避免全局名字空间冲突 因为我们的merge脚本不够强, 为了按需加载和减少请求数, 有可能会把一个组件所有代码放在一个文件中 [1]. 这个区域相当于java的import区, 根据需要可以alias一些用到的类 像这样: [2]. 主模块(类/对象)名要求和js文件名尽量保持一致 [3]. 初始化方法或构造函数名称为init [4]. 最后当页面domready时应该执行初始化方法, 所以调用jquery.ready方法 (在旺铺中进行一些封装,所以调用PageContext.register进入注册) [1]. 构造函数 [1]. 调用父类构造函数 关于文档注释可参考: Google Javascript Gude BOM就是浏览器提供给我们可以操作浏览器的API 我们常用的有: [参考] DOM提供用于访问HTML/XML文档的API 浏览器之间有差异性,所以一般使用js类库来间接访问DOM API 有时候页面较简单,或者没有JS库引入, 那可以直接使用 所以jQuery包含两种操作: dom ready后,表示可以使用js操作页面dom节点, 它比onload要早, 因为onload要等图片全部加载完 我们可以扩展jQuery功能, 但在应用中我们不允许这么做, 维护fdevlib的同学可以根据需要扩展库 跨域jsonp请求 浏览器会产生一次url类似 url?callback=jQuery23522552_24342344的调用 jQuery23522552_24342344({"success": true, data: ...}) 此段代码将会作为js代码在客户端执行,即调用一个由jquery随机生成的方法, 这个方法会调用我们的success方法, 跨域调用要求使用jsonp方式,从避免造成全局名字空间污染和覆盖, 也方便浏览器对数据进行垃圾回收 { "success": true | false, data: ... } 动态载入script文件 注, 由于IE实现上的原因,造成造成script文件返回302也会进入success逻辑 当然我们也可以使用这个方法发起xhr请求 注: 在IE下,xhr请求, 服务器如果返回302跳转(如另一页面退出后,旺铺DIY后台发起xhr post请求,服务端会返回302), 将会进入success逻辑 默认情况下, 如果你ajax请求(包括xhr, jsonp, getScript), 如果有参数data, 并且类型为object, 则jQuery使用 如果后端木有按要求解码,这可能会产生问题. 有两个解决方法: 关于ajax或编辑相关的jquery api有: $.param, $.paramSpecial, $.serialize, $.serializeArray 额外阅读: 关于跨域请求数据,除了使用getscript jsonp还可以使用window.name机制, work平台就使用了这个机制 关于script执行和浏览器渲染阻塞问题,请参看 这两个方法由fdev-v4提供, 使得我们可以按需加载组件 动态加载的方式使用我们的组件 在我们的应用中使用这种机制 根据我的经验,最有用的只有两个 $.isArray - 判断是否为数组 如果引入了fdev-min.js, 则可以使用String#trimg() 或 $.trim() 此方法由fdev-v4提供 namespace用于方便创建一个多层嵌套的对象结构用于代表名字空间(类似于java的package) 在应用中,我们不允许污染全局名字空间,一个应用往往只分配到一个名字空间 那我们旺铺中的其他类都在这个名字空间下, 初始化时会分配了如下几个名字空间 前后台都需要,在global/base.js中 后台, 在page/diy/diy.js中 注: 上述为何有的文件在global中,有的文件在 page/diy中, 请参看 style目录结构规划, 下面这样写达不到目的 所以proxy用于方便创建一个代理function, 让被代理的function具有指定的context 1.6版本的proxy还可以包装额外的参数,但文档还没有更新,具体可参看源码 1.6.2 第804行 提外话: 为了提高JS代码可读性, 我曾做过分享, 其中有一条是: 一个功能性方法,代码行数不超过40行(正常情况下会在一屏之内) 如果要达到上述要求,方法里面将不可能包含很深的嵌套, 即代码嵌套层次不超过3 如: $.map, $.makeArray $.map 相当于 CollectionUtils.transform 简单选择器(simple selecotr) 尽量使用简单的选择器, 如 非常简单, 一句话: id > 非(id,tag) > tag, 相同等级看数量 参看 http://www.w3.org/TR/css3-selectors/ 第9节 [额外阅读] CSS3选择器详细内容请参考W3C文档: http://www.w3.org/TR/css3-selectors/ // from 选择器 // from dom节点 // from jquery对象 如果针对本文档,在firefox script watch中输入 jQuery('ul'), 将创建一个jQuery对象, 了解这个是为了让我们更好地使用jQuery,而不是把$(美元符号)当作一种奇怪的语法来用. 为了增加可读性,提高效率和减少不必要的内存消耗, 请记住 $(elm) 等于 new jQuery(elm); 上述事件挂接,也可以使用bind click方法只是bind方法的一个包装, 相似的还有其他事件: change, resize, dblclick, keypress 等 关于其他事件请参考: http://api.jquery.com/category/events/ 关于事件函数有几点说明: this指向触发事件的元素(html dom节点) 我们可以从中获取一些关于事件的参数, 如鼠标位置,键盘输入等等, 关于event object请参考: http://api.jquery.com/category/events/event-object/ 有时候需要人为地触发一个浏览器事件, 如提交表单 或者 同bind, 无参数的click或submit只是trigger的一个包装 trigger它会执行浏览器默认行为, 比如当你click一个checkbox的时候, 界面中的checkbox也会勾选或取消勾选 如果只想执行事件,而不触发默认行为, 请使用triggerHandler 同时trigger和triggerHandler还支持额外的参数,具体可参考文档 http://api.jquery.com/trigger/ 当我们点击input.search-btn时, input.search-btn, div.search-bar, div.#header, div#doc, body 依次会触发click事件. 关于事件冒泡更细致的内容可参考: http://api.jquery.com/category/events/ 所以如果我们所事件函数挂接在外围节点, 将能接收到里面子节点的事件. 关于namespace的参考链接, 官网上我一时找不到了, 不好意思,以前记得有的,现在只有一点点: http://api.jquery.com/bind/ 或者直接参看源码可能会更清晰: jquery 1.6.2, 第2619行, 第2726行, 第2810行 节点操作的api可直接参考 http://api.jquery.com/category/manipulation/ 有几点需要说明, dom节点操作是所有操作里最慢的, 往往页面的效率瓶颈就在dom操作,所以要特别注意 改变属性的操作 如: addClass, removeClass, css等需要浏览器重绘节点 具体请参考: 《High Performance Javascript》chapter 3 可以像这样: jQuery#data 用于在节点上保存节点相关的数据, 这样在需要的时候就可以根据节点取得相应数据 我们使用html5 data标签代替以往的input:hidden域,来保存后端需要传递给前端的页面参数 jQuery会足够智能地解析出需要的结构,大概规则是: 感兴趣的可以查看源码: 1.6.2版 1689行,dataAttr方法 可以使用 $.util.ua (由fdev-v4包装) 来检测是否IE浏览器和版本号 具体请参考: http://api.jquery.com/jQuery.support/ 其他api可以直接看文档就可以,而且官方文档都有相关例子,不需要再做介绍 前端基础库请参考: http://fd.aliued.cn/fdevlib/#home Javascript书和参考资料语法和语义
可选的分号
var a = 1;
a += 1;
var callback = function() {
return 'hi';
};
// 函数申明语句
function other() {
}
for (var i = 0; i < 10; i++) {
}
if (a === 123) {
}
function abc() {
return // 返回123
123;
}
abc(); // -> undefined
标识符(Identifier)
// 在jQuery中
$('#mydiv a').css('color', '#f00'); // 设置链接颜色
// 在旧版本的Mootools中
if ($type(abc) === 'string') { // 新版本使用typeOf代替
}
// 在中文站JS基础库FDEV3中
var elm = $('mydiv'); // 相当于document.getElementById('mydiv');
// 在有些同学的代码中, 用于在内部函数中访问外围对象
var Test = {
hi: function() {
var $this = this; // 我见过的常用的名称还有 that, self, me 等,
// 使用self有一个隐患,就是忘记了定义self时,
// 会造成难以排错,因为有一个全局的self会产生干忧
$.ajax(url, {
success: function(o) {
o.success && $this.render(o.data)
}
});
},
render: function() {
}
};
基础数据类型和字面量(Literal)
Number
3.14, .222, 1.2e12, 1.4e-12
参考《Javascript权威指页》3.1.6var num = parseInt(inputText, 10); // 如在文本框输入页码等
String
var str1 = '我是一个字符串,包含着双引号"'; // 单引号中的双引号可以不用转义,当然使用转义也木有问题
var str2 = "我是另一个字符串, 包含着单引号'";
var template =
'<div>\
<dl>\
<dt>示例1</dt>\
<dd></dd>\
<dt></dt>\
<dd></dd>\
</dl>\
</div>';
String和Number的转化技巧
parseInt('123', 10); // 注: 请加上第二个参数
'123' - 0 // 注: 不能使用+
456 + ''
123456 + '元' // -> '123456元';
http://w3schools.com/jsref/jsref_obj_string.aspBoolean
var keyword = $('#keyword').val();
if (!$.trim(keyword)) {
// 用户输入为空
}
var num = $('#num').val();
num = parseInt(num, 10);
if (!num) { // NaN
// 用户输入非法数字
}
Function
// 申明式
function a() {
}
console.debug(a.name) // -> 'a'
// 匿名函数
var b = function() {
};
console.debug(b.name) // -> ''
fun(123); // 在这里就可以使用
function fun(value) {
console.debug(value);
}
b(123); // b is undefined;
var b = function() {
};
Object Literal
var album = {
name: 'pipixiuxiu', // 注,这里的name不是变量, 只是省略了单引号
‘count’: 100,
'private': true, // 当属性名称是保留字时,必须使用这种方式
234: '较少用',
12.34: '更少用'
};
album.name;
album['count'];
album[234];
var o = {
0: elm0,
1: elm1,
2: elm2,
3: elm3,
length: 4,
splice: function() {} // firebug看到这个会以为它是个数组,所以显示方式和数组一样
...
}
var o = {}; // 而不是 new Object();
Array Literal
var ary = [];
ary[0] = 'one';
var list = [99, 'some string', function() {}];
http://www.w3schools.com/jsref/jsref_obj_array.aspvar array = []; // 而不是new Array();
在JS中使用数据组达到这一目的。var html = [];
elms.each(function() {
html.push('some string ...');
});
html = html.join('');
所以,如果发现在FF下工作正常,在IE下工作不正常,请检查是否object或array最后多了个逗号var o = {
name: 'pipi',
desc: 'er er er',
// price: 12 // 在调试中把这句注释了,造成上面一句最后多了个逗号
};
var o = {
name: 'pipi',
desc: 'er er er',
// price: 12,
_: 0 // 多了一个这样的元素
};
可以借助工具来扫描这类错误, 如JSLint: http://www.jslint.com/变量的作用域
function hello() {
var a = 123;
for (var i = 0; i < 10; i++) {
var a = 234;
//...
}
console.debug(a); // -> 234
}
1. 处理所有var语句(和函数申明语句), 准备好执行环境, 相当于这些var和function申明语句写在函数的最前面
2. 执行函数内的语句function hello() {
var a,
i;
a = 123;
for (i = 0; i < 10; i++) {
a = 234;
//...
}
console.debug(a); // -> 234
}
function hello() {
alert(a); // alert(undefined);
if (false) {
var a;
}
}
等效于
function hello() {
var a;
alert(a);
if (false) {
}
}
function hello() {
alert(a); // ReferenceError: a is not defined
}
关于 ==, !=, ===, !==
null == undefined // -> true
'0' == false // -> true
'1' == true // -> true
null == false // -> false
undefined == false // -> false
关于 this, new, apply, call
当调用一个方法(函数时),函数内部的this指向一个对象, 在规范中被称为: ThisBinding, 我喜欢叫它BindObject
var A = {
hello: function() {
console.debug(this);
}
};
A.hello(); // -> A
var b = A.hello;
b(); //-> Global Object, 在浏览器中即是window
我们可以使用call或apply方法参数化this
var A = {
name: 'A',
function hello() {
console.debug(this.anme);
}
};
A.hello(); // this === A
var B = { name: 'B' };
A.hello.call(B); // this === B
fun.apply(o, [arg1, arg2, arg3]);
function.call(o, arg1, arg2, arg3);
new 操作符会构造一个对象, 并且让this指向它
function A() {
console.debug(this);
}
A(); // -> window
new A(); // -> object, object !== window
function People(name) {
this.name = name
}
var p1 = new People('p1');
var p2 = new People('p2');
assert(p1 !== p2);
assert(p1.name === 'p1');
关于new的返回值
function A() {
}
new A(); //-> object
function B() {
var o = {
};
return o;
}
new B(); //-> o
function C() {
return 1; // typeof 1 === 'number', 1 is not an object
}
new C(); // -> object, not 1
关于 arguments
function a() {
var args = arguments,
a = args[0],
b = args[3],
len = args.length;
}
var ary = $.makeArray(arguments); // $ is jQuery
var ary = [].slice.call(arguments, 0); // 如果没有库支持
成员访问, prototype链, 继承
var A = {
name: 'A',
hello: function() {
console.debug('hello ' + this.name);
}
};
A.name; // 'A'
A.hello(); // 'hello A'
var CA = function() {
};
CA.prototype = A;
var o = new CA();
// 读取时, 如果必要, 则访问 prototype
o.name; // 'A'
o.hello(); // 'hello A'
// 设置
o.name = 'o';
o.name; // 'o' // 找到了, 就不需要访问 prototype了
o.hello(); // 'hello o'
// A未曾改变
A.name // 'A'
A.hello // 'hello A'
var A = function() {};
A.prototype = { propPA: 'PA' };
var a = new A();
a.propA = 'A';
var B = function() {};
B.prototype = a;
var b = new B();
b.propB = 'B';
var C = function() {};
C.prototype = b;
var c = new C();
c.propC = 'C';
console.debug(c.propC); // C
console.debug(c.propB); // B
console.debug(c.propA); // A
console.debug(c.propPA); // PA
console.debug(c.toString()); // [object Object]
var A = function() {
this.init.apply(this, arguments); // 代理给prototype.init
};
A.prototype = {
/**
* 构造函数
*/
init: function(name) {
this.name = name; // 对象属性
},
/**
* 实例方法
*/
hello: function() {
console.debug('hello ' + this.name);
}
};
var B = function() {
this.init.apply(this, arguments);
};
B.prototype = $.extendIf({
init: function(name, age) {
A.prototype.init.call(this, name); // super(name)
this.age = age;
},
say: function() {
}
}, A.prototype);
变量访问, call object, Closure
var welcome = 'welcome ~~~';
function hello(name) {
var prefix = 'hello';
alert(welcome);
function say(postfix) {
var my = 'string my';
alert(prefix + name);
alert(my)
alert(postfix)
}
return say;
}
var say = hello('alibaba');
say('good bye');
而调用方法的形式参数, 局部变量, arguments等就成为这个对象的属性.
所以访问形式参数, 局部变量, arguments就相当于访问这个对象的属性总结
语言语法,语义,引擎的实现全部加起来也才100页. 所以真的是非常地精巧, 但描述能力却很强大.
由于这个链在js中是不能访问的, 所以又称"暗链"
* 《Javascript权威指》: 4.6 4.7
* ECMA 262 10.3 ~ 10.6
* http://jibbering.com/faq/notes/closures/
* 我的文章: http://b2b-doc.alibaba-inc.com/pages/viewpage.action?pageId=47748204惯用法和技巧
// 检测空串
if (!$.trim(str)) {
}
// 字符串/数字类型转换
var str = '100';
var num = str - 0;
var str2 = num + '';
// 空检则
if (!value) { // undefined, null, false, 0, '', NaN 等为 '空'
}
// 逻辑或 ||
if (!a) {
a = 100;
}
a = a || 100; // 注意 不能写成 a ||= 100, 虽然ruby支持
if (!this.elm) {
this.elm = $('#mydiv');
}
this.elm = this.elm || $('#mydiv');
var pageSize = 10;
if (data && data.pageSize) {
pageSize = data.pageSize;
}
pageSize = (data || {}).pageSize || 10;
// 逻辑与&&
function(success) {
if (success) {
success('abc');
}
success && success('abc');
}
注意: 不能写成 options.delay && this.delay = true; 赋值运算附优先级低
可以是 options.delay && (this.delay = true);
// 默认参数
function hello(options) {
options = $.extend({
time: 1000,
color: '#f00',
'font-size': '12px'
}, options);
...
}
// 字符串拼接
var html = [];
for (...) {
html.push('...');
}
html = html.join('');
// 字符串模板
var template =
'<div>\
<dl>\
<dt>示例1</dt>\
<dd></dd>\
<dt></dt>\
<dd></dd>\
</dl>\
</div>';
编码规范和JS书写模板
所以参考或使用此模板目的在于提高js代码一致性和可读性.页面功能的普通功能
原则上一个文件只包含一个模块(一般是一个主类)
但是也需要把每个模块放在各自的自执行匿名函数中/**
* 旺铺Diy后台皮肤选择
* @author qijun.weiqj
*/
(function($, WP) {
[1]
var Util = WP.Util,
UI = WP.UI,
PageSwitcher = WP.widget.PageSwitcher
...
[2]
var DiySkins = {
[3]
init: function() {
},
initCatsPanel: function() {
},
initSkinPanel: function() {
}
};
[4]
WP.PageContext.register(...)
// 相当于
// 页面载入后就执行
$(function() {
Diy.Skin.init();
})
})(jQuery, Platform.winport);
当然现在我们还需要在merge文件中包含需要的库文件.
后续我们会期望引入脚本来自动merge导入的类var Util = require('widget/util'),
UI = require('widget/ui'),
ModBox = require('diy/mod-box');
模块需要提供给其他模块使用(单例)
(function($, WP) {
var UI = {
[1]
/**
* 缩放图片
* @param {jquery} selector ...
* @param {int} size ...
*/
resizeImage: function(selector, size) {
},
[2]
_resize: function() {
}
/**
* IE6 position fixed
*/
positionFixed: function(selector) {
}
};
[3]
WP.widget.UI = UI;
})(jQuery, Platform.winport);
模块需要提供给其他模块使用(多实例)
(function($, WP) {
var Tabs = function() {
this.init.apply(this, arguments);
};
Tabs.prototype = {
init: function(tabs, bodies) {
},
_create: function() {
}
};
WP.widget.Tabs = Tabs;
})(jQuery, Platform.winport);
为继承而设计的类
(function($, WP) {
var Dialog = function() {
this.init.apply(this, arguments);
};
Dialog.prototype = {
[1]
init: function(options) {
..
render(this);
},
[2]
close: function() {
},
[3]
_createButtons: function() {
}
};
[4]
function render(self) {
self._createButtons();
}
WP.widget.Dialog = Dialog;
})(jQuery, Platform.winport);
[2]. public方法
[3]. protected方法, 可由子类重写
[4]. private方法继承其他类
(function($, WP) {
var Dialog = WP.widget.Dialog;
var FormDialog = function() {
this.init.apply(this, arguments);
};
FormDialog.prototype = $.extendIf({
init: function(options) {
[1]
Dialog.prototype.init.call(this, options);
},
[2]
_createButtons: function() {
Dialog.prototype._createButtons.call(this, ...);
...
},
[3]
__createForm: function() {
},
[4]
getData: function() {
}
}, Dialog.prototype);
[5]
function createForm2(self) {
}
WP.diy.FormDialog = FormDialog;
})(jQuery, Platform.winport);
[2]. 重写父类方法, 调用父类方法
[3]. private方法
[4]. public方法
[5]. private(和3选择一种形式即可)BOM和DOM简介
BOM
打开新窗口, 查看当前URL信息, 检测浏览器类型和版本号, 返回前一页, 查询屏幕分辨率等
http://w3schools.com/jsref/
《Javascript高级程序设计》第8章,第9章DOM
jQuery学习
设计理念
// jQuery是一个function, 返回一个对象(称为jQuery对象)
var jQuery = function() {
return new jQuery.fn.init(...);
};
// jQuery对象的实例方法由 jQuery.fn决定
jQuery.prototype = jQuery.fn = { ... };
jQuery.fn.init.prototype = jQuery.fn;
// 采用这种方法扩展jQuery
jQuery.fn.bind = function() { ... };
// 采用这种方法扩展静态方法
jQuery.extend = function() {...};
jQuery.each = function() {...};
一种是和DOM结点无关, 直接调用静态方法即可, 如$.ajax, $.each等
一种是和DOM结点相关, 需要首先构造jQuery对象, 再使用它的实例方法, 如事件绑定jQuery#bind, 样式设置jQuery#css等Utility
<script src="http://style.china.alibaba.com/js/lib/fdev-v4/core/fdev-min.js"></script>
(function($) {
// 这里$就是jQuery
})(jQuery);
$.ready 初始化
$.ready(function() {
});
// 可以简写
$(function() {
});
$.each 迭代
var array = ['one', 'two', 'three'];
$.each(array, function(index, item) {
// 当item类型为object时, 可使用this访问item, 否则请使用参数方式访问item
});
var o = { name: ..., value: ... };
$.each(o, function(key, value) {
});
$.extend 扩展
// 默认参数
function hello(options) {
options = $.extend({
title: '测试',
delay: 1000
}, options);
...
}
// 扩展功能
var A = {
a: function() {
}
};
$.extend(A, {
b: function() {
}
});
// clone
var o = {...};
var other = $.extend({}, o);
$.extend({
add: function() {
},
use: function() {
}
});
$.fn.extend({
tabs: function() {
}
});
$.extendIf (由fdevlib实现), 类似于extend, 但如果存在相同key的项则不添加, 我常常使用它来实现"继承"
var Base = {
a: function() {
},
b: function() {
},
c: function() {
}
};
var A = $.extendIf({
b: function() {
},
d: function() {
}
}, Base);
var Base = function() {
this.init.apply(this, arguments);
};
Base.prototype = {
};
var A = function() {
this.init.apply(this, arguments);
};
A.prototype = $.extendIf({
}, Base.prototype);
ajax
$.ajax(url, {
dateType: 'jsonp',
success: function(o) {
o.success && self.render(o.data);
}
});
期望浏览器返回这样的文本
于是我们就得到了数据
返回的数据格式要求如下:
$.ajax(url, {
dateType: 'script',
success: function() {
// 在这里script文件就载入完毕了
}
});
所以如果如果采用古老的get script方式来跨域请求数据的话, 需要在success里进行判断.
$.ajax(url, {
dateType: 'script',
success: function() {
if (window.myData) {
...
}
}
});
// 以上服务器反回这样的串串: var myData = ...
$.ajax(url, {
type: 'post',
data: { ... }
success: function(html) {
div.html(html);
}
});
$.param来编码你的数据, 内部会使用 encodeURIComponent, 这将导致中文编码成utf8.
1.前端不编码
自己使用$.paramSpecial-- 这个方法由fdev-v4提供, 用于object -> string, 并且不编码, 只转义几个uri中不允许的字符
2. 要求后端解码(可能需要加参数input_charset参数), 这一条优先采用
具体请参考: http://www.planabc.net/2008/09/01/window_name_transport/
《高性能网站建设进阶指南》第4章或《高性能Javascript》第一章动态加载 $.add, $.use
$.use('web-alitalk', function() {
FE.util.alitalk($('a[data-alitalk]'));
});
// 在应用配置文件中注册
$.add('wp-dialog', {
js: ['http://....dialog.js']
});
// 在需要的地方使用
$.use('wp-dialog', function() {
new WP.widget.Dialog({
...
});
});
类型检测
$.isPlainObject - 判断是否为"简单"对象
if (typeof a === 'string') {
}
if (typeof a === 'function') {
}
if ($.isArray(a)) {
}
$.trim
如果仅仅使用jQuery, 则可以使用$.trim(), 因为有些浏览器(例IE6) 没有实现trim方法$.namespace
比如旺铺是 Platform.winport, offer发布是在 Platform.postofferjQuery.namespace(
'Platform.winport',
'Platform.winport.widget', // 业务无关组件
'Platform.winport.unit' // TODO 后续去掉mod.unit名字空间
'Platform.winport.mod', // 板块
);
jQuery.namespace(
'Platform.winport.diy',
'Platform.winport.diy.form' // 板块编辑
);
直接看文档 http://fd.aliued.cn/doc/page/regulations/dir-structure$.proxy
var Page {
init: function(config) {
var self = this;
this.config = config;
$.use('ui-dialog', function() {
self.initDialog();
});
},
initDialog: function() {
// assert(this === Page);
node.dialog({
center: this.config.center
});
}
};
// 使用proxy
var Page = {
init: function() {
$.use('ui-dialog', $.proxy(this, 'initDialog'));
},
initDialog: function() {
}
};
var Page = {
init: function(config) {
this.config = this.config;
$.use('ui-dialog', this.initDialog);
},
initDialog: functoin() {
assert(this !== Page);
this.config // undefined
}
};
一个看源码技巧: 在页面中引入jquery非压缩版.
在firebug script tab的watch中输入jQuery, 展开对象找到相应的方法单击即可看到相应的源码
var Page = {
init: function() {
var arg1 = 'arg1',
arg2 = 'arg2';
$.ajax(url, {
dateType: 'jsonp',
success: $.proxy(this, 'ajaxSuccess', arg1, arg2);
});
},
ajaxSuccess: function(arg1, arg2, ret) {
assert(this === Page);
assert(arg1 === 'arg1');
assert(arg2 === 'arg2');
if (ret.success) {
...
}
}
};
var Page = {
initPartA: function() {
var self = this;
// level 1
$.ajax(url, {
dateType: 'jsonp',
// level 2
success: function(ret) {
// level 3
ret.success && self.render(ret.data);
};
});
},
render: function(data) {
}
};
其他常用方法
function test() {
var args = $.makeArray(arguments);
}
// 参数可以是数组或非数组
function test(args) {
args = $.makeArray(args);
}
var links = $('a'),
urls = null;
urls = $.map(links, function(index, link) {
return $(link).attr('href');
});
选择 与 CSS3选择器
认识选择器
$('*'); // universal selector 星号选择器 选择所有节点
$('div'); // type selector/element selector 类型选择器(我习惯叫它tag选择器)
$('#header'); // id selector id选择器
$('.input-text'); // class selector class选择器
$(':input'); // pseudo selector 伪类选择器 选择所有表单输入域
// a:hover, a:linked, a:visited 两个冒号带头的就是 伪类选择器
$('li:first') // 选择第一个li节点
$('[name="alibaba"]') // attribute selector 属性选择器 选择所有name属性=alibaba的节点
$('[name]') // 存在...
combinator
~~~js
$('#header a') // descendant selector 后代选择器
$('#header ul li')
$('#header>div') // child selector 子代选择器
// 下面两个邻代选择器应该不常用, 我从来没有用过
$(':input+span') // next adjacent selector 在input后面的, 紧挨着的那个span
$(':input~span') // next sibling selector 在input后面的, 所有同代span
$('div,a,:input') // multiple Selector
$('a.close:acitve') // and
使用选择器
$('#id')
$('a.close', container) // class需要带tag限制,
// 由于在ie6等浏览器对class没有原生api支持,使得单纯的class selector比较慢
$('ul>li', container) // 有context限制
优先级
jQuery支持的选择器请参考: http://api.jquery.com/category/selectors/构造jQuery对象
$('#publish-dialog a.close');
var dom = $('#doc')[0];
$(dom);
var chooser = $('div.offer-chooser');
var panel = chooser.find('ul.chooser-panel');
或者
var panel = $('ul.chooser-panel', chooser); // 内部调用 find来完成jquery对象结构
用于操作文档中所有ul节点, 展开它会看到如下对象结构{
0: ul, // HTMLUListElement, 即原生dom节点对象
1: ul,
2: ul,
...
7: ul,
length: 8,
selector: 'ul',
context: document,
prevObject: document
...
}
见下面这段jQuery初学者常见的代码$('a.close', div).click(function() {
$(this).addClass('abc');
if (...) {
$(this).attr(...)
} else {
$(this).data(...);
}
$(this)...
});
只构造必要的jQuery对象, 上述代码可以这么写elms.click(function() {
var elm = $(this); // 保存引用
...
});
基本操作
var lis = $('ul.offer-list li');
if (!lislength) { // 判断节点是否存在
return;
}
lis.eq(0).addClass('first'); // 只对第一个节点处理, 相当于 $(lis[0]).addClass('first');
var firstLi = lis[0]; // 取得第1个节点(html dom元素)
lis.each(function(index) {
var li = $(this); // each中的this是原生的dom对象
li.data('offer', offers[index]);
});
事件
普通事件
$('a.open', panel).click(function(e) {
e.preventDefault();
new Dialog({
header: '设置'
width: '700',
height: '350',
confirm: function() {
...
}
});
});
button.bind('click', function(e) {
...
});
几乎所有常用的浏览器事件都有直接对应的方法用于挂接或触发事件
$('a.delete', list).click(function(e) {
e.prevent();
var link = $(this), // here, is a html element
li = link.closest('li'),
postId = li.data('postId');
Post.delete(postId);
});
或者取消浏览器默认事件, 阻止冒泡$('a.close', dialog).click(function(e) {
e.preventDefault(); // 阻止链接正常行为,
// 因为这个链接是作为功能按扭来使用的, 而不需要跳转或重新定位瞄点
...
});
$('div.canvas').mousemove(function(e) {
var x = e.pageX, // 鼠标位置
y = e.pageY;
});
$('input.username').keydown(function(e) {
var self = this;
if (e.keyCode === 13) { // 回车
self.submitForm();
}
});
触发事件
或者打开浮层登录框框后需要默认选择第二个tab, 就相当于"按"一下那个tabform.submit();
tabs.eq(2).click();
form.trigger('submit');
tabs.eq(2).trigger('click');
同时trigger还会冒泡(关于事件冒泡,下面会有)
http://api.jquery.com/triggerHandler/事件冒泡
body
div#doc
div#header
div.search-bar
input.search-btn[type=button]
这个过程叫事件冒泡
div.click(function(e) {
if ($(e.target).is('a.delete')) {
// ..
}
});
以上代码可以这样写:
div.delegate('a.delete', 'click', function() {
});
// bigtable为大表格
$('table.bigtable td').dblclick(function() {
});
// 请使用事件代理绑定事件
$('table.bigtable').delegate('td', 'dblclick', function() {
});
自定义事件
// move.js
saveLayout: function() {
...
$('window').trigger('diychanged', { type: 'layout' });
}
// diy-skins
saveSkin: function() {
$('window').trigger('diychanged', { type: 'diyskins' });
}
// header.js
showTips: function() {
$('window').bind('diychanged', function(e, data) {
new Tips({
//...
message: '点击发布可应用您的修改到旺铺'
});
});
}
namespace事件
$('a.mylink').bind('click', function() {
});
$('a.mylink').bind('click.mylink', function() {
});
// 移除事件
$('a.mylink').unbind('click.mylink');
// 触发指定namespace事件
$('a.mylink').triggerHandler('click.mylink');
http://api.jquery.com/unbind/操作
而html, append, prepand,等节点操作需要浏览器重排节点并且重绘render: function(offers) {
var self = this,
html = [];
$.each(offers, function(index, offer) {
html.push(self.createItemHtml(offer));
});
div.html('<ul>' + html.join('') + '</ul>');
}
或者
render: function(offers) {
var self = this,
ul = $('<ul>');
$.each(offers, function(index, offer) {
ul.append(self.createItem(offer));
});
div.append(ul);
}
数据
render: function(offers) {
var self = this,
ul = $('<ul>');
$.each(offers, function(index, offer) {
var li = self.createItem(offer);
li.data('offer', offer); // here
...
});
...
},
handleP4p: function() {
var self = this;
div.delegate('a.title', 'click', function() {
var li = $(this).closest('li'),
offer = li.data('offer');
self.p4pclick(offer);
});
}
html5data标签和data方法
<div class="mod wp-supplier-info" data-mod-config='{"requestUrl":"http..."}'>...</div>
var mod = $('div.wp-supplier-info'),
config = mod.data('modConfig'); // 省略前缀data, 后面的转化成camel形式,
// 返回的是一个json object(如果确实是的话)
<div class="offers-container" data-request-url="http://....">
</div>
var container = $(...),
url = container.data('requestUrl'); // typeof url === 'string'
1. 如果是true/false/null/number就转化成相应的数据
2. 如果是json串,就转化成object
3. 当作string处理检测
可以使用 $.browser 来检测浏览器的信息
可以使用 $.support 进行浏览器特性检测
// 浏览器检测
if ($.util.ua.ie6) {
}
// 浏览器检测
if ($.browser.webkit) {
}
// 特性检测
if ($.support.opacity) { // 是否支持透明, 现在IE不支持
}
前端基础库 fdevlib
style目录结构简要说明
lib - 基础库
fdev-v4
core
fdev-min.js
widget
ui
dialog.js
util
cookie.js
json2.js
web
alitalk.js
sys - 公共业务组件
head
ibank
popsigin
app
platform
company
member
postoffer
work
winport
global
winport-merge.js
module
page
diy
diy-merge.js
应用stle目录结构说明请参考: http://fd.aliued.cn/doc/page/regulations/dir-structurefdev-v4现有组件
fdev-v4
core
fdev-min.js 我们使用的时候引入这个文件
config.js 动态加载的组件配置信息
gears.js 定义了一些基本方法,如String#trim,
还有一些方法移自fdev3, 还有就是动态加载$.add, $.use等方法
jquery1.6.2.js
web.js 可以使用FE.util.lastLoginId获得用户登录信息
所以用户登录等cookie信息的函数由这个文件定义
widget
ui
autocomplete 自动补全,像我们的搜索
colorbox
colorpicker 颜色选取
combobox 自定义样式下拉框(原生下拉框比较丑)
datapicker 日历选择
dialog 对话框
draggable 拖动
droppable 拖放
sortable 拖动排序(来自jquery ui)
portlets 拖动排序,目前用于旺铺diy后台
flash-chart flash图片组件(YID)
flash-storage flash本地存储
flash-uploader 上传文件
flash-websocket flash长链接
flash flash显示
menu
progressbar 进度条
scrollto 页面滚动
tab tab组件
timer
util
cookie cookie操作(写cookie时需要引入)
date
debug 调试
history 历史记录 work平台有使用
json2 json
storage 本地存储
web
alitalk 阿里旺旺
browser
datalazyload 延迟加载
pca
stylesheet 操作样式表
sweet js模板
valid 前端验证
websocket 长链接
评论
這是什麼作用
相关推荐
下面将根据"JS学习资料(自己整理)"的描述,深入探讨JavaScript的基础知识。 一、变量与数据类型 JavaScript 支持七种数据类型,包括两种原始类型:Undefined、Null、Boolean、Number、String、Symbol(ES6新增)...
此“javascript_js学习教程”是针对初学者精心设计的,来源于中兴通讯的内部培训资料,旨在帮助新入门的开发者快速掌握JavaScript的基础知识和实践技巧。 一、JavaScript基础 1. 变量与数据类型:JavaScript支持...
- **免费Codecademy课程**:提供互动式的JavaScript学习路径。 - **W3Schools**:提供了丰富的JavaScript教程和示例代码。 压缩包内的文件可能与这些知识点直接相关: 1. **FixedTips.htm**:可能是一个展示固定...
JavaScript学习指南(第3版)》系统地介绍了JavaScript的基本语法、基本对象、调试工具与排错技术、事件处理机制、浏览器对象模型/文档对象模型(BOM/DOM)等方面的知识,并通过一个复杂的示例深入探讨了Ajax应用。...
JavaScript是Web前端开发的核心语言之一,它为网页和应用程序提供了动态交互的能力。在JavaScript中,条件语句是...在头歌教学实践平台的Web前端开发课程中,这些基础知识的学习和实践将为你的编程技能打下坚实的基础。
JavaScript,简称JS,是Web开发...综上所述,这个"JS学习.zip"压缩包提供了全面的JavaScript学习资源,从基础到高级,覆盖了核心概念、DOM操作、面向对象和异步编程,是初学者或进阶者提升JavaScript技能的宝贵资料。
本学习笔记将深入探讨JavaScript的核心概念,包括变量、数据类型、操作符、控制流程、函数、对象、数组、原型链、闭包等,并结合实际示例,如my.js、order.js、login.js等文件,来讲解其在实际项目中的应用。...
在“学习资料 js学习资料”这个主题下,我们主要关注JavaScript的基础知识、实例应用以及与CSS的协同工作。 1. JavaScript基础: - 变量:JavaScript中的变量用于存储数据,可以使用var、let或const关键字声明。 ...
这个压缩包中的“史上最全的JavaScript学习资料”显然包含了一系列丰富的资源,旨在帮助学习者深入理解和掌握JavaScript。 JavaScript最初由Netscape公司的Brendan Eich设计,目的是为了解决网页动态交互的问题,使...
首先,"JS学习"意味着我们将探讨JavaScript的基础语法,包括变量、数据类型(如字符串、数字、布尔值、对象等)、控制结构(如条件语句、循环语句)、函数、作用域、闭包等。这些都是编程的基石,理解它们能够帮助...
JavaScript,简称JS,是一种广泛应用于Web开发的轻量级编程语言,主要负责客户端的动态交互。李炎恢老师的JS学习资料是一套全面且深入的学习资源,适合初学者和有一定基础的开发者进阶学习。 首先,JavaScript是Web...
html css js 学习html css js 学习html css js 学习html css js 学习 html css js 学习html css js 学习html css js 学习html css js 学习 html css js 学习html css js 学习html css js 学习html css js 学习 ...
html css js学习html css js学习html css js学习html css js学习 html css js学习html css js学习html css js学习html css js学习 html css js学习html css js学习html css js学习html css js学习 html css js学习...
html css js 学习笔记html css js 学习笔记html css js 学习笔记 html css js 学习笔记html css js 学习笔记html css js 学习笔记 html css js 学习笔记html css js 学习笔记html css js 学习笔记 html css js 学习...
本压缩包“JavaScript学习笔记_js常用函数封装_js包.zip”包含了对JavaScript基础及进阶技巧的学习资料,特别关注了函数封装和模块化开发实践。 首先,`tool.js`可能是一个实用工具函数集合,封装了一些常见的...
JavaScript(简称JS)是一种广泛应用于Web开发的轻量级、解释型编程语言,以其灵活性和交互性在网页设计中占据核心地位。本课程通过两份PPT深入浅出地介绍了JavaScript的基本概况和主要分类,旨在帮助学习者从宏观...
Javascript学习是Android客户端目前最全面的免费离线Javascript学习书籍,从Html入门到Html样式设计,再到Javascript,提高网页设计能力。主要内容包括: 1、Html基本标签 2、Html表单知识 3、Web2.0(Div+Css样式)...
HTML-CSS-JS 学习HTML-CSS-JS 学习HTML-CSS-JS 学习HTML-CSS-JS 学习 HTML-CSS-JS 学习HTML-CSS-JS 学习HTML-CSS-JS 学习HTML-CSS-JS 学习 HTML-CSS-JS 学习HTML-CSS-JS 学习HTML-CSS-JS 学习HTML-CSS-JS 学习 ...