分享
 
 
 

为你的DHTML添活力

王朝html/css/js·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

来源:http://www.zdnet.com.cn/developer/webdevelop/story/0,3800067013,39383734,00.htm

作者: Phillip Perkins

*purpleendurer修正了原文中的一些错误

你可以通过IE为你的HTML元素添加行为,建立面向对象的页面设计方法。Phillip Perkins建立了一个<DIV>对象,当用户拖动它时,它会在限定的<DIV>内继续定向运行。

Macromedia Flash可以使开发者免受网络浏览器与互操作解决方案的限制。但是,局限于Flash让你无法体验到网络浏览器的许多特色。

例如,你可以通过IE为HTML元素添加行为,建立对象面向的页面设计方法。在这个例子中,我会建立了一个<DIV>对象,当用户拖动它时,它会在限定的<DIV>内继续定向运行。

为HTML添加行为的能力是设计的一个关键部分。在IE中,这通过相关的样式来实现。添加行为的样式特性即“behavior”。你可以通过嵌套的<STYLE>标签来添加行为,就像这样:

<style>DIV.object { behavior: url(Behavior.htc);}

从这段脚本中,你可以发现一个行为会提及到一个HTC(HTML组件)文件。既然我们具有对象化这些HTML元素的基础,我们就能建立控制它们的行为脚本。

表A中包含了为我们的嵌套<DIV>对象建立行为的所有代码。在这一个组件内就有许多的代码。

表 A --文件component.htc的内容

<public:component lightweight="true">

<public:attach event="onmousedown" onevent="element_onmousedown()"/>

<public:attach event="onmousemove" onevent="element_onmousemove()"/>

<public:attach event="onmouseup" onevent="element_onmouseup()"/>

<public:attach event="onmouseout" onevent="element_onmouseup()"/>

<public:attach event="onselectstart" onevent="element_onselectstart()"/>

<public:attach event="ondragstart" onevent="element_ondragstart()"/>

<public:attach event="onload" for="window" onevent="Init()"/>

<public:method name="moveMe"/>

<public:property name="clickPoint" get="get_clickPoint" put="put_clickPoint"/>

<public:property name="interval" get="get_interval" put="put_interval"/>

<script language="JScript">

var m_bStarted = false;

var m_bMoving = false;

var m_clickPoint = null;

var m_tStart = 0;

var m_tEnd = 0;

var m_ptStart = null;

var m_Slope = null;

var m_interval = 0;

var m_isMoving = false;

var m_trash = 0;

var m_dX = 0;

var m_dY = 0;

var m_vectX = 0;

var m_vectY = 0;

var m_pNode = null;

var m_bounds = [];

var BOUNDS = {"left":0,"top":1,"right":2,"bottom":3};

var m_dimensions = [];

var DIMS = {"width":0,"height":1};

function Init()

{

element.id = element.document.uniqueId;

var m_pNode = element.parentNode;

m_bounds = [

0,

0,

parseInt(m_pNode.currentStyle.width),

parseInt(m_pNode.currentStyle.height)

];

m_dimensions = [

parseInt(element.offsetWidth),

parseInt(element.offsetHeight)

];

}

function element_onmousedown()

{

m_bStarted = true;

m_tStart = new Date();

clearInterval(m_interval);

m_Slope = null;

m_ptStart = null;

m_trash = 0;

m_dX = 0;

m_dY = 0;

m_vectX = 0;

m_vectY = 0;

m_clickPoint = new Point(event.x, event.y);

m_ptStart = new Point(parseInt(element.currentStyle.left), parseInt(element.currentStyle.top));

}

function element_onmouseup()

