译:DOM2中的高级事件处理(转)

17.2. DOM2中的高级事件处理(Advanced Event Handling with DOM Level 2)

       译自:JavaScript: The Definitive Guide, 5th Edition ----By David Flanagan 
       

   迄今为止,在本章中出现的事件处理技术都是DOM0级的一部分,所有支持JavaScript的浏览器都支持DOM0的API.DOM2定义了高级的事件处理API,和DOM0的API相比,有着令人瞩目的不同(而且功能更强大).虽然DOM2标准并没有把已有的API收入其中,但是DOM0级API也没有被去除.对于基本的事件处理任务,你会觉得使用这些简单的API更自由一些.

DOM2事件模型被除了IE以外的所有浏览器支持.

17.2.1. 事件传播(Event Propagation)

        在DOM0级事件模型中,浏览器分派事件给发生事件的文档元素.如果那个对象有相应的事件处理程序,那么就运行该程序.再没有更多的事情发生了.情况在DOM2中就是复杂得多.在DOM2高级事件模型中,当一个文档元素(被叫做事件的目标(target)对象)触发了一个事件,这个目标对象的事件处理程序被触发,除此之外,该目标对象的每一个祖辈元素都有一个或者两个机会去处理该事件.事件传播的过程包括三个阶段.

首先,在捕获阶段(capturing phase),事件是从文档对象(Document object)开始,沿着文档树向下一直到目标对象传播的.如果任何目标对象的祖辈(不包括目标对象本身)也有一些指定注册的捕获事件的处理程序,在事件传播的这个阶段(捕获阶段)将运行它们.(一会儿你就会看到如何注册正常事件处理程序和捕获事件处理程序.)

事件传播的下一个阶段发生在目标对象自身:所有注册到目标对象的对应事件处理程序都被运行.这和DOM0提供的事件模型是相似的.

事件传播的第三阶段是冒泡阶段,或者说按文档层次倒序的,从目标元素到文档对象(Document object).尽管所有的事件都受事件传播的捕获阶段(capturing phase)的影响,但是,并不是所有类型的事件都冒泡:例如,除了被定义了提交事件(submit)的form以外,把这个事件向上传播到文档元素是没有任何意义的.另一方面,像mousedown这样的一般事件对文档中的其它元素是有意义的,所以这些事件才沿着文档层次向上冒泡,并且触发目标元素的祖辈元素的相应事件的处理程序.通常情况下,原始的输入事件冒泡,而高级的语义事件不会.(稍候在本章中出现的表17-3是一个权威的列表,它指出哪些事件是冒泡的,哪些不是.)

在事件传播期间,每个事件的处理程序都可以阻止事件的进一步传播,只需通过调用表现这个事件的事件对象的stopPropagation( )方法就可以.事件对象和stopPropagation( )方法一会儿再进一步讨论.

一些事件会使浏览器执行一个与事件相关联的默认行为.例如,当点击一个链接(<a> tag)的时候,浏览器的默认行为是转向超链接.像这样的默认行为,只有事件传播的三个阶段都完成了才会执行,在事件传播过程中调用的任何处理程序都能阻止默认行为的发生,调用事件对象的preventDefault( )方法就可以了.

尽管这种事件传播机制似乎让人难以理解,但是它有助于你集中你的事件处理代码.DOM1指出了所有的文档元素,还指出了在那些元素上允许发生的事件(如mouseover事件).这就意味着,与旧的DOM0事件模型相比,DOM1是在很多很多的地方注册事件处理程序.假设你想在鼠标经过每一个文档中的段落元素(<P>)时触发一个事件处理程序.除了在所有的段落标签(<p>tag)注册一个onmouseover事件处理程序之外,取而代之的办法是为文档对象(Document object)注册一个单独的事件处理程序,然后,或者在捕获阶段,或者在冒泡阶段,处理这些事件.

事件传播还有一个很重要的细节.在DOM0模型中,你只能为一个特定的对象的一个特定类型的事件注册一个处理程序.而在DOM2模型中,你可以为一个特定对象的一个特定类型事件注册任意数量的事件处理程序.这也适用于事件传播时,在捕获阶段或者冒泡阶段,事件对象的祖辈的处理函数被调用的情况.

