Description
This script creates a DHTML popup window that can be moved around the screen, resized, and closed. Multiple windows may also be used, and the layer presidence will be set by the last window to have been clicked on. It will also degrade well, by continuing to work in older browsers, and browsers that do not have JavaScript enabled. One day, I'll document it better, but until then, just look at what I've done, and do the same thing. ;)
Demonstration
Open Web Dev FAQs
-- possibly opens below the visible screen (see known bugs)
Open W3C
Known Bugs
The popup will "stick" to the cursor when you try to move it in Opera 7, and there is no way to close it. In other browsers, a centered popup will open in the middle of the document, rather than the visible window.
Implementation
Here is the code used to open the popup in the two example above:
<a href="http://www.webdevfaqs.com" onclick="openpopup(this.href,'','','','','center'); return false;">Open Web Dev FAQs</a>
<a href="http://www.w3c.org" onclick="openpopup(this.href,'600','400','100','100',''); return false;">Open W3C</a>
This part: openpopup(this.href,'600','400','100','100','center'); works in this order:
The link to open (current links href)
The width
The height
The position from the left
The position from the top
Center the window
Code
<script type="text/javascript"> /*##################################################### # This script is Copyright 2003, Infinity Web Design # # Written by Ryan Brill - ryan@infinitypages.com # # All Rights Reserved - Do not remove this notice # #####################################################*/ x = 50; //z-index var mainwin = new Array(); //array for popups function beginDrag(elementToDrag, event) { for (i=0; i<mainwin.length; i++) { // loop through the windows if (x<mainwin[i].style.zIndex) { // if x is less than the current z-index of the window it is currently looping through x = mainwin[i].style.zIndex; // set x to the highest z-index of the windows } } elementToDrag.style.zIndex = x+1; // set z-index to be one more than highest z-index for windows elementToDrag.childNodes[1].style.display = "block"; var deltaX = event.clientX - parseInt(elementToDrag.style.left); var deltaY = event.clientY - parseInt(elementToDrag.style.top); if (document.addEventListener) { document.addEventListener("mousemove", moveHandler, true); document.addEventListener("mouseup", upHandler, true); } else if (document.attachEvent) { document.attachEvent("onmousemove", moveHandler); document.attachEvent("onmouseup", upHandler); } else { var oldmovehandler = document.onmousemove; var olduphandler = document.onmouseup; document.onmousemove = moveHandler; document.onmouseup = upHandler; } if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; if (event.preventDefault) event.preventDefault(); else event.returnValue = false; function moveHandler(e) { if (!e) e = window.event; winwidth = document.body.scrollWidth; winheight = document.body.scrollHeight; if (e.clientX - deltaX < 2) { //don't allow past left of screen leftpos = 2; } else if (e.clientX - deltaX > winwidth - parseInt(elementToDrag.style.width)) { //don't allow past right of screen leftpos = winwidth - parseInt(elementToDrag.style.width) - 3; } else { leftpos = e.clientX - deltaX; } if (e.clientY - deltaY < 2) { //don't allow past top of screen toppos = 2; } else if (e.clientY - deltaY > winheight - parseInt(elementToDrag.style.height)) { // don't allow past bottom of screen toppos = winheight - parseInt(elementToDrag.style.height) - 3; } else { toppos = e.clientY - deltaY; } elementToDrag.style.left = leftpos + "px"; //set left position of div elementToDrag.style.top = toppos + "px"; //set top position of div return false; if (e.stopPropagation) e.stopPropagation(); else e.cancelBubble = true; } function upHandler(e) { if (!e) e = window.event; if (document.removeEventListener) { document.removeEventListener ("mouseup", upHandler, true); document.removeEventListener ("mousemove", moveHandler, true); } else if (document.detachEvent) { document.detachEvent ("onmouseup", upHandler); document.detachEvent ("onmousemove", moveHandler); } else { document.onmouseup = olduphandler; docuemnt.onmousemove = oldmovehandler; } if (e.stopPropagation) e.stopPropagation(); else e.cancelBubble = true; elementToDrag.childNodes[1].style.display = "none"; } } function beginResize(elementToResize, event) { elementToResize.childNodes[1].style.display = "block"; var deltaX = event.clientX - parseInt(elementToResize.style.width); var deltaY = event.clientY - parseInt(elementToResize.style.height); if (document.addEventListener) { document.addEventListener("mousemove", resizeHandler, true); document.addEventListener("mouseup", resizeUpHandler, true); } else if (document.attachEvent) { document.attachEvent("onmousemove", resizeHandler); document.attachEvent("onmouseup", resizeUpHandler); } else { var oldresizehandler = document.onmousemove; var oldresizeuphandler = document.onmouseup; document.onmousemove = resizeHandler; document.onmouseup = resizeUpHandler; } if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; if (event.preventDefault) event.preventDefault(); else event.returnValue = false; function resizeHandler(e) { if (!e) e = window.event; elementToResize.style.width = (e.clientX - deltaX) + "px"; //set width of div elementToResize.style.height = (e.clientY - deltaY) + "px"; //set height of div elementToResize.childNodes[1].style.width = (e.clientX - deltaX - 2) + "px"; elementToResize.childNodes[1].style.height = (e.clientY - deltaY - 32) + "px"; elementToResize.childNodes[2].style.width = (e.clientX - deltaX - 2) + "px"; elementToResize.childNodes[2].style.height = (e.clientY - deltaY - 32) + "px"; return false; if (e.stopPropagation) e.stopPropagation(); else e.cancelBubble = true; } function resizeUpHandler(e) { if (!e) e = window.event; if (document.removeEventListener) { document.removeEventListener ("mouseup", resizeUpHandler, true); document.removeEventListener ("mousemove", resizeHandler, true); } else if (document.detachEvent) { document.detachEvent ("onmouseup", resizeUpHandler); document.detachEvent ("onmousemove", resizeHandler); } else { document.onmouseup = oldresizeuphandler; docuemnt.onmousemove = oldresizehandler; } if (e.stopPropagation) e.stopPropagation(); else e.cancelBubble = true; elementToResize.childNodes[1].style.display = "none"; } } function openpopup(url,winwidth,winheight,winleft,wintop,center) { if (document.layers) { //NN windowwidth = window.innerWidth; //get window width windowheight = window.innerHeight; //get window height } else { //IE windowwidth = document.body.clientWidth; //get window width windowheight = document.body.clientHeight; //get window height } if (winwidth == undefined || winwidth == "") { winwidth = "400"; } if (winheight == undefined || winheight == "") { winheight = "300"; } if (wintop == undefined || wintop == "") { wintop = "0"; } if (winleft == undefined || winleft == "") { winleft = "0"; } if (center == "center") { wintop = (windowheight/2) - (winheight/2); winleft = (windowwidth/2) - (winwidth/2); } for (i=0; i<mainwin.length; i++) { // loop through the windows if (x<mainwin[i].style.zIndex) { // if x is less than the current z-index of the window it is currently looping through x = mainwin[i].style.zIndex; // set x to the highest z-index of the windows } } mainwin[mainwin.length] = document.createElement("div"); mainwin[mainwin.length-1].style.position = "absolute"; mainwin[mainwin.length-1].style.top = wintop +"px"; mainwin[mainwin.length-1].style.left = winleft +"px"; mainwin[mainwin.length-1].style.width = winwidth +"px"; mainwin[mainwin.length-1].style.height = winheight +"px"; mainwin[mainwin.length-1].style.border = "1px solid"; mainwin[mainwin.length-1].style.zIndex = x+1; document.body.appendChild(mainwin[mainwin.length-1]); mainwin[mainwin.length-1].innerHTML = ""+ "<div style=\"background:#dddddd;\" onmousedown=\"beginDrag(this.parentNode, event);\">"+ "<span style=\"padding-left: 5px; cursor:default; font-family: verdana; font-weight: bold;\">"+ "<span style=\"font-size: 12px;\">"+url+""+ "</span>"+ "</span>"+ "<span style=\"position: relative; top: -19px; float: right; background: transparent;\" onclick=\"closepopup(this.parentNode.parentNode);\">"+ "<img src=\"required/close.png\" name=\"closebutton\" onmouseover=\"document.closebutton.src='required/closeon.png';\" onmouseout=\"document.closebutton.src='required/close.png';\">"+ "</span>"+ "</div>"+ "<div style=\"position: absolute; top: 18px; height: "+(winheight-32)+"px; width: "+(winwidth - 2)+"px; z-index:2; background-image:url(fake.gif); display:none;\">"+ "</div>"+ "<iframe src=\""+url+"\" style=\"position: absolute; top: 18px; height: "+(winheight-32)+"px; width: "+(winwidth - 2)+"px; overflow:auto; z-index:1\">"+ "</iframe>"+ "<span style=\"position: absolute; bottom: 0px; width: 100%; background: #dddddd; color: white; font-family: arial; font-weight: bold; z-index:3;\" onmouseover=\"this.style.cursor='nw-resize';\" onmousedown=\"beginResize(this.parentNode, event);\">"+ "<span style=\"float:right;\"><img src=\"required/resize.png\"></span>"+ "</span>"; } function closepopup(elementToClose) { mainwin.splice(elementToClose,1); document.body.removeChild(elementToClose); } </script>
Tested in: IE6, Opera 7, NN4.7, NN7, and Mozilla 1.4.
Works or degrades well in: IE6, NN4.7, NN7, and Mozilla 1.4.
Doesn't or doesn't degrade work in: Opera 7
Comments: Works best in Mozilla, as this is the most DOM compliant browser.
Copyright© 2003, Infinity Web Design