javascript学习笔记(2)

文章介绍:javascript中的面向对象编程,遍历DOM。

一,面向对象编程

1,面向对象编程简介,

    面向对象编程相对面向过程编程而言,面向过程编程方式的特点是把数据保存到变量里,然后由一系列指令操作变量。每个指令(或一系列指令,比如函数)都能创建,删除或修改数据,显得数据与代码在某种程度上是“分离”的。

    在面向对象编程(oop)方式中,程序指令与其操作的数据密切关联。换句话说oop把程序的数据包含在"对象"的独立体里,每个对象都有自己的属性(数据)和方法(指令)。

    与面向过程编程方式相比,面向对象编程有不少优点,比如:代码复用,封装,继承。

2,创建对象

(1)创建直接实例,

javascript中有一个内置对象object,利用它可以创建一个空白的对象:

myNewObject = new Object();

这样就得到了一个崭新的对象myNewObject,此时它还没有任何属性和方法,因此没有任何实际功能。可以像下面这样添加属性和方法:

//添加属性
myNewObject.info = 'I am a shiny new object';

//添加方法
function myFunc(){
	alert(this.info);
	};
myNewObject.showInfo = myFunc;

#在把函数myFunc关联到.showInfo属性时只使用了函数名称,而没有包含括号。这是因为我们是要把函数myFunc()的定义赋予mynewObject.showInfo方法。如果加了括号,相当于执行函数然后将函数的返回值赋予变量。

(2)使用关键字this

    当我们在函数中使用this函数的时候,this指向函数的"父对象"。

    在函数最初声明时,它的父对象是全局对象window,window对象并没有名为info的属性,如果直接调用myFunc()函数,会发送错误。

(3)匿名函数

    前面的代码是这样的:

function myFunc(){

    alert(this.info);

};

myNewObject.showInfo = myFunc;

    同样的功能可以这样实现:

myNewObject.showInfo = function(){

    alert(this.info);

};

(4)使用构造函数

    如果只需要某个对象的一个实例,使用直接创建对象实例的方法还算不错。但如果要创建同意个对象的多个实例,使用这种方式就要反复重复整个过程:创建对象,添加属性,定义方法等。

    如果要创建可能具有多个实例的对象,更好的方式是使用"对象构造函数"。它会创建某种模板,方便实现多次实例化。

    查看下面打代码,其中并没有使用new Object(),而是先声明一个函数没有ObjectType(),然后在它的定义里使用关键字this添加属性和方法。