17.2.2. 事件处理程序的注册(Event Handler Registration)

在DOM0的API中,你通过在HTML中设置属性(attribute)或者在JavaScript中设置一个对象的属性(property)的方法注册事件.而在DOM2模型中,你通过调用那个对象的addEventListener( )方法注册事件处理程序.(DOM标准在这个API里使用了术语listener,但是在本文中,我将继续使用这个术语的同义词:handler.)这个方法有三个参数.第一个是被注册的事件类型.事件类型是一个字符串,包含小写的,去掉开头的"on"的HTML中的事件属性名.如果你在DOM0里使用HTML属性onmousedown,你在DOM2中就是使用字符串"mousedown".

第二个参数是指定类型的事件触发的时候应该调用的监听函数.在你的函数被调用的时候,传入了唯一的一个参数:Event对象.这个对象包含了事件的细节信息(如:哪个鼠标键被按下)和一些方法,如:stopPropagation( ).在本章后面将深入讨论事件接口和它的子接口.

addEventListener( )函数的最后一个参数是一个布尔值.如果为true,指定的事件处理程序在事件传播的捕获阶段将捕获事件.如果是false,事件处理程序就是一个正常的事件处理程序了,只有在事件直接发生在该对象上或者发生在子代对象上向上冒泡到达这个元素时,处理程序才被调用.

举个例子,你可以像下面这样使用addEventListener( )方法给一个form元素注册一个提交事件(submit):

document.myform.addEventListener("submit",
                                 function(e) {return validate(e.target); }
                                 false);

如果你想捕获发生在一个特定名字的div中的鼠标按下(mousedown)事件,你可以这样使用addEventListener( ):

var mydiv = document.getElementById("mydiv");
mydiv.addEventListener("mousedown", handleMouseDown, true);

注意,这些例子假设你已经在你的JavaScript代码中定义了函数名为validate( )和handleMouseDown( )的函数.

用addEventListener( )函数注册的事件监听程序运行在它们被定义的作用域.它们并不是在参数的作用域链中被调用的.

因为在DOM2中通过调用一个方法来给对象添加事件监听器,而不是通过设置HTML属性或者JavaScript属性的方法,所以,你可以给一个指定对象的一个特定事件注册多于一个的事件监听程序.如果你通过调用addEventListener( )函数为同一对象的同一事件注册多个监听程序,当那个对象上那个类型的事件发生的时候(或者是向上冒泡,或者是捕获的),所有的处理程序都被调用.重点理解一下:DOM标准并没有保证一个对象的所有监听函数被调用的顺序,因此,你不应该依赖于函数按照被注册的顺序被执行(事实上是根本不按顺序执行).还要注意的是,如果你多次注册相同的监听程序给同一个元素,只有第一次注册的有效,其余的被忽略.

为什么你想要在同一个对象的同一个事件上注册多个事件监听程序呢?因为这有助于将你的软件模块化.假设,你写了一个可重用的JavaScript代码模块,它使用图像上的mouseover事件执行图片轮换.现在再假设你有另一个模块也想使用mouseover事件来显示一些在HTML弹出窗体或者工具提示(Tool tip)上的附加信息.在DOM0的API中,你不得不把这两段代码合并成一个,这样才能共用一个图片对象的onmouseover属性.另一方面,在DOM2的API中,每一个模块都可以注册它需要的事件监听程序,而不必管其它的模块.

removeEventListener( )和addEventListener( )是一对方法,它需要与addEventListener( )同样的三个参数,但它的功能是从一个对象删除一个事件监听函数,而不是添加.它常用于临时注册一个事件监听函数,然后很快就删除这个函数.例如,你得到一个mousedown事件的时候,想为mousemove和mouseup事件注册临时的捕获事件监听函数,这样就可以知道,是否用户拖拽了鼠标.然后在mouseup事件发生的时候,解除这个注册的监听程序.在这种情况下,事件监听器的删除代码如下:

