loadLibrary,GetProcAddress ...

 

IDirectDraw *DynamicDirectDrawCreate(void) {
typedef HRESULT (WINAPI *DirectDrawCreateFunc)
(
GUID FAR *guid,
IDirectDraw FAR **device,
IUnknown FAR *unknown
);
 
HMODULE library;
DirectDrawCreateFunc create;
IDirectDraw *device;
 
library = LoadLibrary("ddraw.dll");
 
if(!library) {
return NULL;
}
 
create = (DirectDrawCreateFunc) GetProcAddress(library, "DirectDrawCreate");
 
if(!create) {
return NULL;
}
 
create(0, &device, 0);
 
return device;
}

flex 实用公式

 

实用公式 

    统领全书,我们已经有了各种运动和效果的公式。我已经提取出了最实用和最常用的公式、方程、以及代码的摘录,并将它们列在本章的最后。我认为将它们放到同一个地方应该对大家非常有帮助,因此我将这些我认为最需要的内容放到一起作为整体的一个参考资料。我将会在这一页夹上书签。 

 

 

第三章 
基础三角函数的计算: 
角的正弦值 = 对边 / 斜边 
角的余弦值 = 邻边 / 斜边 
角的正切值 = 对边 / 邻边 

 

弧度转换为角度以及角度转换为弧度: 
弧度 = 角度 * Math.PI / 180 
角度 = 弧度 * 180 / Math.PI 

 

向鼠标(或者任何一个点)旋转: 
// 用要旋转到的 x, y 坐标替换 mouseX, mouseY 
dx = mouseX - sprite.x; 
dy = mouseY - sprite.y; 
sprite.rotation = Math.atan2(dy, dx) * 180 / Math.PI; 

 

