软件艺术思考者  
混沌,彷徨,立志,蓄势...
公告
日历
<2024年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

导航

随笔分类(86)

随笔档案(85)

搜索

  •  

最新评论

阅读排行榜

评论排行榜

 
翻译说明:本文是我从Prado框架的《快速入门指南》翻译中摘录出来的,感觉对JavaScript的学习很有帮助,特贴出备忘。

Javascript简介

本指引基于Sergio Pereira的 Quick guide to somewhat advanced JavaScript tour of some OO features

嘿,我不知道你能那样做

如果你是一个Web开发者而且与我来自同一个地方,你也许在你的Web页面中使用过相当多的Javascript,大部分用来作用户界面(UI)的粘合。

直到现在,我才知道Javascript具有比我过去使用的更多的面向对象能力,只是我没有如我所需的去使用它。当浏览器开始支持更标准的Javascript和DOM的功能集时,要为客户端上的运行而编写更复杂和多功能的代码就变得可行了。它助长了AJAX现象的产生。

当我们都开始学习它适合编写什么酷的AJAX应用时,我们开始关注到我们过去知道的Javascript不过只是冰山一角而已。我们现在知道Javascript不仅仅被用于象输入校验等简单的用户界面杂务和其他琐碎任务。现在的客户端代码更高级和分层,更象一个真正的桌面应用或一个客户端-服务器的富客户端。我们在其中看到了过去仅在服务器端的代码中见到的类库、对象模型、继承关系、模式和许多其他的东西。

突然在我们能讲到的许多方面被放到了比以前更高的位置。要为新的Web编写应用,我们必需提高我们的Javascript水平来跟上它而且要更加熟练。假如你尝试运用许多现有的javascript库,如:Prototype.jsScriptaculousmoo.fxBehaviourYUI等,你最终会发现自己要阅读JS代码。或许因为你想要学习它们如何实现,或因为你的好奇,或通常因为那是知道如何使用它的唯一办法,大多数这些库象是不太注重文档。无论个案会是什么,假如你之前不了解那样的东西,你将要面对一些引起恐慌的外部技术。

本文的目的正好是解说许多我们还不熟悉的构造类型。

JSON (JavaScript Object Notation-Javascript对象表示法)

Javascript对象表示法(JSON),是围绕AJAX主题突然出现的一个新的时髦词。JSON,简单的说就是一种在Javascript中定义对象的方法。让我们马上来看看一个实例并体会它如何简单。

var myPet = { color: 'black', leg_count: 4, communicate: function(repeatCount){for(i=0;i<repeatCount;i++)alert('Woof!');}};

就让我们加入些许格式让它看起来象我们平常所认识的那样:

var myPet =
{
    color: 'black',
    legCount: 4,
    communicate: function(repeatCount){for(i=0;i<repeatCount;i++)alert('Woof!');
    }};

在这我们创建了一个带两个属性(colorlegCount)和一个方法(communicate)的对象引用。不难发现,该对象的属性和方法用一个逗号区隔的列表来定义。每个成员通过名称来引入,接着是冒号和定义。对于属性来说很容易,仅仅是属性值。方法通过指派一个匿名函数来创建,我们下面会更好地说明。在该对象被创建并指派给变量myPet之后,我们可以如下使用它:

alert('my pet is ' + myPet.color);
alert('my pet has ' + myPet.legCount + ' legs');
//if you are a dog, bark three times:
myPet.communicate(3);

You'll see JSON used pretty much everywhere in JS these days, as arguments to functions, as return values, as server responses (in strings,) etc.

你想说什么?函数也是一个对象?

对于开发者来说这可能与众不同,但在JS中一个函数也是一个对象。你可以象参数一样把一个函数传送给另一个函数,就象你可以传送一个字符串一样。这些被广泛应用而且非常便利。

看看这个实例。我们将把函数传送到另一个使用它们的函数去。