document.removeEventListener("mousemove", handleMouseMove, true);
document.removeEventListener("mouseup", handleMouseUp, true);

addEventListener( )方法和removeEventListener( )方法都被定义在事件目标接口中(the EventTarget interface),在支持DOM2事件模型的Web浏览器中,元素和文档节点实现了这个接口,并且提供了这些事件注册方法.

[*] 从技术上来讲,DOM指出在文档(document)中的所有节点(包括文本节点:Text nodes)都实现了这个事件对象接口.然后事实上,web浏览器仅在元素(Element)和文档节点(Document nodes)上支持事件监听器的注册,还有窗口(Window)对象,尽管这已经超出了DOM的范围.

17.2.3. addEventListener( )和this关键字(addEventListener( ) and the this Keyword)

在原来的DOM0级事件模型中,当一个函数被注册给一个文档元素的某个事件监听程序时,它变成了那个文档元素的一个方法.当这个事件监听程序被调用时,它作为这个元素的一个方法被调用,在函数的内部,this关键字引用当前发生事件的元素.

DOM2是用一种与语言无关的方法写的,它指出监听器(listeners)是对象,而不是简单的函数.绑定了DOM的JavaScript用Javascript函数事件监听器取代对JavaScript对象使用的需求.( The JavaScript binding of the DOM makes JavaScript functions event handlers instead of requiring the use of a JavaScript object.)不幸的是,这个绑定关系并没有实际的指出监听函数如何被调用,也没有指出this关键字的值.

且不去考虑标准的不足,所有已知的实现都调用用addEventListener( )方法注册的处理程序,就像这些处理程序是目标对象的方法一样.也就是说,当监听程序被调用的时候,this关键字引用这个监听程序被注册的那个对象.如果你宁愿不依赖这种未指定的行为,你可以使用传入监听程序的事件对象(Event object)的currentTarget属性.在本章稍候的讨论中你会看到,currentTarget属性引用事件监听程序被注册的对象.

17.2.4. 把对象(Objects)注册为事件监听器(Registering Objects as Event Handlers)

        addEventListener( )允许你注册一个事件监听函数.对于面向对象编程,你可能更喜欢定义一个客户端对象的方法作为事件监听程序,然后把它们作为那个对象的方法进行调用.对于Java程序员,DOM标准允许这样做:事件监听程序可以是实现了EvnentListener接口并且有一个名为handleEvent()的方法的对象.在Java中,当你注册一个事件监听程序时,你给addEventListener( )传入一个对象,而不是一个函数.简单的说,绑定了DOM API的JavaScript不需要你去实现EventListener接口,相反的,允许你直接给addEventListener( )传递一个函数引用.

然而,如果你在写一个面向对象的JavaScript程序,并且更喜欢用对象作为事件监听程序,你可以用一个像下边这样的函数来注册:

function registerObjectEventHandler(element, eventtype, listener, captures) {
    element.addEventListener(eventtype,
                             function(event) { listener.handleEvent(event); }
                             captures);
}

只要一个对象定义了handleEvent( )方法,就可以用这个函数把该对象注册为一个事件监听程序.那个方法作为监听对象的方法被调用,this关键字引用这个监听对象,而不是产生事件的文档元素.

尽管这不是DOM标准的一部分,Firefox(和其它基于Mozilla codebase的浏览器)允许把定义了handleEvent()方法的事件监听对象直接传递给addEventListener()方法,来代替函数.对于这些浏览器,就没有必要定义一个像刚才展示的注册函数了.

17.2.5. 事件模型和事件类型(Event Modules and Event Types)

如我前面所说,DOM2是模块化的,所以,一个实现可以支持其中的一部分而忽略其它对其它部分的支持.事件API(Events API)就是这样一个模块.你可以像这样来测试一个浏览器是否支持这个模块:

document.implementation.hasFeature("Events", "2.0")

然而,事件模块只包含用于基本事件监听结构的API.子模块提供对特定类型事件的支持.每个子模块都提供对一类相关事件类型的支持,并且定义了传入事件监听程序的事件类型.例如,名为MouseEvents的子模块提供了mousedown, mouseup, click等相关事件的类型.它也定义了MouseEvent接口.实现了那个接口的对象,为任何一个被这个模块支持的事件类型,被传入事件监听程序.