function myObjectType(){
	this.info = 'I am a shiny new object';
	this.showInfo = function(){
		alert(this.info);
		}
	this.setInfo = function(newInfo){
		this.info = newInfo;
		}

    这段代码添加了一个属性info,两个方法showInfo和setInfo,前一个方法显示info属性当前保存的值;后移个方法接收一个参数newInfo,用它的值覆盖info的值。

(5)对象实例化

    在定义了构造函数后,可以方便地创建对象的实例:

    var myNewObject = new myObjectType();

(6)构造参数函数

    在把对象实例化时,还可以通过给构造函数传递一个或多个参数来定制对象。在下面的代码里,构造函数的定义包含了一个参数personName,它的值会赋予构造函数的name属性。以后在实例化两个对象时,我们给每个实例都传递了一个姓名作为参数。

var myNewObject = new myObjectType();

function Person(personName){
	this.name = personName;
	this.info = 'I am called '+ this.name;
	this.showInfo = function(){
		alert(this.info);
		}
	}
var person1 = new Person('Adam');
var person2 = new Person('Eve');

3,使用prototype扩展和继承对象

(1)扩展对象

    例子:给它添加一个新方法sayHello。

Person.prototype.sayHello = function(){

    alert(this.name + " says hello");

}

(2)继承

    继承是指从一种对象类型创建另一种对象类型,新对象类型继承老对象类型的属性和方法,还可以可选地添加自己的属性和方法。通过这种方式,我们可以先设计出“通用”的对象类型,然后继承来不断细化它们来得到更特定的类型,这样可以节省很多工作。   

    javascript模拟实现继承的方式也是使用关键字prototype。

    例子:从Pet对象中继承Dog

//先定义一个Pet对象
function Pet(){
	this.animal = "";
	this.name = "";
	this.setAnimal = function(newAnimal){
		this.animal = newAnimal;
		}
	this.setName = function(newName){
		this.name = newName;
		}

//定义一个Dog对象
function Dog(){
	this.breed = "";
	this.setBreed = function(newBreed){
		this.breed = newBreed;
		}
	}

从Pet继承属性和方法,

Dog.prototype = new Pet();

这样就不仅可以访问Dog里的属性和方法,还可以访问Pet里的属性和方法:

var myDog = new Dog();
myDog.setName("Alan");
myDog.setBreed("Greyhound");
alert(myDog.name + " is a "+myDog.breed);

#使用javascript还可以扩展javascript内置的对象。

4,封装

    封装是面向对象编程的一种能力,表示把数据和指令封装到对象内部。其具体实现方法在不同的语言里有所区别。对于javascript来说,在构造函数内部声明的变量只能在对象内部使用,对于外部是不可见的。构造函数内部声明的函数也是这样的。

    如果想从外部访问这些变量和函数,需要在赋值时使用关键字this,这时它们就成为了对象的属性和方法。

二,遍历DOM

1,DOM节点

(1)节点类型

        nodetype值和节点类型:1,元素 2,属性 3,文本 4,CDATA区域 5,实体引用 6,实体  7,执行指令  8,HTML注释   9,文档  10,文档类型(DTD) 11,文档片段  12,标签。

(2)childNodes属性

    每个节点都有一个childNodes属性。这个类似数组的属性包含了当前节点的全部子节点的集合,我们可以访问这些子节点的信息。

    childNodes集合称为"节点列表"(NodeList),其中的项目以数值进行索引。集合(在大多数情况下)的表现类似于数组,我们可以像访问数组元素一样访问集合里的项目,还可以像对待数组一样遍历集合的内容,但有些数组方法是不能用的,比如push()和pop()。

    节点列表是一个动态集合,这表示集合的任何改变都会立即反映到列表。

    使用childNodes属性

    利用childNodes属性返回的集合,我们可以查看程序清单里

    元素的内容。编写一个简单的程序,读取
      元素的子节点,并且放回列表里的总数。

          首先,利用

        的id获取它:

            var olElement = document.getElementById("toDoList");

            现在,

          元素的子节点就包含在这个对象里了:

              olElement.childNodes

              由于我们只想操作子节点里的

        1. 元素,所以在遍历childNodes集合时,只统计nodeType == 1(也就是HTML元素)的节点,忽略其他的元素(比如注释和空白)。处理集合的方式与数组很相似,比如这里使用length属性(就像对数组使用该属性一样)

              var count = 0;

              for(var i =0;i

                  if(olElement.childNodes[i].nodeType == 1) count++;

          }

          (3)firstChild 和 lastChild

              在childNodes数组里可以使用firstChild和lastChild选择数组中的第一个和最后一个元素

          (4)parentNode属性

              parentNode属性保存节点的父节点。

          (5)nextSibling 和 previousSibling

              兄弟节点是指同样具有相同父节点的那些节点。perviousSibling和nextSibling属性分别返回节点的前一个和后一个兄弟节点,如果不存在相应的节点,就返回NULL。

          (6)节点值

              DOM节点的nodeValue属性返回保存在节点里的值,我们一般用它返回文本节点里的内容。

              从前面统计列表项目数量的范例出发,获取页面的

          元素里包含的文本。为此,我们需要访问相应的

          节点,找到它包含的文本节点,再利用nodeValue属性返回其中的信息:

          var text = '';
          var pElement = document.getElementById("toDoNotes");
          for(var i=0;i
          (7)节点名称

              nodeName属性以字符串形式返回节点的名称。这个属性是只读的,不能修改它的值。

              当nodeName返回元素名称时,并不包括HTML源代码里使用的尖括号<>。

          var pElement = document.getElementById("toDoNotes");

          alert(pElement.nodeName);

          nodeName属性的返回值

          • nodeType 1 节点类型:元素 nodeName值:元素(标签)名称
          • nodeType 2 节点类型:属性 nodeName值:属性名称
          • nodeType 3 节点类型:文本 nodeName值:字符串“#text”

          2,利用getElementsByTagName()选择元素

              前面介绍过利用document对象的getElementById()方法访问页面里的元素。document的另一个方法getElementsByTagName可以获取特定的全部标签,将其保存在一个数组里。

              和getElementById()一样,getElementsByTagName()方法也接收一个参数,然而,它需要的参数并不是元素的ID,而是标签的名称。

          3,读取元素的属性

              HTML元素通常会具有一些属性,保存着相关的信息:

               

          Here is some text.

              属性通常放置在标签的前半部分,其形式是"属性=值"。属性本身是所在元素的子节点

              在获得了目标元素之后,就可以利用getAttribute()方法读取它的属性值:

          var myNode = doccument.getElementById("id1");
          alert(myNode.getAttribute("title"));

              上面的两行代码会在alert对话框里显示"report"。如果尝试访问不存在的属性。getAttribute()会返回null。利用这个特性可以检测一个节点元素是否定义了特定的属性

          4,DOM操作

          (1)创建节点

              给DOM数添加新节点需要两个步骤:

          1,首先是创建一个新节点。节点创建之后处于某种"不确定状态",它的确存在,但不属于DOM树的任何位置,也就不会出现在浏览器窗口里。

          2,接下来把接待你添加到DOM树的指定位置,它就成为页面的组成部分了。

              接下来介绍document对象用于创建节点的一些方法。

          createElement()

              createElement()方法可以新建任何类型的标准HTML元素,比如段落,区间,表格,列表等。

              假设我们要新建一个

          元素,为此,只需要把相关的节点名称(也就是"div")传递给createElement方法:

          var newDiv = document.createElement("div");

          新的

          元素就存在了,但目前还没有内容,没有属性,在DOM树立也没有位置。稍后就会介绍如何解决这些问题。

          createTextNode()

              页面里有很多HTML元素需要文本形式的内容,这就需要使用createTextNode()方法。它的工作方式类似于createElement(),但是它的参数不是nodeName,而是元素需要的文本内容:

          var newTextNode = document.createTextNode("here is some text content.");

          cloneNode()

              重复劳动是最没有意义的,如果文档中已有的节点与需要新建的节点很像,就可以使用cloneNode()来新建节点。

              和createElement()和createTextNode()方法不同,cloneNode()接受一个单个的参数,这是一个True或false的布尔值。

              当参数为true时,表示不仅要复制节点,还要复制它的全部子节点:

          var myDiv = document.getElementById("id1");
          var newDiv = myDiv.cloneNode(true);

              上述代码让javascript复制了元素及其子节点,这样myDiv里的文本(保存在元素的文本子节点里)就会完整的复制到新的

          元素。

              如果是下面这样的代码:

              var newDiv = myDiv.cloneNode(false);

              新建的

          元素与原始元素相同,但是没有子节点。它会具有一样的属性(当然,前提是原始节点的类型是元素节点)。

          #注意在复制一个节点的时候,记得要修改新的元素的id,因为一个文档中id值应该是唯一的。

          (2)操作子节点

              前面新建的节点不在DOM树的任何位置,因此并没有上面实际的意义。document对象具有一些特定的方法,专门用于在DOM树里放置节点,接下来介绍他们。

              appendChild()

              把新节点添加到DOM数的最简单方法也许就是把它作为文档中已有节点的一个子节点。这只需要获取父节点,然后调用appendChild()方法:

          var newText = document.createTextCode("here is some text content:");
          var myDiv = document.getElementById("id1");
          myDiv.appendChild(newText);

          这段代码新建一个文本节点,并且把它添加为现有

          (id为id1)的子节点。

              appendChild()方法总是在已有的最后一个子节点之后添加子节点,所以添加的节点会成为父节点的lastChild。

              appendChild()方法不仅可以用于文本节点,而且可以用于各种类型的节点。

              insertBefore()

              appendChild()总是把新的子节点添加到子节点的末尾,而insertBefore()方法可以指定一个子节点,然后把新节点插入到它前面。

              这个方法有两个参数:要插入的新节点,指示插入位置的节点(插入到这个节点的前面)。

          this paragraph contains some text

          hers is some more text

          var newPare = document.createElement("p") var myDiv = document.getElementById("id1"); var para2 = document.getElementById("para2"); myDiv.insertBefore(newPara,para2);

              replaceChild()

              replaceChild()方法可以把父元素现有的一个子节点替换为另一个子节点。它有两个参数,一个是新的子节点,另一个是现有的子节点。           replaceChild(newElement,oldElement)    

              一个使用replaceChild()的例子

          
          
          
          	Replace Page Element
          	
          
          
          	

          Welcome to my web page.

          Please take a look around.

              removeChild()

              removeChild()方法专门用于从DOM数里删除子节点。

          var myDiv = document.getElementById("id1");
          var myPara = document.getElementById("para2");
          myDiv.removeChild(myPara);

          removeChild()方法的返回值是对删除节点的引用,在需要时,可以利用它对已经删除的节点实现进一步操作:

          var removedItem = myDiv.removeChild("myPara");
          alert('Item whit id' + removedItem.getAttribute("id") + ' has been removed.');
          (3)编辑元素属性

              前一章介绍过使用getAttribute()方法读取元素属性。还有一个相应的setAttribute()方法可以为元素节点创建属性并赋值。它有两个参数,一个是要添加的属性,另一个是属性值。此外,设置现有属性的值就会改变该属性的值。也可以使用这一方法来有效编辑已有的属性的值:

          var myPara = document.getElementById("para1");
          myPare.setAttribute("title","hello");
          (4)动态加载javascript文件

              在有些情况下,我们需要给已经在浏览器中加载的页面随时加载javascript代码,为此可以利用createElement()动态新建

          h1

          h2

          p1

          h3

          p2

          h4

          p3

          h5

          p4

          h6

          p5

          menu.js的javascript代码

          function makeMenu(){
          	//获取所有h2元素
          	var h2s = document.getElementsByTagName("h2")
          	//为菜单创建一个新的页面元素
          	var menu = document.createElement("div")
          	//创建一个UL元素,并将其添加到菜单div
          	var menuUI = document.createElement("ul")
          	menu.appendChild(menuUI);
          	//遍历H2元素
          	for(var i =0;i

          脚本运行的结果

          javascript学习笔记(2)_第1张图片

你可能感兴趣的:(javascript)