Προγραμματισμός

CustomScrollbar class for mooTools

Η γνώμη μου σχετικά με την αντικατάσταση γνωστών controls του λειτουργικού συστήματος με customιές είναι γνωστή: καλύτερα να μην το κάνετε. Ωστόσο, μερικές φορές, ο προγραμματιστής δεν έχει λόγο… Ορίστε λοιπόν ένα class που έφτιαξα για custom scrollbars.

Χρησιμοποιώ τη βιβλιοθήκη mootools – είναι σχετικά ελαφριά, εύχρηστη και (όταν τουλάχιστον ήταν online το forum) με καλή υποστήριξη από την κοινότητα. Αυτό το class απαιτεί τα Element και Selectors components από το Core, και το Slider από το More αλλά, δεν αποκλείεται σε επόμενη version να απαιτούνται και άλλα. Ας δούμε ένα παράδειγμα και μετά θα το αναλύσω.

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus consectetuer, magna vitae luctus egestas, arcu ipsum interdum lacus, in vehicula metus nulla at turpis. Maecenas tempus quam eget orci. Etiam sed turpis. Proin ultricies pede quis purus. Quisque fermentum, ipsum a suscipit imperdiet, nunc ante euismod ligula, nec consequat metus orci eu justo. Morbi vel enim at quam luctus sagittis. Integer hendrerit eleifend sem. Sed orci felis, volutpat non, tristique fermentum, vestibulum sed, ante. Donec gravida dolor id arcu. Pellentesque condimentum porttitor turpis. Nullam eu quam vitae mi aliquam porta. Quisque nec est nec mi imperdiet consectetuer. Nunc ac turpis a risus mollis faucibus. Mauris mattis dui a odio. Phasellus nec nisi vel orci eleifend viverra. Etiam at metus sed leo vestibulum interdum. In pellentesque, magna et sodales condimentum, lacus sapien dapibus augue, nec iaculis justo est sed orci. Morbi fringilla vestibulum leo. Vestibulum quis arcu.

Βασικά χρειάζομαι ένα container με position:relative και μέσα σε αυτό, ένα ακόμα με overflow:auto και καθορισμένο ύψος ή πλάτος, ανάλογα με τον αν θέλω κάθετη ή οριζόντια μπάρα. Μπορώ να βάλω και τα 2 είδη μπάρας σε ένα container αλλά δεν είμαι σίγουρος πως έχω λύσει όλα τα πιθανά προβλήματα. Τέλος, μέσα σε αυτό το container μπορώ να έχω οποιοδήποτε άλλο element. Στο παραπάνω παράδειγμα έχω τα εξής:

<div style="position:relative">
<div id="scroller" style="height:100px; overflow:auto;">
<p>Δεν το ξαναγράφω όλο το Lorem ipsum, χάρην συντομίας.</p>
<p>Εννοείται πως τα στυλ θα πρέπει να βρίσκονται σε αρχείο CSS!</p>
</div>
</div>

Ορίστε και το class:

