Source: http://www.zdnet.com.cn/developer/webdevelop/story/0,3800067013,39383734,00.htm
By Phillip Perkins
* Purpleendurer fixed some errors in the original text.
You can use IE to add behavior to your HTML elements and create an object-oriented page design method. Phillip Perkins creates a <div> object. When you drag it, it continues to run in a targeted manner within a limited <div>.
Macromedia Flash can protect developers from the limitations of Web browsers and interoperability solutions. However, the limitations of flash make you unable to experience many features of Web browsers.
For example, you can use IE to add behaviors to HTML elements and create an object-oriented page design method. In this example, I create a <div> object. When you drag it, it continues to run in a targeted manner within the limited <div>.
The ability to add behaviors to HTML is a key part of the design. In IE, this is achieved through related styles. The Style Feature of adding behavior is "Behavior ". You can add behavior through nested <style> labels, as shown in the following figure:
<Style> Div. object {behavior: URL (behavior. HTC );}
From this script, you can find that an action will refer to an HTC (HTML component) file. Now that we have the foundation to target these HTML elements, we can establish a behavior script to control them.
Table A contains all the code for creating behavior for the nested <div> object. There is a lot of code in this component.
Table-- File component. HTC content
<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.doc ument. 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>
If you notice the top of the script, there is a special tag that tells the browser what style to use to present features and contain components, and what events to add this component. These events are standard HTML events.
When a component (in a load event) is initialized, it obtains a uniqueid, records its parent data in a numeric variable, and sets the default value for the Process calculation. When you use the target processor of this object one by one, you will see that every time you click the object, some variables --- element_onmousedown () --- are initialized. Next, you should drag the object to another location.
When you drag an object on the screen, the position of-element_onmousemove ()-object changes to match the movement of the mouse. Then, you should release the mouse button to move the object.
When you release the mouse button-element_onmouseup ()-or the mouse is out of the object area-element_onmouseout ()-, the release point is recorded, the time when the user clicks an object to release the object is calculated, and the object obtains the permanent motion. Calculate the slope between the click Start Point and the release end point, which becomes the new moving path of the object. The distance between moving objects and the dragging time can be used to calculate the speed of dragging objects. This speed is then used to create the object moving method. Finally, the reciprocal of the speed is used to establish the time interval for object location update.
In the interval interrupt event-moveme ()-, the rise and run of the object convert the direction slope to the calculated motion path. We can achieve this by separating large and small changes. The result is that one direction is always 1, and the other is smaller than 1. During each interruption, the larger of the two changes is increased by a vector unit, which may be-2 or 2 pixels. The other one doubles the variation in a small direction (that is, if the motion is 2 and the motion is 1, the rise increases by 1 * vector and the motion increases each time. unit 5*2 ). If a small change increment exceeds the vector unit (-2 or 2,
If the object's new location is outside the limit element, the vector changes to match it. This method "bounce" the object out of the limit element.
Table B is an HTML page containing these components.
Table B--Demo.htm content
<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>
The HTML page contains <div> and the nested <div> as component elements. In JavaScript, some objects and functions are supported to help with component computing. It is worth noting that there is an object stack-objstack-variable which can be used to help manage the call to the moveme () method of the component during the interval interruption process.
Copy the code and paste it into your own file. Remember to name your HTC file component. HTC, especially for behavior style features. Run this example in IE 5.0 or later to check that your object is dynamic.