{

if (!m_bMoving) return;

m_bMoving = false;

m_bStarted = false;

m_tEnd = new Date();

var t = m_tEnd.valueOf() - m_tStart.valueOf();

var lPoint = new Point(event.x, event.y);

m_Slope = Geometry.slope(m_clickPoint, lPoint);

var ptEnd = m_Slope.add(m_ptStart);

element.style.left = ptEnd.posX + "px";

element.style.top = ptEnd.posY + "px";

var spd = 0;

if (m_Slope.deltaX != 0 && m_Slope.deltaY != 0)

{

spd = Math.sqrt(Math.pow(m_Slope.deltaX, 2) + Math.pow(m_Slope.deltaY,2))/t;

}

else

{

spd = (m_Slope.deltaX + m_Slope.deltaY)/t;

}

if (spd > 1) spd = 1;

m_dX = m_Slope.deltaX;

m_dY = m_Slope.deltaY;

if (m_dX != 0) m_vectX = (m_dX > 0) ? 2 : -2;

if (m_dY != 0) m_vectY = (m_dY > 0) ? 2 : -2;

startMove(element, parseInt(1/spd));

}

function element_onmousemove()

{

m_bMoving = m_bStarted;

if (!m_bMoving) return;

var lPoint = new Point(event.x, event.y);

var lSlope = Geometry.slope(m_clickPoint, lPoint);

var ptEnd = lSlope.add(m_ptStart);

element.style.left = ptEnd.posX + "px";

element.style.top = ptEnd.posY + "px";

}

function element_onselectstart()

{

event.returnValue = false;

return false;

}

function element_ondragstart()

{

event.returnValue = false;

return false;

}

function get_clickPoint()

{

return m_clickPoint;

}

function put_clickPoint(o)

{

if (typeof(o) == "object" && o.constructor == "Point")

{

m_clickPoint = o;

}

else

{

alert("Expected Point.");

}

}

function get_interval()

{

return m_interval;

}

function put_interval(n)

{

m_interval = n;

}

function moveMe()

{

if (m_isMoving) return;

setTimeout("m_isMoving = true;", 1);

var newX = parseInt(element.currentStyle.left);

var newY = parseInt(element.currentStyle.top);

var dXabs = Math.abs(m_dX);

var dYabs = Math.abs(m_dY);

if (dXabs > dYabs)

{

//divide both by deltaX

//each call move X by 1 and Y by Y/X

//if iteration > 1, then move Y by 1

//and add remainder back on Y

newX += m_vectX;

var l_step = (m_dY/m_dX) * 2;

m_trash = m_trash + l_step;

if (m_trash > 2 || m_trash < -2)

{

newY += m_vectY;

m_trash -= m_vectX;

}

}

else

{

//vice-versa

newY += m_vectY;

var l_step = (m_dX/m_dY) * 2;

m_trash = m_trash + l_step;

if (m_trash > 2 || m_trash < -2)

{

newX += m_vectX;

m_trash -= m_vectX;

}

}

if (newX <= m_bounds[BOUNDS.left])

{

newX = m_bounds[BOUNDS.left] + 1;

m_vectX *= -1;

}

else if ((newX + m_dimensions[DIMS.width]) >= m_bounds[BOUNDS.right])

{

newX = m_bounds[BOUNDS.right] - m_dimensions[DIMS.width] - 1;

m_vectX *= -1;

}

if (newY <= m_bounds[BOUNDS.top])

{

newY = m_bounds[BOUNDS.top] + 1;

m_vectY *= -1;

}

else if ((newY + m_dimensions[DIMS.height]) >= m_bounds[BOUNDS.bottom])

{

newY = m_bounds[BOUNDS.bottom] - m_dimensions[DIMS.height] - 1;

m_vectY *= -1;

}

element.style.left = newX + "px";

element.style.top = newY + "px";

setTimeout("m_isMoving = false;", 1);

}

</script>

</public:component>

如果你注意到了脚本的顶部,在那里有一个特殊的标签告诉浏览器该用何种样式呈现特性和包含组件的方法,以及将这一组件添加到哪些事件中。这些事件都是标准的HTML事件。