var CustomScrollbar=new Class({
	/* http://www.pvgr.eu - Panayiotis «thePrince» Velisarakos
	this class is licenced under a Creative Commons Attribution-Share Alike 3.0 Greece License
	you can use this in any project as long as you keep these comments
	TODO: 	automatic “overflow height” if the user resizes the text
	rewrite the whole thing to make it more compact and/or “elegant” */

	Implements: Options,
	options: {
		barColor: '#c3c3c3',		// this is the scrollbar
		barSize: 10,				// width or height, depends on orientation
		barMargin: 0,				// horizontal or vertical margin, depends on orientation
		knobColor: '#000',			// knob Color
		knobSize: 40,				// length or height, depends on orientation
		orientation: 'vertical',	// guess what
		bottom: 0,					// CSS position
		right: 0,					// again
		padding: 6,					// extra padding on the scrollbar size, added to size+right or bottom
		top: 0						// for the vertical scrollbar
	},
	initialize: function(element, options){
		if(options) this.setOptions(options);
		this.build($(element));
	},
	build: function(el){
		// you should define the width or the height of the element to be scrolled with CSS
		// the container should have an overflow:auto, in case the client does not support Javascript
		if (this.options.orientation=='vertical') {
			var height=el.getSize().y;
			var overflow=el.getScrollSize().y-height;	// find the overflow height
			var vertical=true;
		} else {
			var width=el.getSize().x;
			var overflow=el.getScrollSize().x-width;	// find the overflow width - remember to set the width of the contents!
			var vertical=false;
		}
		if (el.getScrollSize().y > height || el.getScrollSize().x > width) { // maybe we don't need a scrollbar after all
			el.setStyle('overflow', 'hidden');
			if (vertical) {
				el.setStyle('padding-right', this.options.padding+this.options.barSize+this.options.right);
				el.setStyle('width', el.getStyle('width').toInt()-this.options.padding);
			} else {
				el.setStyle('padding-bottom', this.options.padding+this.options.barSize+this.options.bottom);
				el.setStyle('height', el.getStyle('height').toInt()-this.options.padding);
			}
			var scrollbar=new Element('div'); // this is the scrollbar
			scrollbar.setStyles({
				'background-color': this.options.barColor,
				'cursor': 'pointer',
				'position': 'absolute'
			});
			if (vertical) {
				scrollbar.setStyles({
					'height': height-(this.options.barMargin*2),
					'margin-bottom': this.options.barMargin,
					'margin-top': this.options.barMargin,
					'right': this.options.right,
					'top': this.options.top
				});
			} else {
				scrollbar.setStyles({
					'bottom': this.options.bottom,
					'margin-left': this.options.barMargin,
					'margin-right': this.options.barMargin,
					'left': 0,
					'width': width-(this.options.barMargin*2)
				});
			}
			scrollbar.injectAfter(el);		// will be inserted after the scrolling element
			var slider=new Element('div');	// this is the handle
			slider.setStyles({
				'background-color': this.options.knobColor,
				'cursor': 'pointer'
			});
			if (vertical) {
				slider.setStyles({
					'height': this.options.knobSize,
					'width': this.options.barSize
				});
			} else {
				slider.setStyles({
					'height': this.options.barSize,
					'width': this.options.knobSize
				});
			}
			slider.inject(scrollbar);
			if (vertical) { // use the Slider plugin
				var cs=new Slider(scrollbar, slider, {
					snap: true,
					wheel: true,
					steps: overflow,
					mode: 'vertical',
					onChange: function(value){
						el.scrollTo(el.getScroll().x, value);
					}
				});
			} else {
				var cs=new Slider(scrollbar, slider, {
					snap: true,
					wheel: true,
					steps: overflow,
					mode: 'horizontal',
					onChange: function(value){
						el.scrollTo(value, el.getScroll().y);
					}
				});
			}
			// if we scroll a UL list, we can add a class=”current” on load and scroll there - depends on server scripting
			if (el.getElement('li.current')) {
				cs.set(el.getElement('li.current').getPosition(el).y-length);
			}
		}
	}
});

Χρησιμοποιείται ως εξής:

window.addEvent('domready', function(){
if ($('scroller')) {
new CustomScrollbar('scroller', { barColor:'#504641', knobColor:'#9e9490' });
}
});

Το class δέχεται τις εξής ρυθμίσεις αν οι default δεν σας καλύπτουν:

barColor:
Πρόκειται για το χρώμα background της μπάρας
barSize:
Αυτό είναι το πλάτος ή το ύψος της μπάρας ανάλογα με την επιλογή orientation
barMargin:
Σε περίπτωση που δεν θέλετε η scrollbar να πιάνει όλο το ύψος (ή πλάτος) του container, μπορείτε να βάλετε εδώ το περιθώριο – θα προστεθεί ανάλογο πάνω και κάτω (ή αριστερά και δεξιά) margin
knobColor:
Το χρώμα του χειριστήριου
knobSize:
Το ύψος ή μήκος του handle
orientation:
vertical ή horizontal για κάθετη (default) ή οριζόντια scrollbar
bottom:
Χρησιμοποιείται στην οριζόντια μπάρα – είναι η απόσταση από το κάτω μέρος του container
right:
Η κάθετη μπάρα θα δημιουργηθεί στη δεξιά άκρη του container σε όση απόσταση ζητήσετε
padding:
Μπορείτε να προσθέσετε περιθώριο στην δεξιά ή κάτω άκρη του περιεχομένου ώστε να απέχει από την μπάρα και να είναι ευανάγνωστο
top:
Ρυθμίζει την απόσταση της κάθετης μπάρας από την κορυφή του container — συνήθως δεν είναι απαραίτητο αλλά μου χρειάστηκε!

Επιπλέον, αν το περιεχομένο που θέλετε να «σκρολάρετε» είναι σε λίστα <ul> αντί για <p>, μπορείτε να χρησιμοποιήσετε το class="current" σε όποιο <li> θέλετε σαν προεπιλεγμένο κατά το φόρτωμα της σελίδας και το script θα σκρολάρει εκεί.

Αυτό είναι το πρώτο class που γράφω για την βιβλιοθήκη mootools, παρακαλώ να δείξετε κατάνοηση! Υπάρχουν ακόμα περιθώρια για βελτίωση — ο κώδικας δεν είναι κομψός, δεν έχω φτιάξει τον αυτόματο υπολογισμό της μπάρας σε περίπτωση που ο χρήστης κάνει resize ενώ το μέγεθος του handle είναι ακόμα σταθερό. Στην επόμενη version…

Creative Commons LicenseCustomScrollbar class for mootools by Panayiotis «thePrince» Velisarakos is licensed under a Creative Commons Attribution 3.0 Greece License.

Σχολιάστε

Η ηλ. διεύθυνσή σας δεν κοινοποιείται. Τα υποχρεωτικά πεδία σημειώνονται με *