表17-2列出了每一个事件模块,它定义的接口,和被它支持的事件类型.注意,DOM2并没有把任何键盘事件标准化,因此这里没有列出键盘事件模块.然而,当前的浏览器都支持键盘事件,在本章的后面,你会了解的更多一些.(此处省略几句和MutationEvents模块相关的描述)

Table 17-2. Event modules, interfaces, and types


Module name


Event interface


Event types


HTMLEvents


Event


abort, blur, change, error, focus, load, reset, resize, scroll, select, submit, unload


MouseEvents


MouseEvent


click, mousedown, mousemove, mouseout, mouseover, mouseup


UIEvents


UIEvent


DOMActivate, DOMFocusIn, DOMFocusOut

如你在表17-2中所见,HTMLEvents和MouseEvents模块定义的事件类型和DOM0的事件模块是非常相似的.UIEvents模块定义了事件类型,这和被HTML表单元素支持的focus,blur和click事件很相似,但更通用的,所以,他们能被任何可以接受焦点或者被激活的文档元素产生.

如前所述,当一个事件发生的时候,它的监听程序被传入一个实现了那个类型事件的事件接口对象.这个对象的属性提供了对事件监听程序可能有用的细节信息.表17-3再一次列出标准的事件,但这次是按事件类型组织的,而不是事件模型.对于每个事件类型,该表都指出传入它的监听程序的事件对象的种类,是否这个事件有一个可以用preventDefault()方法阻止发生的默认行为.对于HTMLEvents模块中的事件,表格中的第五列指出哪些HTML元素可以产生该事件.对于所有其它的事件类型,第五列指出事件对象的哪些属性包含了有意义的事件细节信息.注意,在这一列中列出的属性,不包括被基本事件接口定义的对所有事件类型都有意义的属性.

Table 17-3. Event types


Event type


Interface


B


C


Supported by/detail properties


abort


Event


yes


no


<img><object>


blur


Event


no


no


<a><area><button><input><label><select><textarea>


change


Event


yes


no


<input><select><textarea>


click


MouseEvent


yes


yes


screenXscreenYclientXclientYaltKeyctrlKeyshiftKeymetaKeybuttondetail


error


Event


yes


no


<body><frameset><img><object>


focus


Event


no


no


<a><area><button><input><label><select><textarea>


load


Event


no


no


<body><frameset><iframe><img><object>


mousedown


MouseEvent


yes


yes


screenXscreenYclientXclientYaltKeyctrlKeyshiftKeymetaKeybuttondetail


mousemove


MouseEvent


yes


no


screenXscreenYclientXclientYaltKeyctrlKeyshiftKeymetaKey


mouseout


MouseEvent


yes


yes


screenXscreenYclientXclientYaltKeyctrlKeyshiftKeymetaKeyrelatedTarget


mouseover


MouseEvent


yes


yes


screenXscreenYclientXclientYaltKeyctrlKeyshiftKeymetaKeyrelatedTarget


mouseup


MouseEvent


yes


yes


screenXscreenYclientXclientYaltKeyctrlKeyshiftKeymetaKeybuttondetail


reset


Event


yes


no


<form>


resize


Event


yes


no


<body><frameset><iframe>


scroll


Event


yes


no


<body>


select


Event


yes


no


<input><textarea>


submit


Event


yes


yes


<form>


unload


Event


no


no


<body><frameset>


DOMActivate


UIEvent


yes


yes


detail


DOMFocusIn


UIEvent


yes


no


none


DOMFocusOut


UIEvent


yes


no


none

被DOM0和DOM2支持的事件类型大体相同(UIEvents除外).DOM2标准添加了对abort,error,resize和scroll事件类型的支持,这些不是HTML 4的标准,但它不支持HTML 4标准中的键盘事件和双击事件.(取而代之的是,传入click事件处理程序的对象的细节属性指出了发生的连续点击的次数,在event的detail属性中.)

