Scroll bars en javascript sur une page html

Soyez le premier à donner votre avis sur cette source.

Vue 7 833 fois - Téléchargée 606 fois

Description

Ce script répond à l'une de mes attentes les plus chères : un contrôle de type "scroll bar" dans un formulaire...

Déclarez autant de "scroll bars" que vous voulez, horizontaux et ou verticaux! dès que vous touchez à l'un d'eux, il mettra à jour la variable html (une balise input text ou hidden) qui lui est affectée!

La configuration est assez simple, tout est expliqué dans le fichier HTML, en commentaires.

Ne marche probablement pas sous IE, car il utilise des canvas et des gestionnaires d'évènements. Mais il est possible de convertir le code pour les initiés...

L'exemple ci-dessous utilise deux scroll bars pour montrer les possibilités.

Source / Exemple :


<html>     
  <head>     
   <script type="text/javascript">
     /*

  • JavaScript scrollbars VERSION 1.0
  • Glenn Forestier du 20/12/2010
  • /
//--------------- variables utilisateur de configuration --------------------- sc_nbre = 2; // nombre de scrollbar dans la page; pict_size = 15; // taille des images de flêches et curseurs (carrés uniquement) pict_url = "img/scrll_"; // emplacement et préfixe des images de flêches //------------------------ Class scroll_bar --------------------------------- im_top = new Image(); im_bas = new Image(); im_lef = new Image(); im_rig = new Image(); im_cur = new Image(); im_top.src = pict_url + "haut.gif"; im_bas.src = pict_url + "bas.gif"; im_lef.src = pict_url + "gauche.gif"; im_rig.src = pict_url + "droit.gif"; im_cur.src = pict_url + "ctre.gif"; function findPosX(obj) { var curleft = 0; if (obj.offsetParent) { do { curleft += obj.offsetLeft; } while (obj = obj.offsetParent); } return curleft; } function findPosY(obj) { var curtop = 0; if (obj.offsetParent) { do { curtop += obj.offsetTop; } while (obj = obj.offsetParent); } return curtop; } function scroll_bar() { // et valeurs par défaut this.orientation = 0; // 0 = vertical, 1 = horizontal this.min = 0; // valeur min this.max = 100; // valeur max this.value = 0; // valeur de départ this.hauteur = 100 + 3*pict_size; // hauteur en pixels this.largeur = pict_size; // largeur en pixels this.unite = 1; // petit déplacement this.saut = 10; // grand déplacement this.ratio = 1; // ratio affichage curseur this.cible = null; // cible qui reçoit value this.dec = 0; // la suite des variables sont internes au this.t0 = this.largeur; // scrollbar... this.t1 = this.largeur + this.value; this.t2 = this.largeur + this.value + this.largeur; this.t3 = this.hauteur - this.largeur; this.ctx = null; this.canvas = null; this.actualise = function(scbar){ //actualisation du scroll pour chaque clic if (scbar.orientation) { // horizontal efface puis redessine le curseur scbar.ctx.clearRect(scbar.t1, 0, pict_size, pict_size) scbar.t1 = Math.round((scbar.value - scbar.min) * scbar.ratio) + scbar.t0; scbar.t2 = scbar.t1 + pict_size; scbar.ctx.drawImage(im_cur, this.t1, 0); } else { // vertical scbar.ctx.clearRect(0, scbar.t1, pict_size, pict_size) scbar.t1 = scbar.t3 - Math.round((scbar.value - scbar.min) * scbar.ratio) - scbar.t0; scbar.t2 = scbar.t1 + pict_size; scbar.ctx.drawImage(im_cur, 0, this.t1); } scbar.cible.value = scbar.value; } this.mouve = function(e) { // curseur qui suit le mouvement de la souris j = this.id.substring(6, this.id.length); // récupération de l'indice dans le tableau des scrollbar if (sc[j].orientation) { //horizontal x = e.clientX-findPosX(this); sc[j].value = sc[j].min + Math.round((x - sc[j].dec - sc[j].t0)/sc[j].ratio); } else { // vertical y = e.clientY-findPosY(this); sc[j].value = sc[j].min + Math.round((sc[j].t3 - y - sc[j].dec)/sc[j].ratio); } if (sc[j].value > sc[j].max) sc[j].value = sc[j].max; if (sc[j].value < sc[j].min) sc[j].value = sc[j].min; sc[j].actualise(sc[j]); } this.uclic = function(e) { // libération des deux gestionaires (on lâche le curseur) j = this.id.substring(6, this.id.length); // récupération de l'indice dans le tableau des scrollbar this.removeEventListener ("mousemove", sc[j].mouve, false); this.removeEventListener ("mouseup", sc[j].uclic, false); } this.clic = function(e) { // dans cette fonction, this est l'objet canvas... j = this.id.substring(6, this.id.length); // récupération de l'indice dans le tableau des scrollbar if (sc[j].orientation) { //horizontal x = e.clientX-findPosX(this); if (x < sc[j].t0) { sc[j].value -= sc[j].unite; } else if (x < sc[j].t1) { sc[j].value -= sc[j].saut; } else if (x < sc[j].t2) { sc[j].dec = x-sc[j].t1; this.addEventListener ("mousemove", sc[j].mouve, false); this.addEventListener ("mouseup", sc[j].uclic, false); } else if (x < sc[j].t3) { sc[j].value += sc[j].saut; } else { sc[j].value += sc[j].unite; } } else { // vertical y = e.clientY-findPosY(this); if (y < sc[j].t0) { sc[j].value += sc[j].unite; } else if (y < sc[j].t1) { sc[j].value += sc[j].saut; } else if (y < sc[j].t2) { sc[j].dec = sc[j].t2 - y; this.addEventListener ("mousemove", sc[j].mouve, false); this.addEventListener ("mouseup", sc[j].uclic, false); } else if (y < sc[j].t3) { sc[j].value -= sc[j].saut; } else { sc[j].value -= sc[j].unite; } } if (sc[j].value > sc[j].max) sc[j].value = sc[j].max; if (sc[j].value < sc[j].min) sc[j].value = sc[j].min; sc[j].actualise(sc[j]); } this.initialise = function(){ // initialisation du scrollbar this.canvas.width = this.largeur; this.canvas.height = this.hauteur; if (this.orientation) { // horizontal this.t0 = pict_size; this.t3 = this.largeur - pict_size; this.ctx.drawImage(im_lef, 0, 0); this.ctx.drawImage(im_rig, this.t3, 0); } else { // vertical this.t0 = pict_size; this.t3 = this.hauteur - pict_size; this.ctx.drawImage(im_top, 0, 0); this.ctx.drawImage(im_bas, 0, this.t3); } b = this.t3 - this.t0 - pict_size; this.ratio = b / (this.max - this.min); this.actualise(this); this.canvas.addEventListener ("mousedown", this.clic, false); } this.creator = function(ori, d_min, d_max, d_uni, d_saut, d_value, d_long, d_cible) { // constructor this.min = d_min; this.max = d_max; this.unite = d_uni; this.saut = d_saut; this.value = d_value; this.cible = document.getElementById(d_cible); if (ori == 1) { // horizontal this.orientation = 1; this.largeur = d_long; this.hauteur = pict_size; } else { // vertical this.orientation = 0; this.hauteur = d_long; this.largeur = pict_size; } this.initialise(); } } //------------------------------------------------------------------------------------------ var sc = new Array(sc_nbre); // tableau des scrollbar et déclaration window.onload = function() { for (i=0; i<sc_nbre; i++) { sc[i] = new scroll_bar(); sc[i].canvas = document.getElementById("canva_" + i); sc[i].ctx = sc[i].canvas.getContext("2d"); } //--------- création individuelle des scrollbar --------------------- /* Paramètres :
  • sc[n].creator(or, min, max, p_dep, g_dep, val, long, dest);
  • n = numéro du scrollbar, de 0 à sc_nombre
  • or = orientation, 0 : vertical, 1 : horizontal
  • min = valeur minimum de sortie
  • max = valeur maximum de sortie
  • p_dep = petit déplacement (clic sur les flèches)
  • g_dep = grand déplacement (clic entre les flèches et le curseur)
  • val = valeur de départ
  • long = taille du scrollbar en pixels, compter plage de déplacement du curseur
+ 3 fois la taille des images de flèches
  • dest = id de variable html (<input text ou hidden>) qui recevra la valeur de sortie
  • du scrollbar.
* Les balises canvas de déclaration HTML doivent porter l'id "canvas_" + n où n est le numéro du scrollbar !
  • /
//------------------------------------------------------------------- sc[0].creator(0, 0, 200, 1, 25, 0, 145, "test_vertical"); sc[1].creator(1, 45, 124, 10, 32, 53, 275, "test_horizontal"); //------------------------------------------------------------------- } </script> </head> <body> <table border='1'> <tr> <td> <b>Scroll Bar vertical</b><br> Min = 0, Max = 200,<br> Déplacement : 1 et 25,<br> Taille : 145 pixels </td> <td> <b>Scroll Bar horizontal</b><br> Min = 45, Max = 124,<br> Déplacement : 10 et 32,<br> Taille : 275 pixels </td> </tr> <tr> <td align='center'> <canvas id="canva_0" width="15" height="15" style="border: 1px solid black;"></canvas> </td> <td align='center'> <canvas id="canva_1" width="15" height="15" style="border: 1px solid black;"></canvas> </td> </tr> <tr> <td> <input type='text' id='test_vertical'> </td> <td> <input type='text' id='test_horizontal'> </td> </tr> </table> </body> </html>

Conclusion :


Le code est assez lourd, puisqu'il est basé sur des classes que javascript ne gère pas si facilement que ça. Il y a certaines restrictions sur les noms des canvas, mais vous vous en accommoderez! Celui ou celle qui peut proposer des améliorations est très bienvenue!!!

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Glennouchet Messages postés 6 Date d'inscription mercredi 17 février 2010 Statut Membre Dernière intervention 15 juillet 2012
22 janv. 2011 à 06:07
Salut à vous deux et merci pour l'info.

Je débute complètement en javascript, surtout parce que l'accès aux éléments déclarés en HTML est particulièrement délicat, il est fréquent que mes scripts foirent. Je suis bien content de ne pas avoir passé 2 jours pour rien sur ce code. Avant de plancher sur la portabilité, je me suis heurté à un autre problème :

On remarquera que je n'ai pas réussi à remonter d'un cran dans les fonctions mouve, clic et uclic à partir de this qui correspond dans ces fonctions à sc[n].canvas, je n'ai pas trouvé de référence simple pour accéder à sc[n].autrePropriété, genre this.enArrière.autrePropriété. D'où les lignes 79, 92 et 97, où je fouille sauvagement pour trouver le bon n. Je ne trouve pas ça beau, et c'est pour ça que l'on est obligé de nommer les scroll bars sc[n]. J'aurais voulu ne pas utiliser de tableau, mais que chacun puisse créer ses scrollbars avec des noms simples...

Il paraît qu'en HTML5 le canvas sera réellement supporté dans tous les navigateurs... Et je ne peux même pas tester sous IE, je l'ai désactivé sur toutes mes machines...

PS : je viens de voir une faute de frappe ligne 47 (roientation au lieu de orientation) que je vais tenter de corriger, mais cela ne semble pas gêner le script.
tefa24600 Messages postés 30 Date d'inscription samedi 4 août 2007 Statut Membre Dernière intervention 21 février 2012
21 janv. 2011 à 16:44
Source intéressant (même si je ne vois pas l'utilité directe).

En ce qui concerne le portage sur IE, il existe une petite librairie, http://code.google.com/p/explorercanvas/ qui permet de porter ça sur le tristement célèbre navigateur de Microsoft

@hornetbzz, tu as aussi la solution du try & catch :

try {
// sous W3C
referenceVersUnElement.addEventListener('typeEvenement', referenceVersFonction, phase);
referenceVersUnElement.removeEventListener('typeEvenement', referenceVersFonction, phase);
} catch (err) {
// sous IE
referenceVersUnElement.attachEvent('ontypeEvenement',referenceVersFonction);
referenceVersUnElement.detachEvent('ontypeEvenement',referenceVersFonction);
}
cs_hornetbzz Messages postés 59 Date d'inscription lundi 1 décembre 2008 Statut Membre Dernière intervention 3 janvier 2011
27 déc. 2010 à 10:12
il n'y a pas grand chose à faire pour rendre ton code un peu plus X-browser.
cf http://hornetbzz.developpez.com/tutoriels/javascript/dom/

W3C
referenceVersUnElement.addEventListener('typeEvenement', referenceVersFonction, phase);
referenceVersUnElement.removeEventListener('typeEvenement', referenceVersFonction, phase);

Modele MS (IE)
referenceVersUnElement.attachEvent('ontypeEvenement',referenceVersFonction);
referenceVersUnElement.detachEvent('ontypeEvenement',referenceVersFonction);

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.