var ie = document.all;
var moz = document.getElementById && !document.all;
var intr;

function Message_UpdatePos(msg, dy) ...{
var el = document.getElementById(msg);
if (ie) ...{
el.style.pixelTop = document.body.scrollTop + dy;
}
else if (moz) ...{
el.style.top = window.pageYOffset + dy + ‘px‘;
}
}

function Message_Display(msg, vis, dx, dy) ...{
var el = document.getElementById(msg);
// Position Message

if (ie) ...{
el.style.pixelTop = document.body.scrollTop + dy;
el.style.pixelLeft = document.body.clientWidth - dx;
}
else if (moz) ...{
el.style.top = window.pageYOffset + dy + ‘px‘;
el.style.left = window.innerWidth - dx + ‘px‘;
}
if (vis) ...{ // and display it
el.style.visibility = "visible";
intr = setInterval("Message_UpdatePos(‘" + msg + "‘, " + dy + ")", 1);
}
else ...{ // or hide it
el.style.visibility = "hidden";
if (intr)
clearInterval(intr);
}
}
<span id="testmsg" style="position: absolute;
visibility: hidden; background: red;">This is a test…</span>
onclick="Message_Display(‘testmsg‘, 1, 700, 50); return false;"
onclick="Message_Display(‘testmsg‘, 0, 700, 50); return false;"For menu click here:
这个样例更加复杂是由于它包括了一个JavaScript函数和一些更加复杂的事件处理。以下是用到的JavaScript代码和HTML:
function getElementAbsPosX(el)
...{
var dx = 0;
if (el.offsetParent) ...{
dx = el.offsetLeft + 8;
while (el = el.offsetParent) ...{
dx += el.offsetLeft;
}
}
return dx;
}
function getElementAbsPosY(el)
...{
var dy = 0;
if (el.offsetParent) ...{
dy = el.offsetTop + el.offsetHeight / 2;
while (el = el.offsetParent) ...{
dy += el.offsetTop;
}
}
return dy;
}
function GetAbsWindowBottom()
...{
// Compute the bottom of the popup window and the bottom of
// the browser window, in absolute co-ordinates - different
// on all browsers but the below should be accurate usually!
var abswindowbottom = 0;
if (typeof(window.innerHeight) == ‘number‘)
abswindowbottom = window.innerHeight;
else if (document.documentElement && document.documentElement.clientHeight)
abswindowbottom = document.documentElement.clientHeight;
else if (document.body && document.body.clientHeight)
abswindowbottom = document.body.clientHeight;
if (typeof(window.pageYOffset) == ‘number‘)
abswindowbottom = abswindowbottom + window.pageYOffset;
else if (document.body && document.body.scrollTop)
abswindowbottom = abswindowbottom + document.body.scrollTop;
else if (document.documentElement && document.documentElement.scrollTop)
abswindowbottom = abswindowbottom + document.documentElement.scrollTop;
return abswindowbottom;
}
function PopupMenu(name, vis)
...{
var el = name + ‘menu‘;
var tag = name + ‘menuroot‘;
if (!document.getElementById(el)) // menu object not found
return;
if (vis == 0) ...{ // hide the menu
document.getElementById(el).style.visibility = ‘hidden‘;
return;
}
// Get menuroot position
var pos = document.getElementById(tag);
var dx = getElementAbsPosX(pos);
var dy = getElementAbsPosY(pos);
// Compare bottom of menu to bottom of window
var abspopupbottom = dy + document.getElementById(el).clientHeight + 10;
var abswindowbottom = GetAbsWindowBottom();
// If menu goes below bottom of window, move it up!
if (abspopupbottom > abswindowbottom)
dy = dy - (abspopupbottom - abswindowbottom);
// Set final menu position and make it appear
document.getElementById(el).style.left = dx + ‘px‘;
document.getElementById(el).style.top = dy + ‘px‘;
if (vis > 0)
document.getElementById(el).style.visibility = ‘visible‘;
}
<div id="testmenu" style="position: absolute; visibility: hidden; color: #aaaaaa; font-style: italic; border: solid thin #888;
background-color: #afafaf; padding: 4px;" onmouseover="clearTimeout(tout);" onmouseout="tout=setTimeout(‘PopupMenu(‘test‘, 0);‘, 1500);">
<table>
<tr>
<td><span style="cursor:pointer; color:blue;" onclick="PopupMenu(‘test‘, 0);">Menu Item #1</span></td>
</tr>
<tr>
<td><span style="cursor:pointer; color:blue;" onclick="PopupMenu(‘test‘, 0);">Menu Item #2</span></td>
</tr>
<tr>
<td><span style="cursor:pointer; color:blue;" onclick="PopupMenu(‘test‘, 0);">Menu Item #3</span></td>
</tr>
</table>
</div>
<span id="testmenuroot" style="cursor:pointer; color:blue;"
onclick="PopupMenu(‘test‘, 1); tout=setTimeout(‘PopupMenu
(‘test‘, 0);‘, 1500);" >X</span> 首先,我们来看一下菜单。我们能够在div标签中放置不论什么我们喜欢的东西,全部的秘密都在div标签的属性中。特别须要注意的,和前面的样例一样,我们使用绝对定位,所以无论其它文本和图片出现的位置,我们都能够控制菜单的确切位置。我们还要确保菜单開始时visiblity:hidden,而且分配了ID testmenu,这样我们就能够在后面非常easy获得一个句柄。
在div标签中,我们还会遇到setTimeout和clearTimeout函数的第一次使用。它们和上例中的setInterval函数的行为相似,仅仅只是它们在某段时间后仅仅运行一个命令一次。在本例中,它们用来在鼠标移出菜单区域1500毫秒后关闭菜单,或者鼠标又一次移回到菜单区域时(假设仍然处于打开状态)取消退出效果。tout是在JavaScript文件里定义的一个全局变量,用来保存定时器对象的指针。当触发onmouseout事件时(鼠标移动由div标签指定的菜单区域之外)PopMenu(‘test‘, 0)被设定为在1500毫秒后调用(注意我们是怎样转移引號的,由于它们已经在引號之内)。假如在1500毫秒耗尽之前动作没有被取消,这个函数就会被调用,菜单就会消失(就像我们在以下将要看到的那样)。然后,假设onmouseover时间被触发(鼠标移动到菜单上),clearTimeout(tout)就会运行,它会阻止取消定时器,阻止菜单消失,直到用户触发下一次鼠标事件。
在菜单自身内部,我们会包括一些运行其它任务或跳转其它页面的链接。当然,本例中仅仅是一些虚假的链接。然而,注意每个菜单项的onclick事件。在div标签上面,一点击菜单项菜单就会消失(试一下!)。注意,这里没有使用timeout,由于我们想在这样的情况下菜单马上消失。
接下来是由id为testmenuroot的span标签包括的一段HTML代码,表示了菜单实际出现的点击区域。在本例总,我们仅仅是在span标签中间放置了一个X字母,当然,你能够在这里放你喜欢的不论什么东西:button、图片等等。须要注意的另外一个事情是onclick时间,它使菜单显示,而且设置定时器以在1500ms后关闭菜单。然而,我们已经仅仅要用户移动鼠标到菜单区域,定时器就会被取消,而且菜单会一直显示,直到下次鼠标移走。
最后,我们来看JavaScript函数本身,PopupMenu。它依赖的函数有:GetAbsWindowBottom,获得浏览器底部的绝对位置;getElementAbsPosX和getElementAbsPoxY,获得一个元素在绝对坐标系中的x和y位置。最后两个的计算方式是通过迭代加上父元素的偏移量,直到DocumentRoot。这些函数看起来有些过于复杂了,可是它们极有可能是在差点儿每个流行的浏览器上获得这些信息的唯一方式。不幸的是,每个浏览器都使用一个非常不同的方式保存这些信息。
PopupMenu函数有两个输入參数:name和一个表示菜单应该显示或隐藏的标志。关于name,假设菜单被一个标签包围形成,其id由name參数加上“menu”组成(那么在我们的样例中就是“testmenu”,由于參数为“test”)。相似地,假设菜单的左上角定位在id为name加“menuroot”的标签(本例中为“testmenuroot”)上。假设vis參数是0,我们仅仅须要把菜单标签的visibility的样式设置为hidden。否则,我们须要使菜单出如今右側的位置上。首先,我们使用GetElementAbsPos函数获得“menuroot”标签的绝对位置。然后,我们能够把菜单的位置设置为这些值,这就能够让菜单的左上角出如今我们点击以使其弹出的位置。然而,我们还不希望菜单滚动出页面的底端,由于这是非常令人讨厌的。注意多数包括弹出式菜单的widget toolkits都仅仅实现上面的功能,所以我们将尝试实现一个更好的。我们能够计算出绝对坐标系中窗体以及弹出菜单的底部位置,接下来的两行代码完毕了这个任务。注意,菜单的高度由clientHeight属性给出,我们再加上10以使和页面底部留下一些空间。然后我们能够检查弹出菜单是否已经向下超出了浏览器窗体的底部,假设是这样,就会对应地调整它的坐标,如此它的底部就会刚刚接触窗体的底部。最后,我们接着向下看,就是定位弹出式菜单,并使其可见。
总结(Summary)
但愿,这次讨论和这两个样例能够让你领略到使用仅仅几行JavaScript代码就能够完毕的事情,而且揭示了在JavaScript工具内部并没有非常多非常多的魔法。虽然有时候有些棘手,可是通常仅仅须要额外的一点工作来确保函数能够在全部的主流浏览器上运行,而且这些小小的额外付出差点儿永远是值得的。在后面的文章中,将会讨论更加具体的JavaScript widget的演示样例。
Howard Feldman是在位于Montreal, Quebec的Chemical Computing Group一名研究科学家。
原文:http://www.cnblogs.com/yxwkf/p/3812701.html