17.2.6. 事件接口和事件细节(Event Interfaces and Event Details)

        一个事件发生的时候,DOM2提供了关于这个事件的其它细节(例如何时何地发生的),这些信息作为传入到事件监听程序的对象的属性出现.每一个事件模块都有一个相关联的事件接口,该接口指出和那个类型事件相关的细节.表17-2列出了三种不同的事件模块和三种不同的事件接口.

事实上这三个接口是互相关联的,并且形成了一个层次关系.事件接口是这个层次的根层;所有的事件对象都实现了它大部分基本的事件接口.UIEvent是事件接口的子接口:任何实现了UIEvent接口的事件对象都实现了Event接口的属性和方法.MouseEvent接口又是UIEvent的子接口.举个例子,这就是说,传给点击事件处理程序的事件对象实现了在MouseEvent, UIEvent, 和Event接口中定义的所有属性和方法.

接下来的部分介绍的是事件接口,并且着重讲最重要的属性和方法.

17.2.6.1. 事件(Event) 
        在HTMLEvents模块中定义的事件类型使用Event接口.所有其它的事件类型都使用Event的子接口,子接口被所有的事件对象实现,并且提供了应用于那个事件类型的细节信息.事件接口定义了如下属性(注意,这些属性和所有事件子接口的属性都是只读的):

type
        发生的事件类型.这个属性的值是事件类型的名字,它和用于注册事件处理程序时使用的字符串是一样的(如: click 或者 mouseover).

target
        事件发生的节点,可能与currentTarget不同.

currentTarget
        正在处理事件的节点(也就是正在运行的事件处理程序所属的节点).如果在事件被捕获或者冒泡阶段被处理,这个属性的值和target属性的值是不同的.如前所述,你可以在你的事件处理程序中用这个属性代替this关键字

eventPhase
        指出正在理的是事件传播的哪一个阶段的数值.该值为三个常中之一:Event.CAPTURING_PHASE, Event.AT_TARGET, 或者 Event.BUBBLING_PHASE.

timeStamp
        指出该事件何时发生的日期对象

bubbles
        指出该事件是否沿文档树向中冒泡的布尔值.

cancelable
        指出该事件是否有一个可以用prevertDefault()阻止的和事件相关联的默认行为的布尔值.

除了这七个属性以外,事件接口定义了两个方法,也都被事件对象实现了,它们是:stopPropagation( ) 和 preventDefault( ).任何事件处理程序都可以调用stopPropagation( )来阻止正在被传播的事件越过正在被处理的节点.任何事件处理程序都可以调用preventDefault( )来阻止浏览器执行与该事件关联的默认行为.在DOM2中调用preventDefault( ),就像在DOM0中返回false.

17.2.6.2. 用户信息事件(UIEvent) 
        用户信息事件接口是Event的子接口.它定义了被传递到DOMFocusIn, DOMFocusOut和DOMActivate的事件对象的类型.这些事件类型通常是用不到的;但对于UIEvent接口来讲,比较重要的是它是MouseEvent的父接口.除了在Event中定义的属性外,UIEvent还定义了两个属性:

view
        发生的事件所在的窗口对象(Window Object:known as a view in DOM terminology).

detail
        可以提供附加信息的数值.对于click,mousedown和mouseup事件,这个字段代表点击计数:1代表单击,2代表双击,3代表三击.(注意,每次点击都产生一个事件,但是如果多次点击间隔足够短,detail属性就会指示出来.也就是说,detail为2的鼠标事件要优先于detail为1的鼠标事件.)对于DOMActivate事件,这个字段值为1代表正常激活,2代表极度活跃(hyperactivation),比如双击或者Shift-Enter组合键.

17.2.6.3. MouseEvent

MouseEvent接口继承了Event和UIEvent的属性和方法,还定义了如下附加属性:
附加属性:

button
        数值类型,指出在mousedown, mouseup或者click事件期间哪一个鼠标键改变了状态.0代表左键,1代表中键,2代表右键.只有当一个按键改变状态时,才使用这个属性;例如:不能用于报告mousemove事件发生时哪个键是被按下的.注意Netscape 6得到的值为1,2,3,而不是0,1,2.这个问题在Netscape 6.1中已经修正了.

