// // Page Scroller // var page_scroller; function make_page_scroller(min_val,max_val,curr_val,scrollbar_width,callback) { document.write(make_page_scroller.template(scrollbar_width)); // Define scrollbar attributes. Slider.SliderMin = 1; Slider.SliderMax = max_val; Slider.SliderBorderWidth = 2 // Define scrollbar var fudge = Slider.isIE ? 6 : 2; scrollbar_width += fudge; // Define scrollbar slider. var slider_e = get_ref('page_scroller'); var slider_width = slider_e.offsetWidth ? slider_e.offsetWidth : 20; // Reset size of slider for small numbers if (Math.floor(scrollbar_width / (slider_width + 2*Slider.SliderBorderWidth)) >= (Slider.SliderMax - Slider.SliderMin + 1)) { slider_width = Math.floor(scrollbar_width / Slider.SliderMax); } slider_e.style.width = slider_width + "px"; // Determine number of units per pixel of scrolling. var scale_width = (scrollbar_width - (slider_width + 2*Slider.SliderBorderWidth)); Slider.SliderScale = (max_val-Slider.SliderMin)/scale_width; Slider.ScrollStep = 1/Slider.SliderScale; // Define callback routine. var scroller_action = function(n,done) { if (callback) { callback(n,done); } if (done) { // flag set when scrolling stops // Set url page parameter to scroller value. href=location.href.replace(/\&p=\d*/,'') + "&p="+Math.round(n) // Add total number of rows to url to prevent server from recomputing. if (window.NFound && NFound > 0) href += "&n="+NFound; // Display next page. location.href = href; } } // Setup scrollbar. var max_pos = scrollbar_width - (slider_width + 2*Slider.SliderBorderWidth); if (max_pos < 0) max_pos = 0; // happens if slider width equals scrollbar (borders) page_scroller = new Slider('page_scroller',max_pos,slider_e,scroller_action); // Move to initial position. page_scroller.set_val(curr_val); page_scroller.move(page_scroller.slider_pos(curr_val)); } make_page_scroller.template = function(scrollbar_width) { return '' + '\n' + '\n' + '\n' + '
\n' + '\n' + '\n' + '\n' + '\n' + '\n' + '\n' + '\n' + '\n' + '
 
\n' + '\n' + '\n' + '
 
\n' + '\n' + '
 