var myDog =
{
    bark: function(){alert('Woof!');
    }};
 
var myCat =
{
    meow: function(){alert('I am a lazy cat. I will not meow for you.');
    }};
 
function annoyThePet(petFunction){//let's see what the pet can do
    petFunction();
}
 
//annoy the dog:
annoyThePet(myDog.bark);
//annoy the cat:
annoyThePet(myCat.meow);

注意,我们把没有添加"()"的myDog.bark和myCat.meow传送给它们。假如我们那样做了,我们不是传送函数,而是调用那些方法并传送它们的返回值,这里的两个个案中都未定义

要是你想另我的懒猫起来嗥叫,你可以简单地这样做:

myCat.meow = myDog.bark;
myCat.meow(); //alerts 'Woof!' 

数组、项目和对象成员

在JS中下列两行做了同样的事。

var a = new Array();
var b = [];

正如我确定你已经知道的那样,你可以通过使用方括号在一个数组中访问个别项目:

var a = ['first', 'second', 'third'];
var v1 = a[0];
var v2 = a[1];
var v3 = a[2];

但你还不限于数字索引。你可以通过使用它的名字以字符串来访问一个JS对象的任何成员。下面的例子创建了一个空对象,并通过名字加入了一些成员。

var obj = {}; //new, empty object
obj['member_1'] = 'this is the member value';
obj['flag_2'] = false;
obj['some_function'] = function(){/* do something */};

上述代码的作用与下面的相同:

var obj =
{
    member_1:'this is the member value',
    flag_2: false,
    some_function: function(){/* do something */}};

在许多情形下,在JS中对象的概念和关联的数组(杂凑)没有区别。下面两行代码都做了同样的事情。

obj.some_function();
obj['some_function']();

关于对象已经够了,我现在能有一个类了吗?

面向对象编程语言的巨大力量来源于类的使用。我不认为仅应用我之前使用其他语言的经验就能推测出在JS中如何定义类。这由你自己来判断。

//defining a new class called Petvar Pet = function(petName, age){this.name = petName;
    this.age = age;
};
 
//let's create an object of the Pet classvar famousDog = new Pet('Santa\'s Little Helper', 15);
alert('This pet is called ' + famousDog.name);

让我们看看如何加入一个方法到我们的Pet类。我们将使用所有类都具有的prototype属性。prototype属性是一个包含任何对象的类会具有的所有成员的对象。甚至默认的JS类,如StringNumberDate拥有一个的prototype对象,它能让我们可以添加方法和属性并使那个类的任何对象自动获取这个新成员。

Pet.prototype.communicate = function(){alert('I do not know what I should say, but my name is ' + this.name);
};

那就是一个类似于prototype.js的库会派上用场的时候。如果我们使用prototype.js,我们能使我们的代码看起来更清晰(至少在我看来是这样)。

var Pet = Class.create();
Pet.prototype =
{//our 'constructor'
    initialize: function(petName, age){this.name = petName;
        this.age = age;
    },
 
    communicate: function(){alert('I do not know what I should say, but my name is ' + this.name);
    }};

函数作为参数,一个有趣的模式

假如你从来没有接触过支持闭合的语言,你也许会发现下面的惯用法太令人震惊了。

var myArray = ['first', 'second', 'third'];
myArray.each(function(item, index){alert('The item in the position #' + index + ' is:' + item);
});

哇!在你断定我已经离题太远并且想转去比这篇更好点的文章之前,让我们在这解释一下要继续干些什么。

首先,在上述实例中我们使用了prototype.js库,它添加了each函数到Array类。该each函数接到一个函数对象的参数。这个函数对于数组中的每个项目都将被依次调用一次,对于当前项目调用时传送两个参数,item和index。让我们称这个函数为iterator函数。我们也能象这样编写代码:

function myIterator(item, index){alert('The item in the position #' + index + ' is:' + item);
}
 