altKey , ctrlKey, metaKey, shiftKey
        这四个布尔值代表,当一个鼠标事件发生时,是否 Alt, Ctrl, Meta或者Shift键被按下.与button属性不同,这些按键属性对于任何鼠标事件都是有效的.

clientX, clientY
        这两个属性指出鼠标指针的X和Y坐标,相对于浏览器窗口的客户区.注意这个坐标并没有计算文档的滚动高度或者宽度在内:如果事件发生在窗口的最上边,不管这个文档已经向下滚动了多远,clientY就是0.不幸的是,DOM2并没有提供一个标准的方法去转换这个窗口坐标为文档坐标.在除了IE以外的浏览器中,你可以加上window.pageXOffset和window.pageYOffset.

screenX, screenY
        这两个属性指出鼠标指针相对于用户显示器的左上角的坐标.如果你打算在鼠标事件发生的地点或者附近打开一个窗口,这两个属性就有用了.

relatedTarget
        这个属性引用一个相对于事件的target节点的节点.对于mouseover事件,它引用当鼠标经过target节点时鼠标离开的那个节点.对于mouseout事件,它引用当鼠标离开目标节点时,鼠标进入的节点.对于其它事件,这两个属性是无用的.

17.2.7. 混合事件模型(Mixing Event Models)

        到现在为止,我们讨论了传统的DOM0级事件模型,和新的标准的DOM2模型.为了向后兼容,支持DOM2模型的浏览器将继续支持DOM0级事件模型.这就意味着,你可以在一个文档里混合使用这两种事件模型.

支持DOM2级事件模型的web浏览器总是传递一个事件对象给事件监听程序,这和用DOM0级事件模型的HTML属性或者JavaScript属性注册事件处理程序是一致的,理解这一点很重要.当事件监听程序作为一个HTML属性被定义的时候,它被暗中转换成一个函数,这个函数有一个名为event的参数.这就意味着,像这样的一个事件监听程序可以用标识符event来引用事件对象.

DOM标准承认DOM0级事件模型继续保留使用,并指出,对待DOM0事件模型的监听程序的注册方法就像用addEventListener( )注册的一样.也就是说,如果你给一个文档元素e的onclick属性赋值为函数f(或者说设置对应的HTML中的onclick属性),它和下面这种注册方法是一样的:

e.addEventListener("click", f, false);

当函数f被调用的时候,传入一个事件对象作为参数,尽管这个函数是用DOM0模型注册的.

时间: 2024-11-01 01:43:09

译:DOM2中的高级事件处理(转)的相关文章

[译]JavaScript中,{}+{}等于多少?

[译]JavaScript中,{}+{}等于多少? 原文:http://www.2ality.com/2012/01/object-plus-object.html 最近,Gary Bernhardt在一个简短的演讲视频“Wat”中指出了一个有趣的JavaScript怪癖:在把对象和数组混合相加时,会得到一些你意想不到的结果.本篇文章会依次讲解这些计算结果是如何得出的. 在JavaScript中,加法的规则其实很简单,只有两种情况:你只能把数字和数字相加,或者字符串和字符串相加,所有其他类型的值

[IBM]掌握Ajax,Ajax中的高级请求和响应

掌握 Ajax, Ajax 中的高级请求和响应 http://www.ibm.com/developerworks/cn/xml/wa-ajaxintro1.html http://www.ibm.com/developerworks/cn/xml/wa-ajaxintro2/ http://www.ibm.com/developerworks/cn/xml/wa-ajaxintro3/ dynaTrace Ajax:前端性能分析利器 http://www.ibm.com/developerwo

Python中的高级数据结构(转)

