A-A+
javascript实现定位并且可拖动的弹出框
实现弹出一个框,这个框是出现在超链接或按钮附近的,即可以给框定位,也可以随意拖拽,代码如下 第一种情况就是ie下获取scrollTop/scrollLeft值,最典型的就是文档类型,DOCTYPE ,不同取值方式不同,兼容各浏览器实现
如下:
- function getScrollXY() {
- var scrOfX = 0, scrOfY = 0;
- if( typeof( window.pageYOffset ) == 'number' ) {
- //Netscape compliant
- scrOfY = window.pageYOffset;
- scrOfX = window.pageXOffset;
- } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
- //DOM compliant
- scrOfY = document.body.scrollTop;
- scrOfX = document.body.scrollLeft;
- } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
- //IE6 standards compliant mode
- scrOfY = document.documentElement.scrollTop;
- scrOfX = document.documentElement.scrollLeft;
- }
- return [ scrOfX, scrOfY ];
- }
主要是关注document.documentElement.scrollTop和document.body.scrollTop应用场景。
第二种情况就是获取页面某个元素的位置,指标top/left值,普遍的方案如下:
- var getPosition = function(obj){
- var pos = [0,0];
- if(obj.offsetParent){
- while(obj.offsetParent){
- pos[0] += obj.offsetTop;
- pos[1] += obj.offsetLeft;
- obj = obj.offsetParent;
- }
- }
- return pos;
- }
传入一个页面元素对象,获取当前对象在页面中的位置top和left。通过循环offsetParent获取offsetTop和 offsetLeft值。
其实在实际应用中还有很多问题,如弹出框浮动,漂浮等,先了解一下这两种情况,继续完善,第三种获取元素位置与定位方法,性能更高,浏览器兼容性更强,高度推荐。
- var getPosition = function(el){
- var ua = navigator.userAgent.toLowerCase();
- var isOpera = (ua.indexOf('opera') != -1);
- var isIE = (ua.indexOf('msie') != -1 && !isOpera); // not opera spoof
- if(el.parentNode === null || el.style.display == 'none')
- {
- return false;
- }
- var parent = null;
- var pos = [];
- var box;
- if(el.getBoundingClientRect) //IE
- {
- box = el.getBoundingClientRect();
- var scrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
- var scrollLeft = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);
- return {x:box.left + scrollLeft, y:box.top + scrollTop};
- }
- else if(document.getBoxObjectFor) // gecko
- {
- box = document.getBoxObjectFor(el);
- var borderLeft = (el.style.borderLeftWidth)?parseInt(el.style.borderLeftWidth):0;
- var borderTop = (el.style.borderTopWidth)?parseInt(el.style.borderTopWidth):0;
- pos = [box.x - borderLeft, box.y - borderTop];
- }
- else // safari & opera
- {
- pos = [el.offsetLeft, el.offsetTop];
- parent = el.offsetParent;
- if (parent != el) {
- while (parent) {
- pos[0] += parent.offsetLeft;
- pos[1] += parent.offsetTop;
- parent = parent.offsetParent;
- }
- }
- if (ua.indexOf('opera') != -1
- || ( ua.indexOf('safari') != -1 && el.style.position == 'absolute' ))
- {
- pos[0] -= document.body.offsetLeft;
- pos[1] -= document.body.offsetTop;
- }
- }
- if (el.parentNode) { parent = el.parentNode; }
- else { parent = null; }
- while (parent && parent.tagName != 'BODY' && parent.tagName != 'HTML')
- { // account for any scrolled ancestors
- pos[0] -= parent.scrollLeft;
- pos[1] -= parent.scrollTop;
- if (parent.parentNode) { parent = parent.parentNode; }
- else { parent = null; }
- }
- return {x:pos[0], y:pos[1]};
完整实例,代码如下:
- popup(showid,contents,isbox,divleft);
- /**
- * 显示弹出框
- * @param string id
- * @param string contents:弹出框的内容
- * @param int isbox
- * @param int divleft
- */
- function popup(showid, contents, isbox, divleft)
- {
- var jsmenu = new Array();
- jsmenu['active'] = new Array();
- if(isUndefined(isbox)) isbox = 0;
- if(isUndefined(divleft)) divleft = 0;
- var offset = 0;
- var div = $(showid + "_menu");
- if(div)
- {
- div.parentNode.removeChild(div);
- }
- div = document.createElement('div');
- div.id = showid + "_menu";
- div.style.position = 'absolute';
- if(isbox)
- {
- divclass = 'popupmenu_centerbox';
- offset = -1;
- }
- else
- {
- divclass = 'popupmenu_popup';
- }
- if(iserrortipbox)
- {
- divclass = 'popupmenu_inner';
- }
- div.className = divclass;
- div.style.display = '';
- $('append_parent').appendChild(div);
- div.innerHTML = "<div style='width: 200px;'>" + contents + "</div>";
- jsmenu['active'][0] = div;
- $('append_parent').appendChild(div);
- //定位弹出框
- setPopupPosition(showid, offset, divleft);
- }
- /**
- * 定位弹出框
- * @param string showid:显示弹出框的id
- * @param int offset: 这个参数有四种情况,默认值为:0
- * offset= -1 :弹出框会出现在屏幕中央位置
- * offset=1 :弹出框的右上角在鼠标点击位置附近,但垂直位置始终保持在鼠标的下方
- * offset=2 :弹出框的右上角在鼠标点击位置附近,但垂直位置始终保持在鼠标的上方
- * offset=其它值:弹出框的右上角在鼠标点击位置附近,但垂直位置会根据滚动条位置判断,
- * @param int divleft
- */
- function setPopupPosition(showid, offset, divleft)
- {
- var showobj = $(showid);
- var menuobj = $(showid + '_menu');
- if(isUndefined(offset)) offset = 0;
- if(showobj)
- {
- showobj.pos = fetchOffset(showobj);
- showobj.X = showobj.pos['left'];
- showobj.Y = showobj.pos['top'];
- showobj.w = showobj.offsetWidth;
- showobj.h = showobj.offsetHeight;
- menuobj.w = menuobj.offsetWidth;
- menuobj.h = menuobj.offsetHeight;
- var sTop = document.documentElement && document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
- if(offset != -1)
- {
- menuobj.style.left = (showobj.X + menuobj.w > document.body.clientWidth) && (showobj.X + showobj.w - menuobj.w
- >= 0) ? showobj.X + showobj.w - menuobj.w + 'px' : (showobj.X - divleft) + 'px';
- menuobj.style.top = offset == 1 ? showobj.Y + 'px' : (offset == 2 || ((showobj.Y + showobj.h + menuobj.h > sTop + document.documentElement.clientHeight) && (showobj.Y - menuobj.h >= 0)) ? (showobj.Y - menuobj.h) + 'px' : showobj.Y + showobj.h + 'px');
- }
- else if(offset == -1)
- {
- menuobj.style.left = (document.body.clientWidth-menuobj.w)/2 + 'px';
- if (document.documentElement.clientHeight > menuobj.h + 300)
- {
- var divtop = sTop + (document.documentElement.clientHeight-menuobj.h)/2;
- if(divtop > 100) divtop = divtop - 100;
- }
- else
- {
- divtop = 100;
- }
- menuobj.style.top = divtop + 'px';
- }
- if(menuobj.style.clip && !is_opera)
- {
- menuobj.style.clip = 'rect(auto, auto, auto, auto)';
- }
- }
- menuobj.onmousedown = function(event) {try{popupdrag(menuobj, event, 1);}catch(e){}};
- document.body.onmousemove = function(event) {try{popupdrag(menuobj, event, 2);}catch(e){}};
- menuobj.onmouseup = function(event) {try{popupdrag(menuobj, event, 3);}catch(e){}};
- }
- /**
- * 拖动弹出框
- * @param obj 可拖动的对象
- * @param e event
- * @param int op 1:表示onmousedown 2:表示onmousemove 3:表示onmouseup
- */
- var menudragstart = new Array();
- function popupdrag(menuobj, e, op)
- {
- if(op == 1)
- {
- if(in_array(is_ie ? event.srcElement.tagName : e.target.tagName, ['TEXTAREA', 'INPUT', 'BUTTON', 'SELECT']))
- {
- return;
- }
- menudragstart = is_ie ? [event.clientX, event.clientY] : [e.clientX, e.clientY];
- menudragstart[2] = parseInt(menuobj.style.left);
- menudragstart[3] = parseInt(menuobj.style.top);
- doane(e);
- }
- else if(op == 2 && menudragstart[0])
- {
- var menudragnow = is_ie ? [event.clientX, event.clientY] : [e.clientX, e.clientY];
- menuobj.style.left = (menudragstart[2] + menudragnow[0] - menudragstart[0]) + 'px';
- menuobj.style.top = (menudragstart[3] + menudragnow[1] - menudragstart[1]) + 'px';
- doane(e);
- }
- else if(op == 3)
- {
- menudragstart = [];
- doane(e);
- }
- }
- /**
- * @param event
- */
- function doane(event)
- {
- e = event ? event : window.event;
- if(is_ie)
- {
- //e.returnValue设置为false的时候可以组织浏览器执行默认的事件动作,同e.preventDefault();
- e.returnValue = false;
- //e.cancelBubble把它设置为true的时候,将停止事件进一步起泡到包容层次的元素,同e.stopPropagation();
- e.cancelBubble = true;
- }
- else if(e)
- {
- e.stopPropagation();
- e.preventDefault();
- }
- }
- /**
- * 获取定位
- * @param obj
- */
- function fetchOffset(obj)
- {
- var left_offset = obj.offsetLeft;
- var top_offset = obj.offsetTop;
- while((obj = obj.offsetParent) != null)
- {
- left_offset += obj.offsetLeft;
- top_offset += obj.offsetTop;
- }
- return { 'left' : left_offset, 'top' : top_offset };
- }
太专业的东西,菜鸟看得懂,慢慢学习了,经常来
建议把运行效果截个图附上,访客能够一眼看到这个效果是不是自己所需要的