var myArray = ['first', 'second', 'third'];
myArray.each( myIterator );

我们不会象那些学校里的那些天真孩子那样做的,对吧?虽然更严格地说,后面的形式更易于理解但导致我们要进入代码中四处找寻myIterator函数。最好在它调用的同一个地方那里有迭代函数的逻辑。在本案例中,我们也不会在其他任何地方需要迭代函数,所以我们无损地把它转化成一个匿名函数。

这是this,但有时this也是那个

当使用JS开始编写我们的代码时,我们最普遍的一个麻烦就是this关键字的使用。它是一个真正的牵绊。

就象我们之前提及的那样,在JS中一个函数也是一个对象,而且有时候我们不注意我们正在传出一个函数。

拿这小段代码举个例:

function buttonClicked(){alert('button ' + this.id + ' was clicked');
}
 
var myButton = document.getElementById('someButtonID');
var myButton2 = document.getElementById('someOtherButtonID');
myButton.onclick = buttonClicked;
myButton2.onclick = buttonClicked;

由于buttonClicked函数在任何对象之外被定义,我们也许以为this关键字会包含一个windowdocument对象(假设这些代码位于一个在浏览器中被浏览的HTML页面中间)的引用。

但是当我们运行这段代码时,我们看到它如愿工作并显示被点击按钮的id。究竟其中发生了什么另我们使每个按钮的onclick方法包含buttonClicked对象引用,而无论之前那里有什么。现在无论按钮什么时候被点击,浏览器都会运行一些类似下行的东西:

myButton.onclick();

那毕竟不是这么混乱,是吧?只要你了解有别的对象要进行处理并想在这些对象的事件上,如点击按钮,进行什么行动后发生了什么就行了。

var myHelper =
{
    formFields: [],
    emptyAllFields: function(){for(i=0; i < this.formFields.length; i++){var elementID = this.formFields[i];
            var field = document.getElementById(elementID);
            field.value = '';
        }}};
 
//tell which form fields we want to work with
myHelper.formFields.push('txtName');
myHelper.formFields.push('txtEmail');
myHelper.formFields.push('txtAddress');
 
//clearing the text boxes:
myHelper.emptyAllFields();
 
var clearButton = document.getElementById('btnClear');
clearButton.onclick = myHelper.emptyAllFields;

因此你想:好了,现在我可以在我的页面上点击Clear按钮,那三个文本框就将被清空。然后你尝试点击该按钮后仅得到一个运行时错误。该错误将涉及(猜猜是什么?)this关键字。该问题是this.formFields没被定义即便this包含了一个到按钮的引用,那正是现在所发生的。一个快速的解决方案是重写我们最后一行的代码。

clearButton.onclick = function(){
    myHelper.emptyAllFields();
};

我们创建一个全新的函数,那种方法在协助对象的场景中调用了我们的协助方法。

