Create a gist now

Instantly share code, notes, and snippets.

@arkitrave /ViewLarger.js Secret
Created Feb 16, 2013

What would you like to do?
Old view larger application
/*
File: ViewLarger class
Version: 0.9
Desc: This class builds the View Larger functionality on a product page.
Requires: /pages/v4/script/dhtml_lib.js
/pages/v4/script/ProductHelper.js
/pages/v4/script/AjaxHelper.js
Use: Auto-initialize by setting up a window load event to call AutoInit static member
EventHelper.AddEvent(window, 'load', ViewLarger.AutoInit, false);
This assumes you already have a link to the view larger page.
Author: Eric Shepherd
Date: December 2006
Methods: The following methods are in this class.
init()
If the large image link is present, calls activate()
Version History:
0.9 EBS Development
1.0 EBS Production
*/
// Class ViewLarger
function ViewLarger(parent)
{
this._relAttribute = 'view-larger';
this._imageCaptionId = 'product-caption';
this._parent = parent;
}
// Public
ViewLarger.prototype.SetRelAttribute = function(value) {
this._relAttribute = value;
}
ViewLarger.prototype.SetImageCaptionId = function(value) {
this._imageCaptionId = value;
}
ViewLarger.prototype.SetParent = function(value) {
this._parent = value;
}
// Function: init()
// Calls activate() if the view larger link is present
// Returns:
// void
ViewLarger.prototype.init = function()
{
if (this.largeImageLink(this._parent) != null) {
this.activate(this._parent);
}
}
// Funtion: largeImageLink()
// Returns the large image link by querying the document to match the rel attribute "view-larger"
// Parameters:
// parent - the element in which to check for a view larger link
// Returns:
// the view larger link if present, else null
ViewLarger.prototype.largeImageLink = function(parent)
{
var theLinks = parent.getElementsByTagName('a');
var theLink = null;
for (i=0; i<theLinks.length; i++) {
if (theLinks[i].getAttribute('rel') && theLinks[i].getAttribute('rel').match(this._relAttribute)) {
theLink = theLinks[i];
}
}
return theLink;
}
// Function: activate()
// Adds the click event to trigger the view larger functionality
// Parameters:
// parent - the element which contains the current view larger scope
// Returns:
// void
ViewLarger.prototype.activate = function(parent)
{
var theLink = this.largeImageLink(parent);
var thisReference = this;
EventHelper.AddEvent(theLink, 'click', ptr = function(e) { thisReference.showLarger(theLink, e); }, false);
}
// Function: showLarger()
// Builds the view larger modal window, or reactivates it as needed, then cancels the default action
// Parameters:
// theLink - the view larger link which was clicked to activate the view larger functionality
// e - the click event
// Returns:
// void
ViewLarger.prototype.showLarger = function(theLink, e)
{
// here is where we actually build stuff
if (document.getElementById('larger-image') == null) {
var newDiv = document.createElement('div');
newDiv.id = 'larger-image';
newDiv.style.display = 'none';
var theBody = document.getElementsByTagName('body')[0];
theBody.appendChild(newDiv);
// set overlay size
this.overlay();
// load the external page into the div
var thisReference = this;
// make the xmlhttprequest
AjaxHelper.load(newDiv, theLink, function() { thisReference.setBehaviors(); });
} else if (SupportTest.isIE) { // ie has bugs when reactivating the hidden div - things vanish - so we need to make the ajax call again
// delete div
var div = document.getElementById('larger-image');
div.parentNode.removeChild(div);
// redo ajax call
var newDiv = document.createElement('div');
newDiv.id = 'larger-image';
newDiv.style.display = 'none';
var theBody = document.getElementsByTagName('body')[0];
theBody.appendChild(newDiv);
this.overlay();
var thisReference = this;
AjaxHelper.load(newDiv, theLink, function() { thisReference.setBehaviors(); });
} else { // good browsers can just reactivate the hidden div
// restore the visibility of the previously hidden element
$('larger-image').setStyle('display', 'block');
$('viewlarger-scroll-frame').setStyle('display', 'block');
$('viewlarger-close').setStyle('display', 'block');
$('viewlarger-include').effect('opacity').custom(0,1);
// we need to set the image display now, also
this.fixImages(theLink);
this.fixCaption();
// run the effects for the mouseovers and close functionality
this.setBehaviors();
}
// cancel the default action
EventHelper.CancelDefault(e);
}
// Function: fixImages()
// Fixes all images after a new click reactivates since we don't instantiate a new scroller object
// This is kind of ugly, but the scroller doesn't know what's inside it,
// so we have to longhand compare the large image with the scroller items.
// Parameters:
// theLink - the link which was clicked to activate view larger
// Returns:
// void
ViewLarger.prototype.fixImages = function(theLink)
{
// get a reference to the ViewLarger object stored as a reference in document
var VLI = document.ViewLargerInstance;
// get the large image
var image = $('main-large-image').getElementsByTagName('img')[0];
// Here we go...
// get the old number image and the newly selected image number.
// we can take the difference and jump by that number
var theOldNumberArr = image.src.match(/_(\d{1,2})\./);
var theOldNumber = theOldNumberArr.length > 0 ? theOldNumberArr[1] : 1;
// get the new number
var theNewNumberArr = theLink.href.match(/image=(\d+)/);
var theNewNumber = theNewNumberArr.length > 0 ? theNewNumberArr[1] : 1;
// set the new large image
var newImage = document.createElement('img');
newImage.src = image.src.replace(/_\d+.jpg/g, '_' + theNewNumber + '.jpg');
newImage.onload = function() {
image.src = newImage.src;
newImage = null;
}
// get an array of the images
// PROBLEM: IE places the script objects in the ViewLarger.aspx page out of scope, so we can't read from the instances
// SOLUTION: Place a reference to the instance in the document object when it's created in ViewLarger.aspx
var container = document.getElementById(VLI.scroller._itemId);
var thumbnails = container.getElementsByTagName('img');
// get the new number
var str = '_' + theNewNumber + '.jpg';
var imageSlot = 1;
// assign imageSlot to index in array of that number's occurrence
// and set the selected list item for use below
var theNewLi;
for (i=0; i<thumbnails.length; i++) {
if (thumbnails[i].src.match(str)) {
imageSlot = i;
theNewLi = DomHelper.AscendDom(thumbnails[i], 'li');
}
}
var oldTop = VLI.scroller._itemTop;
var newTop = imageSlot * VLI.scroller._increment;
// reset scroller to new position
if (thumbnails.length > 6) {
VLI.scroller._scrollerItem.style.top = (0 - newTop) + 'px';
VLI.scroller._itemTop = parseInt(VLI.scroller._scrollerItem.style.top);
}
// change the active/inactive items
// start with scroller buttons
VLI.scroller.updateControls(0, VLI.scroller.canScrollBackward());
VLI.scroller.updateControls(1, VLI.scroller.canScrollForward());
// then do the image active states and links using the currently instantiated ProductHelper object
var theListItems = container.getElementsByTagName('li');
var activeEl;
for (i=0; i<theListItems.length; i++) {
if (!theListItems[i].getElementsByTagName('a').length > 0) {
activeEl = theListItems[i];
VLI.viewLargerPH._storage = DomHelper.DeactivateElement(activeEl, VLI.viewLargerPH._storage);
VLI.viewLargerPH._storage = DomHelper.ActivateElement(theNewLi, VLI.viewLargerPH._storage);
}
}
}
// Function: fixCaption()
// Fix the caption after the modal window is reactivated
// Returns:
// void
ViewLarger.prototype.fixCaption = function()
{
var theCaptionNode = document.getElementById(this._imageCaptionId);
var theCaption = theCaptionNode.firstChild ? theCaptionNode.firstChild.nodeValue : ' ';
var theNewCaptionNode = document.getElementById('viewlarger-caption');
theNewCaptionNode.innerHTML = theCaption;
}
// Function: setBehaviors()
// Callback after ajax call or reactivation of hidden elements. Sets the behavioral effects of the modal window
// Returns:
// void
ViewLarger.prototype.setBehaviors = function()
{
var thisReference = this;
targetsLoaded = setInterval(setEffects, 300);
function setEffects() {
if (typeof $ != 'undefined') {
// INIT: set the position before making visible
thisReference.setPosition();
// make visible
$('larger-image').setStyle('display', 'block');
$('viewlarger-scroll-frame').setStyle('display', 'block');
$('viewlarger-close').setStyle('display', 'block');
// EFFECT: sets the opacity of the entire modal window, including display none
// after it fades out, so that it won't be present over the product page window
viewLargerOpacityEffect = $('viewlarger-include').effect('opacity', {
onStart : function() {
},
onComplete: function() {
$('larger-image').setStyle('display', 'none');
$('viewlarger-scroll-frame').setStyle('display', 'none');
$('viewlarger-close').setStyle('display', 'none');
}
});
// ACTION: make modal window draggable
var dragOptions = {
onStart : function() {
$('viewlarger-include').setStyle('cursor', 'move');
},
onComplete : function() {
$('viewlarger-include').setStyle('cursor', 'default');
}
}
$('viewlarger-include').makeDraggable(dragOptions);
// EVENT: click - ELEMENT: close button or window overlay - ACTION: close and hide modal window
$('viewlarger-overlay').addEvent('click', function() { viewLargerOpacityEffect.custom(1,0); });
$('viewlarger-close').addEvent('click', function() { viewLargerOpacityEffect.custom(1,0); });
// EVENT: keypress - ESCAPE KEY - ACTION: close and hide modal window
document.onkeydown = function(e){
if (e == null) { // ie
keycode = event.keyCode;
} else { // mozilla
keycode = e.which;
}
if(keycode == 27){ // close
viewLargerOpacityEffect.custom(1,0);
}
}
// clear interval - TODO: add a try/catch to be sure the interval gets cleared?
clearInterval(targetsLoaded);
}
}
}
// -----------------------
// HELPER METHODS
// -----------------------
// Function: overlay()
// Sets the size of the overlay div to match the height and width of the current window
// Returns:
// void
ViewLarger.prototype.overlay = function()
{
if (window.innerHeight && window.scrollMaxY || window.innerWidth && window.scrollMaxX) {
xScroll = window.innerWidth + window.scrollMaxX;
yScroll = window.innerHeight + window.scrollMaxY;
var doc = document.documentElement;
var docw = (doc && doc.clientWidth) || document.body.clientWidth || window.innerWidth || self.innerWidth;
var doch = (doc && doc.clientHeight) || document.body.clientHeight || window.innerHeight || self.innerHeight;
xScroll -= (window.innerWidth - docw);
yScroll -= (window.innerHeight - doch);
} else if (document.body.scrollHeight > document.body.offsetHeight || document.body.scrollWidth > document.body.offsetWidth) {
xScroll = document.body.scrollWidth;
yScroll = document.body.scrollHeight;
} else {
xScroll = document.body.offsetWidth;
yScroll = document.body.offsetHeight;
}
$('larger-image').setStyles({
'width' : xScroll + 'px',
'height' : yScroll + 'px'
});
}
// Function: getPageSizes()
// Returns an array containing the width and height of the current page
// Returns:
// array[width, height]
ViewLarger.prototype.getPageSizes = function()
{
var doc = document.documentElement;
var w = window.innerWidth || self.innerWidth || (doc && doc.clientWidth) || document.body.clientWidth;
var h = window.innerHeight || self.innerHeight || (doc && doc.clientHeight) || document.body.clientHeight;
pageSizes = new Array(w, h);
return pageSizes;
}
// Function: setPosition()
// Sets the left and top offsets of the view larger modal window
// Returns:
// void
ViewLarger.prototype.setPosition = function()
{
var pageSizes = this.getPageSizes();
var pageScrolls = this.getPageScrollTop();
$('viewlarger-include').setStyles({
'left' : pageScrolls[0] + ((pageSizes[0] - 590)/2) + 'px',
'top' : (pageScrolls[1] + 25) + 'px'
});
}
// Function: getPageScrollTop()
// Returns the amount the page has been scrolled
// Returns:
// array[left offset, top offset]
ViewLarger.prototype.getPageScrollTop = function()
{
var xScrollLeft;
var yScrollTop;
if (self.pageYOffset || self.pageXOffset) {
xScrollLeft = self.pageXOffset;
yScrollTop = self.pageYOffset;
} else if (document.documentElement && document.documentElement.scrollTop || document.documentElement.scrollLeft) {
xScrollLeft = document.documentElement.scrollLeft;
yScrollTop = document.documentElement.scrollTop;
} else if (document.body) {
xScrollLeft = document.body.scrollLeft;
yScrollTop = document.body.scrollTop;
}
pageScrolls = new Array(xScrollLeft, yScrollTop);
return pageScrolls;
}
// Function: AutoInit()
// Static member to create a standard application on a product page assuming we are targeting the "#product-shot" element
// Returns:
// void
ViewLarger.AutoInit = function() {
var parent = document.getElementById('product-shot');
var instance = new ViewLarger(parent);
instance.init();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment