/* * MojoMagnify 0.1.5 - JavaScript Image Magnifier * Copyright (c) 2008 Jacob Seidelin, cupboy@gmail.com, http://blog.nihilogic.dk/ * Licensed under the MPL License [http://www.nihilogic.dk/licenses/mpl-license.txt] */ var MojoMagnify = (function() { var $ = function(id) {return document.getElementById(id);}; var dc = function(tag) {return document.createElement(tag);}; function addEvent(element, ev, handler) { var doHandler = function(e) { return handler(e||window.event); } if (element.addEventListener) { element.addEventListener(ev, doHandler, false); } else if (element.attachEvent) { element.attachEvent("on" + ev, doHandler); } } function getElementPos(element) { var x = element.offsetLeft; var y = element.offsetTop; var parent = element.offsetParent; while (parent) { x += parent.offsetLeft; y += parent.offsetTop; parent = parent.offsetParent; } return { x : x, y : y } } function getEventMousePos(element, e) { var scrollX = document.body.scrollLeft || document.documentElement.scrollLeft; var scrollY = document.body.scrollTop || document.documentElement.scrollTop; if (e.currentTarget) { var pos = getElementPos(element); return { x : e.clientX - pos.x + scrollX, y : e.clientY - pos.y + scrollY } } return { x : e.offsetX, y : e.offsetY } } function makeMagnifiable(img, zoomSrc) { // make sure the image is loaded, if not then add an onload event and return if (!img.complete && !img.__mojoMagnifyQueued) { addEvent(img, "load", function() { img.__mojoMagnifyQueued = true; setTimeout(function() { makeMagnifiable(img, zoomSrc); }, 1); }); return; } var w = img.offsetWidth; var h = img.offsetHeight; var oldParent = img.parentNode; if (oldParent.nodeName.toLowerCase() != "a") { var linkParent = dc("a"); linkParent.setAttribute("href", zoomSrc); oldParent.replaceChild(linkParent, img); linkParent.appendChild(img); } else { var linkParent = oldParent; } var isIE = !!document.all && !!window.attachEvent && !window.opera; linkParent.style.position = "relative"; linkParent.style.display = "block"; linkParent.style.width = w+"px"; linkParent.style.height = h+"px"; var imgLeft = img.offsetLeft; var imgTop = img.offsetTop; var zoom = dc("div"); zoom.className = "mojomagnify_zoom"; var parent = img.parentNode; var zoomImg = dc("img"); zoomImg.className = "mojomagnify_img"; zoomImg.style.position = "absolute"; if (isIE) { // IE won't let the mouse click pass through properly to the link, // so we clone the link and use it for the zoom image as well. Do for all browsers, perhaps? var zoomLink = dc("a"); zoomLink.setAttribute("href", linkParent.getAttribute("href")); zoomLink.setAttribute("onclick", linkParent.getAttribute("onclick")); zoomLink.style.position = "absolute"; zoomLink.style.left = "0px"; zoomLink.style.top = "0px"; zoomLink.appendChild(zoomImg); zoom.appendChild(zoomLink); } else { zoom.appendChild(zoomImg); } var ctr = dc("div"); with (ctr.style) { position = "absolute"; left = imgLeft+"px"; top = imgTop+"px"; width = w+"px"; height = h+"px"; overflow = "hidden"; display = "none"; } ctr.appendChild(zoom); parent.appendChild(ctr); var zoomBorder = dc("div"); zoomBorder.className = "mojomagnify_border"; zoom.appendChild(zoomBorder); var zoomInput = parent; var isInImage = false; addEvent(zoomImg, "load", function() { var onMouseOut = function(e) { var target = e.target || e.srcElement; if (!target) return; if (target.nodeName != "DIV") return; var relTarget = e.relatedTarget || e.toElement; if (!relTarget) return; while (relTarget != target && relTarget.nodeName != "BODY" && relTarget.parentNode) { relTarget = relTarget.parentNode; } if (relTarget != target) { isInImage = false; ctr.style.display = "none"; } }; addEvent(ctr, "mouseout", onMouseOut); addEvent(ctr, "mouseleave", onMouseOut); if (isIE) { addEvent(document.body, "mouseover", function(e) { if (isInImage && e.toElement != zoomImg) { ctr.style.display = "none"; } } ); } addEvent(zoomInput, "mousemove", function(e) { isInImage = true; ctr.style.display = "block"; var pos = getEventMousePos(zoomInput, e); if (e.srcElement && isIE) { if (e.srcElement == zoom) return; if (e.srcElement != zoomInput) { var zoomImgPos = getElementPos(e.srcElement); var imgPos = getElementPos(img); pos.x -= (imgPos.x - zoomImgPos.x); pos.y -= (imgPos.y - zoomImgPos.y); } } var x = e.clientX - (getElementPos(img).x - (document.body.scrollLeft||document.documentElement.scrollLeft)); var y = e.clientY - (getElementPos(img).y - (document.body.scrollTop||document.documentElement.scrollTop)); var maskWidth = zoom.offsetWidth; var maskHeight = zoom.offsetHeight; var left = pos.x - maskWidth/2; var top = pos.y - maskHeight/2; if (!isIE) { left -= imgLeft; top -= imgTop; } zoom.style.left = left + "px"; zoom.style.top = top + "px"; var zoomXRatio = zoomImg.offsetWidth / w; var zoomYRatio = zoomImg.offsetHeight / h; var zoomX = Math.round(x * zoomXRatio); var zoomY = Math.round(y * zoomYRatio); var zx = -zoomX + maskWidth/2; var zy = -zoomY + maskWidth/2; zoomImg.style.left = zx + "px"; zoomImg.style.top = zy + "px"; } ); }); // I've no idea. Simply setting the src will make IE screw it self into a 100% CPU fest. In a timeout, it's ok. setTimeout(function() { zoomImg.src = zoomSrc; }, 1); } function init() { var images = document.getElementsByTagName("img"); var imgList = []; for (var i=0;i