创建波形: 
// 将 x, y 或其它属性赋值给 Sprite 影片或影片剪辑, 
// 作为绘图坐标,等等。 
public function onEnterFrame(event:Event){ 
value = center + Math.sin(angle) * range; 
angle += speed; 

 

创建圆形: 
// 将 x, y 或其它属性赋值给 Sprite 影片或影片剪辑, 
// 作为绘图坐标,等等。 
public function onEnterFrame(event:Event){ 
xposition = centerX + Math.cos(angle) * radius; 
yposition = centerY + Math.sin(angle) * radius; 
angle += speed; 

 

创建椭圆: 
// 将 x, y 或其它属性赋值给 Sprite 影片或影片剪辑, 
// 作为绘图坐标,等等。 
public function onEnterFrame(event:Event){ 
xposition = centerX + Math.cos(angle) * radiusX; 
yposition = centerY + Math.sin(angle) * radiusY; 
angle += speed; 

 

获得两点间的距离: 
// x1, y1 和 x2, y2 是两个点 
// 也可以是 Sprite / MovieClip 坐标,鼠标坐标,等等。 
dx = x2 – x1; 
dy = y2 – y1; 
dist = Math.sqrt(dx*dx + dy*dy); 

 

第四章 

十六进制转换为十进制: 
trace(hexValue); 

 

十进制转换为十六进制: 
trace(decimalValue.toString(16)); 

 

颜色组合: 
color24 = red << 16 | green << 8 | blue; 
color32 = alpha << 24 | red << 16 | green << 8 | blue; 

 

颜色提取: 
red = color24 >> 16; 
green = color24 >> 8 & 0xFF; 
blue = color24 & 0xFF; 
alpha = color32 >> 24; 
red = color32 >> 16 & 0xFF; 
green = color32 >> 8 & 0xFF; 
blue = color232 & 0xFF; 

 

穿过某点绘制曲线: 
// xt, yt 是我们想要穿过的一点 
// x0, y0 以及 x2, y2 是曲线的两端 
x1 = xt * 2 – (x0 + x2) / 2; 
y1 = yt * 2 – (y0 + y2) / 2; 
moveTo(x0, y0); 
curveTo(x1, y1, x2, y2); 

 

第五章 
角速度转换为 x, y 速度: 
vx = speed * Math.cos(angle); 
vy = speed * Math.sin(angle); 

 

角加速度(作用于物体上的 force)转换为 x, y 加速度: 
ax = force * Math.cos(angle); 
ay = force * Math.sin(angle); 

 

将加速度加入速度: 
vx += ax; 
vy += ay; 

 

将速度加入坐标: 
movieclip._x += vx; 
sprite.y += vy; 

 

第六章 
移除出界对象: 
if(sprite.x - sprite.width / 2 > right || 
sprite.x + sprite.width / 2 < left || 
sprite.y – sprite.height / 2 > bottom || 
sprite.y + sprite.height / 2 < top) 

// 删除影片的代码 

 

重置出界对象: 
if(sprite.x - sprite.width / 2 > right || 
sprite.x + sprite.width / 2 < left || 
sprite.y – sprite.height / 2 > bottom || 
sprite.y + sprite.height / 2 < top) 

// 重置影片的位置和速度 

 

屏幕环绕出界对象: 
if(sprite.x - sprite.width / 2 > right) 

sprite.x = left - sprite.width / 2; 

else if(sprite.x + sprite.width / 2 < left) 

sprite.x = right + sprite.width / 2; 

if(sprite.y – sprite.height / 2 > bottom) 

sprite.y = top – sprite.height / 2; 

else if(sprite.y + sprite.height / 2 < top) 

sprite.y = bottom + sprite.height / 2; 

 

摩擦力应用(正确方法): 
speed = Math.sqrt(vx * vx + vy * vy); 
angle = Math.atan2(vy, vx); 
if(speed > friction) 

speed -= friction; 

else 

speed = 0; 

vx = Math.cos(angle) * speed; 
vy = Math.sin(angle) * speed; 

 

摩擦力应用(简便方法): 
vx *= friction; 
vy *= friction; 

 

第八章: 
简单缓动运动,长形: 
var dx:Number = targetX - sprite.x; 
var dy:Number = targetY - sprite.y; 
vx = dx * easing; 
vy = dy * easing; 
sprite.x += vx; 
sprite.y += vy; 

 

简单缓动运动,中形: 
vx = (targetX - sprite.x) * easing; 
vy = (targetY - sprite.y) * easing; 
sprite.x += vx; 
sprite.y += vy; 

 

简单缓动运动,短形: 
sprite.x += (targetX - sprite.x) * easing; 
sprite.y += (targetY - sprite.y) * easing; 

 

简单弹性运动,长形: 
var ax:Number = (targetX - sprite.x) * spring; 
var ay:Number = (targetY - sprite.y) * spring; 
vx += ax; 
vy += ay; 
vx *= friction; 
vy *= friction; 
sprite.x += vx; 
sprite.y += vy; 

 

简单弹性运动,中形: 
vx += (targetX - sprite.x) * spring; 
vy += (targetY - sprite.y) * spring; 
vx *= friction; 
vy *= friction; 
sprite.x += vx; 
sprite.y += vy; 

 

简单弹性运动,短形: 
vx += (targetX - sprite.x) * spring; 
vy += (targetY - sprite.y) * spring; 
sprite.x += (vx *= friction); 
sprite.y += (vy *= friction); 

 

偏移弹性运动: 
var dx:Number = sprite.x - fixedX; 
var dy:Number = sprite.y - fixedY; 
var angle:Number = Math.atan2(dy, dx); 
var targetX:Number = fixedX + Math.cos(angle) * springLength; 
var targetY:Number = fixedX + Math.sin(angle) * springLength; 
// 如前例弹性运动到 targetX, targetY 

 

第九章 
距离碰撞检测: 
// 从影片 spriteA 和 spriteB 开始 
// 如果使用一个空白影片,或影片没有半径(radius)属性 
// 可以用宽度或高度除以 2。 
var dx:Number = spriteB.x - spriteA.x; 
var dy:Number = spriteB.y - spriteA.y; 
var dist:Number = Math.sqrt(dx * dx + dy * dy); 
if(dist < spriteA.radius + spriteB.radius) 

// 处理碰撞 

 

多物体碰撞检测: 
var numObjects:uint = 10; 
for(var i:uint = 0; i < numObjects - 1; i++) 

// 使用变量 i 提取引用 
var objectA = objects[i]; 
for(var j:uint = i+1; j 

  // // 使用变量 j 提取引用 
  var objectB = objects[j]; 
  // perform collision detection 
  // between objectA and objectB 

 

第十章 
坐标旋转: 
x1 = Math.cos(angle) * x - Math.sin(angle) * y; 
y1 = Math.cos(angle) * y + Math.sin(angle) * x; 

 

反坐标旋转: 
x1 = Math.cos(angle) * x + Math.sin(angle) * ;y 
y1 = Math.cos(angle) * y - Math.sin(angle) * x; 

 

第十一章 
动量守恒的数学表达式: 
                (m0 – m1) * v0 + 2 * m1 * v1 
v0Final = ---------------------------------------------- 
                          m0 + m1 

                (m1 – m0) * v1 + 2 * m0 * v0 
v1Final = --------------------------------------------- 
                          m0 + m1 


动量守恒的 ActionScript 表达式,短形: 
var vxTotal:Number = vx0 - vx1; 
vx0 = ((ball0.mass - ball1.mass) * vx0 + 
2 * ball1.mass * vx1) / 
(ball0.mass + ball1.mass); 
vx1 = vxTotal + vx0; 

 

第十二章 
引力的一般公式: 
force = G * m1 * m2 / distance2 

 

ActionScript 实现万有引力: 
function gravitate(partA:Ball, partB:Ball):void 

var dx:Number = partB.x - partA.x; 
var dy:Number = partB.y - partA.y; 
var distSQ:Number = dx * dx + dy * dy; 
var dist:Number = Math.sqrt(distSQ); 
var force:Number = partA.mass * partB.mass / distSQ; 
var ax:Number = force * dx / dist; 
var ay:Number = force * dy / dist; 
partA.vx += ax / partA.mass; 
partA.vy += ay / partA.mass; 
partB.vx -= ax / partB.mass; 
partB.vy -= ay / partB.mass; 

 

第十四章 
余弦定理 
a2 = b2 + c2 - 2 * b * c * cos A 
b2 = a2 + c2 - 2 * a * c * cos B 
c2 = a2 + b2 - 2 * a * b * cos C 

 

ActionScript 的余弦定理: 
A = Math.acos((b * b + c * c - a * a) / (2 * b * c)); 
B = Math.acos((a * a + c * c - b * b) / (2 * a * c)); 
C = Math.acos((a * a + b * b - c * c) / (2 * a * b)); 

 

第十五章 
基本透视法: 
scale = fl / (fl + zpos); 
sprite.scaleX = sprite.scaleY = scale; 
sprite.alpha = scale; // 可选 
sprite.x = vanishingPointX + xpos * scale; 
sprite.y = vanishingPointY + ypos * scale; 

 

Z 排序: 
// 假设有一个带有 zpos 属性的 3D 物体的数组 
objectArray.sortOn("zpos", Array.DESCENDING | Array.NUMERIC); 
for(var i:uint = 0; i < numObjects; i++) 

setChildIndex(objectArray[i], i); 

 

坐标旋转: 
x1 = cos(angleZ) * xpos - sin(angleZ) * ypos; 
y1 = cos(angleZ) * ypos + sin(angleZ) * xpos; 
x1 = cos(angleY) * xpos - sin(angleY) * zpos; 
z1 = cos(angleY) * zpos + sin(angleY) * xpos; 
y1 = cos(angleX) * ypos - sin(angleX) * zpos; 
z1 = cos(angleX) * zpos + sin(angleX) * ypos; 

 

3D 距离: 
dist = Math.sqrt(dx * dx + dy * dy + dz * dz); '

 

 

ref:http://www.cnblogs.com/liongis/archive/2010/08/10/1796558.html

flex, component's life-cycle

这篇文章帮了我很大的忙,转了

Earlier today I fixed a minor code issue. It took seconds to identify, but I remember being a little stumped by a similar problem in my early Flex days. The difference now is that I'm familiar with the component life-cycle.

You may think it is only worth reading up on the Flex component life-cycle if you intend to create advanced components, but that's not true, even when you are doing nothing other than extending basic mxml components a little knowledge goes a long way.

To demonstrate the problem take a look at the init method for this simple mxml component called TimeInputBar (which extends Canvas).

 

   
      //<code>Init</code> is called when the component's <code>initialize</code> event is fired:
   
      public var time:Number;
   
       
   
      public function init():void
   
      {
   
          time = 0;
   
      }

That's simple enough. Now take a look at the ActionScript which is creating an instance of the TimeInputBar:

 

   
      var t:TimeInputBar = new TimeInputBar();
   
      t.time = 12;
   
      addChild(t);

Again, simple code, but did you spot the problem? With a little bit of knowledge it's easy to see that time will always be reset to 0 and will never be 12. Why?

When you create a component using the new operator, only part of the life-cycle completes. The component gets as far as the configuration stage, which means you can set properties on the component (to be processed by the component later) but the life-cycle will not go any further than that. It is in effect, paused.

However, all the really cool stuff in the life-cycle, like creating the component's child elements, measuring the component, drawing the component and dispatching events happens during the next stage.

It is only when you add the component to the display list using addChild or addChildAt that the life-cycle continues (in other words ... it continues when the component has a parent).

As mentioned, the next phase is the one in which the cool stuff happens: In more detail, this means that the preinitialize event is dispatched, the component's children are created, the initialize event is dispatched and the component's validation methods are called (those are beyond the scope of this article) and if that's not enough for you, when all that is done then everybody's favourite event, creationComplete is dispatched.

So, with that knowledge in hand let's revisit the order of execution for the original example:

  • Create component using 'new' operator
  • Set time variable to 12
  • Add component to display list
  • initialize event is fired
  • init() method is called
  • time variable is set to 0

Many beginners make the assumption that the preinitialize and initialize events are dispatched early on - don't beat yourself up, that's a reasonable assumption to make. However those events may actually be dispatched after you've set initial values for some of your component's properties.

So, what's the solution? We could simply swap the order of our code:

 

   
      //no worky!
   
      t.time = 12;
   
      addChild(t);
   
       
   
      //worky
   
      addChild(t);
   
      t.time = 12;


...but I'm hoping you can see the issue; components should be just a little more flexible than that!

A perfectly acceptable solution here would be to perform a simple check inside our init method:

 

   
      public var time:Number;
   
       
   
      private function init():void
   
      {
   
          if(isNaN(time)) time = 0;
   
      }


[Edit - it's also perfectly acceptable to set 'time' to 0 when you first declare it - this post is not really concerned with which solution you choose, but rather it uses simplified code to explain why such a problem may arise in the first place.]

Once that is done, it will not matter if you set time before or after you add your component to the display list. If the value is set externally before init is called, the value will not be overridden.

You can read a little more about the Flex component life-cycle in one of my earlier posts here.

ref:nwebb.co.uk/blog/

 

 

jqGrid 问题笔记

 

所谓问题可能不是jqgrid本身问题,而是浏览器或应用的特殊需要而产生的问题。

 

01.单元格内的文本自动换行

 

加入样式:

 

.ui-jqgrid tr.jqgrow td {

    white-space: normal !important;

    height:auto;

    vertical-align:text-top;

    padding-top:2px;

}

 

具体说明可参阅: http://blog.qumsieh.ca/2009/12/03/jqgrid-textword-wrapping/

 

 

02.保持显示垂直滚动条

 

在IE中记录比较少的时候,默认情况下不显示垂直滚动条,会出现标题行与数据行位置对不齐的情况,通过保持显示垂直滚动条可以解决这个问题。

 

    $( pGridId ).closest(".ui-jqgrid-bdiv").css({ 'overflow-y' : 'scroll' });

 

需要保持水平滚动条,则:

    $( pGridId ).closest(".ui-jqgrid-bdiv").css({ 'overflow-x' : 'scroll' });

 

 

 

 

03.控制列的水平宽度

 

当表字段比较多时,如果按照colModel指定的宽度,整个jqGrid宽度会太宽,我们通常希望控制一下grid的宽度,并同时保持各列的指定宽度。

可以指定jgrid的参数 shrinkToFit:false shrinkToFit属性用来说明当初始化列宽度时候的计算类型,如果为ture,则按比例初始化列宽度。如果为false,则列宽度使用colModel指定的宽度。

同时需要控制jqgrid的宽度。通过autowidth:true属性可以达到目地。

 

04. 高度随记录数自动变化.

 

使用 height: 'auto' 参数 .

 

不理想的是,在IE6中,当字段比较多并出现水平滚动条时,感觉会比较难受。参考保持垂直滚动条的办法,保持一个水平滚动条,高度是对了。( 使用的Firefox3.6没发现这个问题, 所以说IE比较烂并不是空穴来风 )

 

 

Js代码

  1. if($.browser.msie) {      
  1.     // 保持垂直滚动条   
  1.     // $( pGridId ).closest(".ui-jqgrid-bdiv").css({ 'overflow-y' : 'scroll' });    
  2.     // 保持水平滚动条  
  3.     $( pGridId ).closest(".ui-jqgrid-bdiv").css({ 'overflow-x' : 'scroll' });    
  4. }  

  

 

 

 

 

05. jqgrid 和 validation 插件一起使用的问题

 

在提交表单的时候,会报错:'settings' is null or not an object.  'setting'为空或不是对象

 

http://www.trirand.com/blog/?page_id=393/help/jqgrid-validation-plugin-issue/ 有这样的问题报告,

 

目前还是有这样的问题。

 

 

06. 动态修改 jqgrid 提交的参数 

 

具体的说明可以参考 http://www.trirand.com/jqgridwiki/doku.php?id=wiki:post_data_module  

 

这里举个例子:当你需要根据用户的输入过滤 jqgrid 的显示数据,可以这样实现,

 

Js代码

  1. userName = $( '#userName' ).val( );   // input 的值  
  1.   
  1. userCode =  $( '#userCode' ).val( );   // input 的值  
  2.   
  1. jQuery('#grid_user').appendPostData( { userName :userName , userCode :userCode }   
  1.   
  2. 这样,刷新 grid 数据时,提交到服务器的数据将包含这 userName 和 userCode两项。  

  

 

07. Editing form 提交时,动态添加数据项 

 

在以 Form Editing 方式添加或修改数据,如何在提交时动态的添加或修改一些项目呢?

 

一个典型的例子是添加文章记录时,在提交的数据中添加当前时间这个项目。

 

参考 http://www.trirand.com/jqgridwiki/doku.php?id=wiki:form_editing 可以知道:

 

在表单提交前,将触发事件 beforeSubmit 所以我们可以在这个事件里做些事情。

 

Js代码

  1. // 提交前  
  1. fn_beforeSubmit = function( postdata, formid ) {   
  1.     // 添加或修改 postdata 项目值             
  1.     postdata[ 'uploadDate' ] = new Date().format("yyyy/MM/dd") ;    
  1.     postdata[ 'uploadTime' ] = new Date().format("hh:mm:ss") ;    
  1.                                           
  1.     return[true,''];   // 提交  
  1.                           
  1. };  
  1.   
  1. // 添加记录 options   
  2. Options_add = {  
  3.         width:500,  
  4.         height:290,  
  5.         reloadAfterSubmit:true,  
  1.         jqModal:true,   
  1.         beforeSubmit:       fn_beforeSubmit,  
  1.         ......  
  2. }  
  3.   
  1. // 配置 jqgrid nav  
  2. jQuery( pGridId ).jqGrid('navGrid',pPageId, {edit:true,add:true,del:true,search:false,refresh:true,view:true,addtext:'添加',edittext:'修改',deltext:'删除' }, //options   
  1.         {height:290,reloadAfterSubmit:false, jqModal:true, closeOnEscape:true, bottominfo:"标记有*的字段不能为空"}, // edit options   
  1.         Options_add, // add options   
  1.         {reloadAfterSubmit:false,jqModal:true, closeOnEscape:true }, // del options   
  1.         {closeOnEscape:true}, // search options   
  1.         {height:250,jqModal:false,closeOnEscape:true} // view options   
  1.     );   

  

 

 

08.  Editing form 中上传文件 

 

待续 ......

 

 

 

09.  不显示中间的分页器或右边的记录信息 

 

通过 FireBug可以发现 jqgrid  pager中各部分的命名规则: pager id + _left/_center/_right

 

pPageId = '#pager_grid' ;

$( pPageId + "_center" ).remove( );    // 删除中间分页器

 

 

另外,也可以通过控制 css 实现。

 

参考:

 jqgrid  Tips, Tricks and Hacks -  To use the nav bar for buttons but hide the pager, using CSS

10 JQGrid Tips learned from my experience - tip5,tip6

 

 

10.  取得记录行序号 

 

jqGrid提供的方法一般只能取得记录的 id 号。使用 $('#jqgrid1').jqGrid('getDataIDs') 方法可以获得各行的id数组,此数组相应元素的索引号就是记录行序号了(0开始)

 

可以参考:

http://www.trirand.com/blog/?page_id=393/help/to-get-the-rowid-of-the-nth-row-of-the-grid/

 

Found the answer using $('#gridmain').jqGrid('getDataIDs');

It will return an array of ids for the visible grid.

So to get the nth rowid, i use:

var rids = $('#gridmain').jqGrid('getDataIDs');

var nth_row_id = rids[n-1]; //bec the row array starts from zero.

Hope it will help others, if interested.

 

 

 

 

 

其他参考:

 

10 JQGrid Tips learned from my experience

http://veechand.wordpress.com/2009/07/13/10-jqgrid-tips-learned-from-my-experience/

 

 

jqGrid and JQuery UI tabs showing grids expanded only on primary tab (div)

 

 

http://stackoverflow.com/questions/2117687/jqgrid-and-jquery-ui-tabs-showing-grids-expanded-only-on-primary-tab-div

 

 

源文档 <http://forestkqq.javaeye.com/blog/602944>

用 Javascript 获取指定页面元素的位置 - top, left, document, Element, 元素, position, 位置

 

 Javascript 获取指定页面元素的位置是一个非常常见的需求,本文介绍的方法能够准确返回一个元素相对于整个文档左上角的坐标,即元素的 top left 的位置,而且能够兼容浏览器,相信对新手非常有用。

 

 

--------------------------------------------------------------

点此浏览示例文件

--------------------------------------------------------------

 

 

Javascript:

 

  1.  
  2. <script language="JavaScript" type="text/javascript">
  3. <!--
  1.  
  1. // 说明:用 Javascript 获取指定页面元素的位置
  2. // 整理:http://www.codebit.cn
  3. // 来源:YUI DOM
  1.  
  1. function getElementPos(elementId) {
  1.  
  1. var ua = navigator.userAgent.toLowerCase();
  2. var isOpera = (ua.indexOf('opera') != -1);
  3. var isIE = (ua.indexOf('msie') != -1 && !isOpera); // not opera spoof
  1.  
  1. var el = document.getElementById(elementId);
  1.  
  1. if(el.parentNode === null || el.style.display == 'none') 
  1. {
  1. return false;
  1. }
  1.  
  1. var parent = null;
  2. var pos = [];
  1. var box;
  1.  
  1. if(el.getBoundingClientRect)    //IE
  1. {
  1. box = el.getBoundingClientRect();
  1. var scrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
  2. var scrollLeft = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);
  1.  
  1. return {x:box.left + scrollLeft, y:box.top + scrollTop};
  1. }
  1. else if(document.getBoxObjectFor)    // gecko
  1. {
  1. box = document.getBoxObjectFor(el);
  1. var borderLeft = (el.style.borderLeftWidth)?parseInt(el.style.borderLeftWidth):0;
  1. var borderTop = (el.style.borderTopWidth)?parseInt(el.style.borderTopWidth):0;
  1.  
  1. pos = [box.x - borderLeft, box.y - borderTop];
  1. }
  1. else    // safari & opera
  1. {
  1. pos = [el.offsetLeft, el.offsetTop];
  1. parent = el.offsetParent;
  1. if (parent != el) {
  2. while (parent) {
  1. pos[0] += parent.offsetLeft;
  2. pos[1] += parent.offsetTop;
  3. parent = parent.offsetParent;
  1. }
  1. }
  1. if (ua.indexOf('opera') != -1 
  1. || ( ua.indexOf('safari') != -1 && el.style.position == 'absolute' )) 
  1. {
  1. pos[0] -= document.body.offsetLeft;
  1. pos[1] -= document.body.offsetTop;
  1. } 
  2. }
  1. if (el.parentNode) { parent = el.parentNode; }
  1. else { parent = null; }
  1. while (parent && parent.tagName != 'BODY' && parent.tagName != 'HTML') 
  1. { // account for any scrolled ancestors
  1. pos[0] -= parent.scrollLeft;
  1. pos[1] -= parent.scrollTop;
  1. if (parent.parentNode) { parent = parent.parentNode; } 
  1. else { parent = null; }
  1. }
  1. return {x:pos[0], y:pos[1]};
  1. }
  1.  
  1. //-->
  1. </script>
  1.  

 

从 <http://www.codebit.cn/pub/html/javascript/tip/get_element_position/> 插入