当组件(在装载事件中)初始化时,它获得一个uniqueID,将其包含的母体记录在一个数字变量中,并为进程计算设定缺省值。当你逐句通过这一对象的目标处理器时,你会看到每当用户点击对象时--- element_onmousedown()---一些变量进行了初始化。下一步,用户应该将对象拖动到另一个位置。

当用户在屏幕上拖动对象时— element_onmousemove() —对象的位置发生改变,以与鼠标的运动相匹配。然后,用户应该释放鼠标按钮,让对象自行移动。

当用户释放鼠标按钮— element_onmouseup() —或是鼠标脱离了对象区域— element_onmouseout() —时,释放点即被记录下来,并对用户点击对象到释放对象的时间进行计算,对象则获得永恒运动。通过计算得出点击起始点与释放终止点的斜度,这个斜度成为对象新的移动路径。通过对象移动的距离与拖动时间可计算出用户拖动对象的速度。这个速度再又用来建立对象的移动方式。最终,速度的倒数被用来建立对象位置更新的时间间隔。

在间隔中断事件— moveMe() —中,对象的上升(rise)与运动(run)将方向斜度转换成计算的运动路径。将较大的方向改变与较小的方向改变区分开来,我们就可以做到这点。结果是,其中一个方向改变总是1,而另一个则小于1。在每次中断中,两个方向改变中较大的一个由一个向量单元增加,可能是-2或是2个像素。另一个则增加较小方向改变的两倍(即,如果上升为2而运动为1的话,那么上升将增加1 *向量而运动每次增加.5 * 2单元)。如果较小的改变增量超过向量单元(-2或2)的话,

如果对象的新位置位于限定元素之外,向量则发生改变以与之相匹配。这种方法将对象“反弹”到限定元素之外。

表B是含有这些组件的HTML页面。

表 B --demo.htm的内容

<html>

<head>

<style>

DIV.bounds

{

width: 800px;

height: 600px;

border: 1px red solid;

overflow: hidden;

}

DIV.object

{

position:absolute;

left: 0px;

top: 0px;

border: 0px blue solid;

behavior: url(component.htc);

cursor: hand;

}

</style>

<script language="JavaScript">

function Point(pX, pY)

{

this.posX = pX;

this.posY = pY;

}

function CSlope(P1, P2)

{

this.deltaY = P2.posY - P1.posY;

this.deltaX = P2.posX - P1.posX;

this.m = (P2.posY - P1.posY)/(P2.posX - P1.posX);

}

function _slopeAdd(P1)

{

var lPoint = new Point((P1.posX + this.deltaX), (P1.posY + this.deltaY));

return lPoint;

}

CSlope.prototype.add = _slopeAdd;

function CGeometry() {}

function _slope(P1, P2)

{

var lSlope = new CSlope(P1, P2);

return lSlope;

}

CGeometry.prototype.slope = _slope;

var Geometry = new CGeometry();

var objStack = [];

function startMove(obj, t)

{

var id = objStack.push(obj);

objStack[id-1].interval = setInterval("objStack[" + (id - 1) + "].moveMe()", t);

}

</script>

</head>

<body style="font-family: Verdana; font-size: 24pt;">

<center>

<div class="bounds" id="divBounds" name="divBounds" onselectstart="window.event.returnValue = false;">

<div class="object">dog</div>

</div>

</center>

</body>

</html>

HTML页面不过是包含<DIV>及作为组件元素的嵌套<DIV>。在JavaScript内,有一些支持对象与功能来帮助进行组件计算。值得注意的是,有一个对象栈— objStack —变量,在间隔中断过程中,可以用来帮助管理对组件moveMe()方法的调用。

拷贝这些代码并将它粘贴到你自己的文件中。记得把你的HTC文件命名为component.htc,特别用于行为样式特性。在IE 5.0或更高版本中运行这个例子,看着你的对象充满活力。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有