\n' + '\n' + ''; } /* * AcmePScroller v.8 * Control DHTML slider elements. * Copyright (c) 2003,2006 Mackley F. Pexton. All rights reserved. * This work based on AcmeSlider v1.3 * Send correspondence and feedback to: mack_pexton[at]acmebase[dot]com. */ // Set Slider configuration variables to the CSS style settings of the slider. Slider.SliderBorderWidth = 2; // slider's border width Slider.SliderScale = 1; // value per pixel of slider bar // Set Slider Scroller configuration variables. Slider.ScrollRate = 100; // Rate of scroll (milliseconds between iterations) Slider.ScrollDelay = 500; // Initial delay before scrolling (milliseconds) Slider.ScrollStep = 1; // Step of scroll Slider.SliderMin = 0; // Minimum value of slider // Slider working variables. Slider.current_slider = null; // current activated slider control Slider.callback_timer; // for IE Slider.isIE = navigator.userAgent.match(/MSIE/) ? true : false; // Slider object constructor. function Slider(e,max,fld,callback) { // Parameters: // e -- slider element (element that slides on the scale) // max -- maximum value of the slider (default is 100) // fld -- optional form field used to track slider position // callback -- optional function called with slider value when slider is moved if (typeof e == 'string') e = document.getElementById(e); if (fld == null) fld = new Object; if (max == null) max = 100; this.e = e; // slider object this.fld = fld; // field or object to record slider position this.max = max; // maximum value of slider (pixels) this.callback = callback; // function called when slider is moved this.on = false; // flag if slider is active or not this.xdiff = 0; // offset difference between slider and container // Copy global settings to object this.SliderBorderWidth = Slider.SliderBorderWidth; this.SliderScale = Slider.SliderScale; // Copy slider scroller global settings to object this.ScrollRate = Slider.ScrollRate; this.ScrollDelay = Slider.ScrollDelay; this.ScrollStep = Slider.ScrollStep; this.SliderMin = Slider.SliderMin; this.SliderMax = Slider.SliderMax; this.saved_pos = 0; this.saved_val = this.SliderMin; document.body.parentNode.onmouseup = Slider.turn_off; // safety } // Class method for event handler Slider.turn_off = function(evt) { if (Slider.current_slider) Slider.current_slider.turn_off(evt); Slider.current_slider = null; } Slider.prototype.next_pos = function(evt) { var pos = (evt.pageX ? evt.pageX : evt.clientX) - this.xdiff; if (pos < 0) pos = 0; if (pos > this.max) pos = this.max; return pos; } Slider.prototype.set_pos_val = function(pos) { var val = this.slider_val(pos); this.set_val(val); } Slider.prototype.set_val = function(val) { if (this.fld.value) this.fld.value = val; else if (this.fld) { // Note: setTimeout is necessary when IE displays the slider in a frame. if (Slider.isIE) { var e = this.fld; setTimeout(function(){e.innerText=val},1); } else { this.fld.innerHTML = val; } } this.saved_val = val; } Slider.prototype.slider_val = function(pos) { return Math.round(pos*this.SliderScale + this.SliderMin); // integer value } Slider.prototype.slider_pos = function(val) { var pos = Math.round((val - this.SliderMin)/this.SliderScale); // integer value if (pos < 0) pos = 0; if (pos > this.max) pos = this.max; return pos; } Slider.prototype.track = function(evt) { // Track current position of slider if (! this.on) return; var pos = this.next_pos(evt); this.set_pos_val(pos); this.move(pos); this._collapse_text_selection(); } Slider.prototype.move = function(pos,done) { if (isNaN(pos)) return; // Move slider to position. // Note: pos already assumed to be checked to be within its range. this.e.style.left = pos + 'px'; // Call callback function notifying that the slider has moved. if (this.callback) { if (Slider.isIE) { // HACK: IE has a timing problem when callback function assigns a // new url to location.href (an initial intended purpose of this). var obj = this; var val = this.saved_val; setTimeout(function(){obj.callback(val,done)},1); } else { this.callback(this.saved_val,done); } } // Hack, save pos so callback can be called in scroll_stop(). this.saved_pos = pos; } Slider.prototype.turn_on = function(evt) { // Start tracking slider var pos = parseInt(this.e.style.left,10); if (isNaN(pos)) pos = 0; this.xdiff = (evt.pageX ? evt.pageX : evt.clientX) - pos; this._activate(evt); } Slider.prototype.move_and_turn_on = function(evt) { evt = evt ? evt : window.event ? window.event : null; var target = evt.target ? evt.target : evt.srcElement ? evt.srcElement : null; // Note: this method is to be fired when mouse is clicked on the // slider-bar-top or slider-bar-bottom elements which are enclosed // by the slider-container element. It moves the slider to the position // clicked and then follows the cursor. If the target is the slider-container // element, it is because Netscape (v6-v7.1) fires the event when the // mouse is clicked outside of the element, which is wrong. (!!) // The problem apparently comes from Netscape keeping a flag if the mouse // is down and clears it only if the original element that fires a // mousedown fires the mouseup. Because the slider moves into place // on a mousedown event, it is the slider that receives the mouseup // and not the original element receiving the mousedown, so Netscape // thinks the mouse is still down until the next click. if (target.className == 'slider-container') return; // Netscape errant trigger workaraound // Move the slider to the place on the slider bar where the mouse was clicked. this.xdiff = target.offsetLeft + 10; // 10 is half of slider's width this._activate(evt); } Slider.prototype.turn_off = function(evt) { evt = evt ? evt : window.event ? window.event : null; this.on = false; if (evt) { evt.cancelBubble = true; if(evt.stopPropagation) evt.stopPropagation(); var pos = this.next_pos(evt); this.move(pos,true); this._collapse_text_selection(); this.set_pos_val(pos); } if (this == Slider.current_slider) Slider.current_slider = null; } Slider.prototype._collapse_text_selection = function() { // Un-select text that might have been selected as the mouse moved. if (window.getSelection) { var sel = window.getSelection(); if (sel.removeAllRanges) sel.removeAllRanges(); // Moz else if (sel.getRangeAt) sel.getRangeAt(0).collapse(true); // DOM } else if (document.selection && document.selection.empty) { document.selection.empty(); // IE } } Slider.prototype._activate = function(evt) { // Start following mouse pointer with slider. Slider.scroll_stop(); // safety this.on = true; Slider.current_slider = this; // register this.track(evt); evt.cancelBubble = true; if(evt.stopPropagation) evt.stopPropagation(); } /* * Slider Scroll Methods */ // Slider scroller working variables. Slider.scroll_timer; // setTimeOut() timer Slider.scroll_sliders = []; // working array - list of sliders being scrolled Slider.scroll_rate; // working variable - milliseconds between scroll Slider.scroll_dir; // working variable - direction of scroll (-1 left, 1 right) Slider.prototype.scroll = function(dir) { // Scroll slider left or right Slider.scroll_stop(); // safety document.onmouseup = Slider.scroll_stop; // safety // Save arguments for next scroll in global context Slider.scroll_sliders = [ this ]; // one element array Slider.scroll_dir = dir; Slider.scroll_rate = this.ScrollRate; Slider.scroll_move(); // Schedule next scroll Slider.scroll_timer = setTimeout(Slider.scroll_next,this.ScrollDelay); } Slider.prototype.scroll_stop = function(evt) { evt = evt ? evt : window.event ? window.event : null; // Stop scrolling clearTimeout(Slider.scroll_timer); if (evt) { evt.cancelBubble = true; if(evt.stopPropagation) evt.stopPropagation(); } this.move(this.saved_pos,true); } // Class method Slider.scroll_next = function() { Slider.scroll_move(); Slider.scroll_timer = setTimeout(Slider.scroll_next,Slider.scroll_rate); } // Class utility method to move all sliders a step. Slider.scroll_move = function() { // Recover scroller arguments from saved class variables var slider; for (var i = 0; i < Slider.scroll_sliders.length; i++) { slider = Slider.scroll_sliders[i]; var val = slider.saved_val + (Slider.scroll_dir * 1); if (val < slider.SliderMin) val = slider.SliderMin; if (val > slider.SliderMax) val = slider.SliderMax; slider.set_val(val); slider.move(slider.slider_pos(val)); } } // Class method Slider.scroll_all = function(dir) { // Scroll a list of sliders left or right Slider.scroll_stop(); // safety document.onmouseup = Slider.scroll_stop; // safety // Save arguments for next scroll in global context Slider.scroll_sliders = [ ]; // initialize array Slider.scroll_dir = dir; // scroll direction Slider.scroll_rate = Slider.ScrollRate; // use global setting for (var i = 1; i < arguments.length; i++) { Slider.scroll_sliders[i-1] = arguments[i]; } Slider.scroll_move(); // Schedule next scroll Slider.scroll_timer = setTimeout(Slider.scroll_next,Slider.ScrollDelay); } // Class method Slider.scroll_stop = function(evt) { // Stop scrolling clearTimeout(Slider.scroll_timer); }