add by zhj: Python中的高级数据结构 数据结构 数据结构的概念很好理解,就是用来将数据组织在一起的结构.换句话说,数据结构是用来存储一系列关联数据的东西.在Python中有四种内建的数据 结构,分别是List.Tuple.Dictionary以及Set.大部分的应用程序不需要其他类型的数据结构,但若是真需要也有很多高级数据结构可供 选择,例如Collection.Array.Heapq.Bisect.Weakref.Copy以及Pprint.本文将介绍这些数据结构的用法,看 看它

mysql中的高级查询

mysql中的高级查询 以前学习的查询语法:   select 字段名 from 表名 where 条件   其实,查询的语法变化很多: 1. select 可以查询表达式, 表达式就是 运算符+操作数. 比如 1 + 1   2 * 3  2-1+5*9   Math.random() * 1; 可以看出,数据库中,字符串+字符串不是拼接,而是计算加法, 试一试,拿着'1' + 'a123'. 扩充,如果非要让两个字符串是拼接,咋办? 2. 表的别名     其实列也可以起别名:   3. d

Python中的高级数据结构详解

这篇文章主要介绍了Python中的高级数据结构详解,本文讲解了Collection.Array.Heapq.Bisect.Weakref.Copy以及Pprint这些数据结构的用法,需要的朋友可以参考下 数据结构 数据结构的概念很好理解,就是用来将数据组织在一起的结构.换句话说,数据结构是用来存储一系列关联数据的东西.在Python中有四种内建的数据结构,分别是List.Tuple.Dictionary以及Set.大部分的应用程序不需要其他类型的数据结构,但若是真需要也有很多高级数据结构可供选择

链接脚本在编程中的高级运用之一:可变长数组

作为嵌入式软件工程师,应该要清楚程序的每一条指令在哪里,什么时候会被加载到内存,什么时候会被执行.链接脚本会明确告诉你程序的代码和数据在内存中的分布.精确控制代码和数据在内存中的分布是高效利用内存资源的前提.自定义链接脚本是资深嵌入式软件工程师的必备技能,更是嵌入式架构师的最基本要求.此外,灵活定制链接脚本在编程方面有更高级的应用. 一.编译链接原理 简单讲述编译链接的基本原理有助于后面内容的理解. a. 简单点说,一个可执行程序包括文件头.代码段(.text).数据段(.bss).符号段等信息

Delphi2010中DataSnap高级技术

Delphi2010中DataSnap高级技术 日期:2010年12月1日 作者:SUNSTONE原创 人气:13498 查看:[大字体 中字体 小字体]  (1)—为DataSnap系统服务程序添加描述 这几天一直在研究Delphi 2010的DataSnap,感觉功能真是很强大,现在足有理由证明Delphi7该下岗了. DataSnap有三种服务模式,其中Service Application方式建立的windows服务没有描述,描述部分是空的,感觉总是欠缺点什么. 现找到办法添加描述: p

链接脚本在编程中的高级运用之二——执行时库和C++特性支持

我们在链接脚本在编程中的高级运用之中的一个可变长数组中已经讲述了编译链接的原理,并且以uboot命令为例具体介绍链接脚本怎样实现可变长数组. 本章在前者的基础上继续讲述链接脚本在执行时库中的高级应用技巧.以及编译器怎样支持类对象的构造和析构函数.本章的应用原则上类似于可变长数组,但本章更加側重讲述执行时库的实现原理,其不仅通过链接脚本的section来实现可变长数组去支持随意多类对象的构造函数和析构函数,并且还支持特定函数体的"可变长". 一.执行时库和类对象的构造.析构函数 非常多程

链接脚本在编程中的高级运用之二——运行时库和C++特性支持

我们在链接脚本在编程中的高级运用之一可变长数组中已经讲述了编译链接的原理,并且以uboot命令为例详细介绍链接脚本如何实现可变长数组.本章在前者的基础上继续讲述链接脚本在运行时库中的高级应用技巧,以及编译器如何支持类对象的构造和析构函数.本章的应用原则上类似于可变长数组,但本章更加侧重讲述运行时库的实现原理,其不仅通过链接脚本的section来实现可变长数组去支持任意多类对象的构造函数和析构函数,而且还支持特定函数体的"可变长". 一.运行时库和类对象的构造.析构函数 很多程序员以为程