posted on 2006-10-23 14:06 智者无疆 阅读(415) 评论(9)  编辑  收藏
评论:
  • # re: 弹指一挥间,JavaScript乌鸦变凤凰  白白 Posted @ 2006-10-23 14:29
    呵呵,精华,我也来学学!  回复  更多评论   

  • # re: 弹指一挥间,JavaScript乌鸦变凤凰  self Posted @ 2006-10-27 17:25
    //--------------------JAVAscript树形菜单-----------------------

    <%@ page contentType="text/html; charset=GBK" %>
    <html>
    <head>
    <title>
    jsp4
    </title>
    <style>
    <!--
    #foldheader{cursor:hand ; font-weight:bold ;
    list-style-image:url(fold.gif)}
    #foldinglist{list-style-image:url(/blog/list.gif)}
    //-->
    </style>
    <script language="JavaScript1.2">
    <!--
    var head="display:''"
    img1=new Image()
    img1.src="fold.gif"
    img2=new Image()
    img2.src="/blog/open.gif"

    function change(){
    if(!document.all)
    return
    if (event.srcElement.id=="foldheader") {//如果id是文件夹节点,
    var srcIndex = event.srcElement.sourceIndex//取得事件节点
    var nested = document.all[srcIndex+1] //得到所有嵌套节点
    if (nested.style.display=="none") { //如果嵌套节点为隐藏
    nested.style.display='' //则节点的播放样式为显示
    event.srcElement.style.listStyleImage="url(/blog/open.gif)"//源事件的样式图为开文件夹
    }
    else {//如果id是文件夹下的子节点
    nested.style.display="none"//则嵌套子节点的播放样式为隐藏
    event.srcElement.style.listStyleImage="url(fold.gif)"//事件源样式图为关文件夹
    }
    }
    }

    document.onclick=change

    //-->
    </script>



    </head>
    <body bgcolor="#ffffff">
    <ul>
    <li id="foldheader">News</li>
    <ul id="foldinglist" style="display:none" style=&{head};>
    <li><a href="http://www.cnn.com">CNN</a></li>
    <li><a href="http://www.abcnews.com">ABC News</a></li>
    <li><a href="http://www.vancouversun.com">Vancouver Sun</a></li>
    </ul>
    <li id="foldheader">Games</li>
    <ul id="foldinglist" style="display:none" style=&{head};>
    <li><a href="http://www.gamespot.com">GameSpot</a></li>
    <li><a href="http://www.happypuppy.com">Happy Puppy</a></li>
    <li><a href="http://www.gamecenter.com">Game Center</a></li>
    </ul>
    </ul>
    </body>
    </html>
    <script>
    function test()
    {
    for(i=0;i<document.all[event.srcElement.id].length;i++)
    if(document.all[event.srcElement.id][i]==event.srcElement)
    alert("是第"+(i+1)+"个"+event.srcElement.id);
    }
    </script>
    <input type=checkbox name=mycheck id=mycheck value=12 onclick=test()>
    <input type=checkbox name=mycheck id=mycheck value=22 onclick=test()>
    <input type=checkbox name=mycheck id=mycheck value=22 onclick=test()>
    <input type=checkbox name=mycheck id=mycheck value=42 onclick=test()>  回复  更多评论   

  • # re: 弹指一挥间,JavaScript乌鸦变凤凰  self Posted @ 2006-11-02 11:37
    //------------------js普通菜单--------------------------
    <html>
    <head>
    <style>
    ul#menu, ul#menu ul{
    list-style:none;
    margin:0;
    border-bottom:1px solid #DDD;
    border-right:1px solid #DDD;
    border-left:1px solid #DDD;
    width:100px;
    padding:0;
    font-size:14px;
    }
    ul#menu li{
    border-top:1px solid #DDD;
    position:relative;
    padding:4px;

    }
    ul#menu li ul{
    position:absolute;
    left:150px;
    _left:94px;
    top:0;
    display:none;
    }
    ul#menu li.over{
    background:#EEE;
    }
    ul#menu li.out{
    background:#fff;
    }
    ul#menu a{
    display:block;
    text-decoration:none;
    color:#000;
    _height:0;
    }
    </style>
    <script type="text/javascript">
    function initMenu(event,ul){
    if(!ul) ul = document.getElementById("menu");//得到一个元素对象ul,对应顶级元素ul id=menu;
    li = ul.getElementsByTagName("li"); //得到所有的元素对象数组li,每个元素的id=li;
    for(i=0;i<li.length;i++)//循环执行所有的元素。
    {
    li[i].onmouseover = function(){//当第i个元素有动作onmouseover时,执行函数(它li的样式名为over)
    try{
    this.className='over';
    this.getElementsByTagName("ul")[0].style.display="block";//用这个元素得到其中第一个ul元素,使其display=block显示
    }catch(e){};
    }
    li[i].onmouseout = function(){//当第i个元素有动作onmouseout时,执行函数(使它li的样式名为out)
    try{
    this.className='out';
    this.getElementsByTagName("ul")[0].style.display="none";//用这个元素得到其中第一个ul元素,使其display=none,隐藏
    }catch(e){};
    }
    }
    }
    window.onload = initMenu;
    </script>
    </head>
    <body>
    <ul id="menu">
    <li>
    文件
    <ul>
    <li><a href="#">新建</a></li>
    <li><a href="#">打开</a></li>
    <li>
    另存类型>
    <ul>
    <li>文本文件>
    <ul>
    <li><a href="#">txt文件</a></li>
    <li><a href="#">doc文件</a></li>
    </ul>
    </li>
    <li>图片文件></li>
    <ul>
    <li><a href="#">bmp文件</a></li>
    <li><a href="#">jpg文件</a></li>
    <li><a href="#">gif文件</a></li>
    </ul>

    </ul>
    <li>
    </ul>

    </li>
    <li>
    编辑
    <ul>
    <li><a href="#">全选</a></li>
    <li><a href="#">粘贴</a></li>
    <li><a href="#">复制</a></li>
    </ul>
    </li>


    <li>
    搜索
    <ul>
    <li><a href="#">查找</a></li>
    <li><a href="#">替换</a></li>
    <li><a href="#">转换到行数</a></li>
    </ul>
    </li>
    </ul>
    </body>
    </html>
      回复  更多评论   

  • # re: 弹指一挥间,JavaScript乌鸦变凤凰  self Posted @ 2006-11-02 13:33
    //------------------js二级联动菜单------------------------------
    <TITLE>二级联动</TITLE>
    <STYLE>

    select { font-size: 11px; font-family: Verdana;vertical-align: middle;margin: 3px;background:#ececec;color:#666666;}
    </STYLE>
    <body>
    <div id="tar"></div>
    <SCRIPT LANGUAGE="JavaScript" DEFER>
    var fMenu = ["上海","北京","广东","南京"]
    var fValue = ["shanghai","beijing","guadong","nanjing"]
    var sMenu = [["杨浦区","徐汇区","黄浦区","卢湾区"],["丰台区","海淀区","朝阳区","西城区","东城区"],["广州","深圳"],["雨花台"]]
    var sValue = [["yp","xh","hp","lw"],["ft","hd","cy","xc","dc"],["gz","sz"],["yht"]]

    var oWhere = document.all.tar;//得到div对象
    var ofMenu = document.createElement("<SELECT name='main'>");//创建一个名为main的select对象,对应城市,
    var osMenu = document.createElement("<SELECT name='sub'>");//创建一个名为sub的select对象,对应城区。
    with(oWhere)appendChild(ofMenu),appendChild(osMenu);//用div对像添加城市对象,再添加城区对象。

    createMainOptions();
    createSubOptions(0);

    ofMenu.onchange = function() {
    createSubOptions(this.selectedIndex);//当城市选择对象发生onchange事件时,根据选择的id号创建城区对象
    }
    //创建城市选项数组
    function createMainOptions() {
    for(var i=0;i<fMenu.length;i++)ofMenu.options[i] = new Option(fMenu[i],fValue[i]);
    //根据城市数组长度,依次创建选择对象Option,并添加进城市的option数组
    }
    //创建城区选项数组
    function createSubOptions(j){//根据城市数组下标,创建城区对象,并添加进城区option对象数组
    with(osMenu) {
    length=0;
    for(var i=0;i<sMenu[j].length;i++)osMenu.options[i] = new Option(sMenu[j][i],sValue[j][i]);
    }
    }
    </SCRIPT>
    <div style="background:#E7E3DE;text-align:right;font-family:'Arial';font-size:10px;margin-top:10px;"><a href="mailto:cloudchen@yeah.net">mailto:cloudchen</a></div><div style="background:#666666;color:white;font-family:'Arial';font-size:10px;">2003.8.19</div>

    </body>  回复  更多评论   

  • # re: 弹指一挥间,JavaScript乌鸦变凤凰  selft Posted @ 2006-11-08 11:40
    //------------js的拖动类及其广泛应用=----------------------------
    文件1.拖动类文件:文件名可为:dd.js
    function ObjectDragDrop(obj){ //定义拖动类
    var me = this; //把一个应用此函数的网页对象传进来赋值给me.
    this.foo = (typeof obj=="string")?document.getElementById(obj):obj; //给foo赋值,值为应用此函数的网页中的对象

    this.foo.onmousedown = function(e){ //当鼠标落下时
    var foo = me.foo; //把网页对象赋值给foo.
    e = e||event; //获得事件对象;
    if( e.layerX ){ foo.oOffset = {x:e.layerX, y:e.layerY }; }//若事件对象的坐标x不为null,
    else { foo.oOffset = {x:e.offsetX, y:e.offsetY }; }
    document.onmousemove = me.drag; //拖动事件发生时,事件对象坐标重新赋值
    document.onmouseup = me.drop; //事件坐标重新赋值null
    document.onselectstart = function(){ return false; };
    }

    this.drag = function(e){ //拖动函数,改变事件对象的位置
    var foo = me.foo;
    e=e||event;
    foo.style.top = e.clientY - foo.oOffset.y + "px";
    foo.style.left = e.clientX - foo.oOffset.x + "px";
    }

    this.drop = function(e){ //放开鼠标时,各个文档对象事件都赋值为null
    e=e||event;
    document.onmousemove = document.onmouseup = document.onselectstart = null;
    }
    }
    文件2.应用例子:test.html
    <html>
    <head>
    <title>Drag 'n' Drop Demo</title>
    <style>
    #foo {
    position:absolute;
    top:100px;
    left:100px;
    width:100px;
    height:100px;
    background-color:#f0f0f0;
    border:solid 1px #121212;
    }
    #foo1 {
    position:absolute;
    top:150px;
    left:130px;
    width:100px;
    height:100px;
    background-color:#fff0f0;
    border:solid 1px #121212;
    }
    </style>



    </head>
    <body>
    <script src="dd.js"></script>
    <script>
    window.onload = function(){
    var test = new ObjectDragDrop("foo");
    var test1 = new ObjectDragDrop("foo1");
    var test2 = new ObjectDragDrop("p1");
    var test3 = new ObjectDragDrop("img1");
    }
    </script>
    <h1>最简单的拖动演示</h1>

    <input name=name type=text id="foo">
    <div id="foo1">test<br>test2</div>
    <img style="position:absolute;left:400px;top:750px;"
    src="C:\Documents and Settings\dragon\My Documents\My Pictures\images\01.jpg" id="img1">

    </body>
    </html>
    注意事项:
    1.引入js文件时:<script src="dd.js"></script>不能用:<script src="dd.js"/>的形式
    2.style="position:absolute;left:400px;top:750px;"必须为每个元素对象定义类似这样的位置  回复  更多评论   

  • # re: 弹指一挥间,JavaScript乌鸦变凤凰  selft Posted @ 2006-11-08 11:54
    3.new 拖动对象时的次序最好与页面元素id号的次序一致。  回复  更多评论   

  • # re: 弹指一挥间,JavaScript乌鸦变凤凰  selft Posted @ 2006-11-08 12:10
    http://www.aspxboy.com/myjs/
    js特效  回复  更多评论   

  • # re: 弹指一挥间,JavaScript乌鸦变凤凰  self Posted @ 2007-03-02 12:54
    http://www.cublog.cn/u/23633/showart_211908.html  回复  更多评论   

  • # js菜单大集合  self Posted @ 2007-03-02 12:55
    http://www.cublog.cn/u/23633/showart_211908.html   回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
 
Copyright © 智者无疆 Powered by: 博客园 模板提供:沪江博客


   观音菩萨赞