Skip to content

Instantly share code, notes, and snippets.

@markusfisch
Last active June 29, 2019 00:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save markusfisch/2942485 to your computer and use it in GitHub Desktop.
Save markusfisch/2942485 to your computer and use it in GitHub Desktop.
A small and simple hovering image viewer
/**
* A small and simple hovering image viewer
*
* @param loadingHtml - HTML snippet to show while loading (optional)
*/
function ImageViewer( loadingText )
{
/** Text to show while loading */
this.loadingText = loadingText ?
loadingText :
"<div><p>Loading ...</p></div>";
/** True if this is Opera */
this.isOpera = window.opera ? 1 : 0;
/** True if this is Internet Explorer */
this.isIE = document.all && !window.opera ? 1 : 0;
/** True if this is Mozilla/Firefox */
this.isMozilla = window.innerWidth &&
!window.opera && !document.layers ? 1 : 0;
/** Image buffer for loading */
this.imageBuffer = new Image();
/** Timer ID of loading timer */
this.loadingTimer = 0;
/** URL of currently shown image */
this.shownUrl = null;
/** Frame division for full view */
this.div = document.createElement( "div" );
if( this.div )
{
// setup view division
{
var properties = {
visibility: "hidden",
position: "absolute",
left: "0",
top: "0",
zIndex: "1" };
for( var p in properties )
this.div.style[p] = properties[p];
this.div.imageViewer = this;
this.div.className = "ImageViewer";
this.div.onmouseout = this.leaveThumbnail;
}
// add elements to body
{
var body = document.getElementsByTagName( "body" );
if( !body ||
!body.length )
return;
body[0].appendChild( this.div );
}
}
}
/**
* Create image viewer for all divsions having the given class
*
* @param className - class name
*/
ImageViewer.prototype.createForClasses = function( className )
{
var d = document.getElementsByTagName( "div" );
for( var n = d.length; n--; )
if( d[n].className.indexOf( className ) > -1 )
this.create( d[n] );
}
/**
* Create image viewer
*
* @param container - container element
*/
ImageViewer.prototype.create = function( container )
{
for( var n = container.childNodes.length; n--; )
{
var c = container.childNodes[n];
if( c.tagName != "A" )
continue;
c.onclick = function(){ return false; };
// attach viewer to image tags
{
var i = c.getElementsByTagName( "img" );
if( i.length > 0 )
{
var ii = i[0];
ii.onmouseover = this.enterThumbnail;
ii.onmouseout = this.leaveThumbnail;
ii.imageViewer = this;
ii.imageViewerSrc = c.href;
}
}
}
}
/**
* Mouse entered thumbnail
*
* @param ev - mouse event
* @return false when handled, true otherwise
*/
ImageViewer.prototype.enterThumbnail = function( ev )
{
var v;
if( !(v = this.imageViewer) ||
v.shownUrl == this.imageViewerSrc )
return true;
v.show( v.getPosition( ev ), this.imageViewerSrc, this.alt );
return false;
}
/**
* Mouse left thumbnail
*
* @param ev - mouse event
* @return false when handled, true otherwise
*/
ImageViewer.prototype.leaveThumbnail = function( ev )
{
var v;
if( !(v = this.imageViewer) )
return true;
if( ev ||
(ev = window.event) )
{
var t = ev.relatedTarget ? ev.relatedTarget : ev.toElement;
// ignore events if cursor has gone to thumbnail
if( t.imageViewerSrc &&
v.shownUrl == t.imageViewerSrc )
return false;
// ignore events within viewer division
for( ; t; t = t.parentNode )
if( t == v.div )
return false;
}
v.hide();
return false;
}
/**
* Show viewer
*
* @param p - cursor position as object
* @param url - URL of image to show
* @param label - image label (optional)
*/
ImageViewer.prototype.show = function( p, url, label )
{
if( this.shownUrl != url )
{
this.shownUrl = url;
this.imageBuffer.src = url;
var d = this.div;
d.innerHTML = this.loadingText;
d.style.left = p.x+"px";
d.style.top = p.y+"px";
d.style.visibility = "visible";
}
if( !this.imageBuffer.complete )
{
this.clearTimer();
var t = this;
this.loadingTimer = setTimeout(
function(){ t.show( p, url, label ); }, 250 );
return;
}
this.div.innerHTML = "<div><img src=\""+url+"\"/>"+
(label ?
"<p>"+label+"</p>" :
"")+
"</div>";
}
/**
* Hide viewer
*/
ImageViewer.prototype.hide = function()
{
this.shownUrl = null;
this.clearTimer();
this.div.style.visibility = "hidden";
}
/**
* Clear loading timer
*/
ImageViewer.prototype.clearTimer = function()
{
if( !this.loadingTimer )
return;
clearTimeout( this.loadingTimer );
this.loadingTimer = 0;
}
/**
* Get cursor position from event
*
* @param e - mouse event
*/
ImageViewer.prototype.getPosition = function( e )
{
var x = 0,
y = 0;
if( this.isOpera )
{
x = e.clientX;
y = e.clientY;
}
else if( this.isIE )
{
if( document.documentElement &&
document.documentElement.scrollTop )
{
x = event.clientX+document.documentElement.scrollLeft;
y = event.clientY+document.documentElement.scrollTop;
}
else
{
x = event.clientX+document.body.scrollLeft;
y = event.clientY+document.body.scrollTop;
}
}
else if( this.isMozilla )
{
x = e.pageX;
y = e.pageY;
}
return { x: x, y: y };
}
window.ImageViewer = ImageViewer;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment