1/** 2 * jquery.ui.menuflottant.js 3 * --------------------------------------------------------------- 4 * Ce fichier est un SECRET COMMERCIAL de Druide informatique inc. 5 * Tout lecteur ou possesseur non autorisé sera poursuivi. 6 * --------------------------------------------------------------- 7 * 8 * Extension (« widget ») jquery permettant de gérer les menus flottants. 9 * 10 * 11 * @author Philippe Arcand <[email protected]> 12 * @copyright 2013 Druide informatique Inc. 13 */ 14$(function() { 15 $.widget("custom.menuflottant", { 16 17 estVisible: false, 18 modeFlottant: true, 19 jeMePositionne: false, 20 21 /** 22 * Constructeur 23 */ 24 _create: function() { 25 var widget = this; 26 var elem = this.element; 27 var declencheur = widget.donneDeclencheur(); 28 var $body = $('body'); 29 30 /* Element de fond modal */ 31 if(! $('#fond-modal-menu').length){ 32 $body.append('<div id="fond-modal-menu"></div>'); 33 } 34 35 /* Flèche */ 36 $(elem).append('<div class="fleche"></div>'); 37 38 widget.activeModeFlottant(); 39 40 // Activation sur click (menus) 41 $(declencheur).on('mouseup', function(event){ 42 if(widget.modeFlottant && !$(elem).parents('.menu-flottant').length){ 43 44 event.preventDefault(); 45 event.stopPropagation(); 46 if(!$(this).hasClass('desactive')){ 47 if(! $(this).hasClass('menu-flottant-actif')){ 48 $(this).addClass('menu-flottant-actif'); 49 widget.affiche(); 50 } 51 else{ 52 $(this).removeClass('menu-flottant-actif'); 53 widget.masque(); 54 } 55 } 56 57 return false; 58 } 59 }); 60 61 // Fermeture des sous-menu lors d'un mouse over sur un autre lien 62 $(elem).find('> ul > li > a').on('mouseover', function(){ 63 $(elem).find('.menu-flottant').menuflottant('masque'); 64 }); 65 66 // Activation sur mouseover (sous-menus) 67 $(declencheur).on('mouseover', function(event){ 68 if(!widget.jeMePositionne && widget.modeFlottant && $(elem).parents('.menu-flottant').length){ 69 event.preventDefault(); 70 event.stopPropagation(); 71 if(!$(this).hasClass('desactive')){ 72 $(this).addClass('menu-flottant-actif'); 73 widget.jeMePositionne = true; 74 widget.affiche(); 75 widget.jeMePositionne = false; 76 } 77 78 return false; 79 } 80 }); 81 82 // Désactivation sur mouseout 83 $(declencheur).on('mouseout', function(event){ 84 if (widget.jeMePositionne) 85 return false; 86 }); 87 88 89 $(elem).find('.declencheur-fermeture-menu').on('mouseup', function(){ 90 if(widget.modeFlottant) { 91 widget.masque(); 92 } 93 }); 94 95 96 $(elem).on('click', function(e){ 97 if(widget.modeFlottant) { 98 e.stopPropagation(); 99 } 100 }); 101 102 103 $body.on('mouseup', function(e){ 104 if(widget.estVisible && widget.modeFlottant) 105 { 106 //Ferme le menu s'il y a un clique à l'extérieur 107 //ou si un lien est cliqué 108 if(e.target.nodeName === "A" || !$.contains(widget.element[0])) 109 { 110 widget.masque(); 111 } 112 } 113 }); 114 115 $(window).scroll(function(){ 116 if(widget.estVisible && widget.modeFlottant) 117 { 118 widget.masque(); 119 } 120 }) 121 }, 122 123 /** 124 * Fonction permettant d'obtenir le déclencheur associé au menu flottant 125 * 126 * @return element Le déclencheur 127 */ 128 donneDeclencheur: function(){ 129 var elem = this.element; 130 131 if(typeof($(elem).data('declencheur')) === 'string'){ 132 var declencheur = $("#"+$(elem).data('declencheur')); 133 $(elem).data('declencheur', declencheur); 134 135 } 136 else if($(elem).data('declencheur') === undefined ){ 137 declencheur = $(elem).siblings('.declencheur-menu'); 138 $(elem).data('declencheur', declencheur); 139 140 } 141 else{ 142 declencheur = $(elem).data('declencheur'); 143 } 144 145 return declencheur; 146 }, 147 148 149 /** 150 * Fonction permettant d'afficher le menu 151 */ 152 affiche: function(){ 153 var widget = this; 154 var elem = this.element; 155 var $fondModal = $('#fond-modal-menu'); 156 var $declencheur = widget.donneDeclencheur(); 157 158 if(widget.modeFlottant){ 159 // Fermeture des autres menus flottants déjà ouverts 160 $('.menu-flottant').not(elem).each(function(){ 161 162 // Vérification afin de s'assurer que le menu flottant n'est pas le parent du menu flottant actuel 163 if(!$(this).find($declencheur).length){ 164 $(this).menuflottant('masque'); 165 } 166 }); 167 168 widget.estVisible = true; 169 $fondModal.css('display', 'block'); 170 171 if(!$(elem).parents('.menu-flottant').length && $(elem).data('pref-placement') !== 'relatif'){ 172 $(elem).insertAfter($fondModal); 173 } 174 175 window.setTimeout(function(){ 176 $(window).on('scroll.menuflottant', function(){ 177 var positionTop = $(elem).position().top; 178 var positionScroll = $(document).scrollTop(); 179 if(positionScroll + $(window).height() < positionTop || $(elem).height() + positionTop <= positionScroll) 180 { 181 widget.masque(); 182 } 183 }); 184 $(window).on('resize.menuflottant', function(){widget.positionne()}); 185 },100); 186 187 $(elem).show(); 188 widget.positionne(); 189 } 190 }, 191 192 /** 193 * Fonction permettant de masquer le menu 194 */ 195 masque: function(){ 196 var widget = this; 197 var elem = this.element; 198 widget.estVisible = false;
199 var declencheur = widget.donneDeclencheur(); 200 201 if(widget.modeFlottant) { 202 203 $('#fond-modal-menu').css('display', 'none'); 204 205 $(window).off('scroll.menuflottant resize.menuflottant'); 206 207 $(declencheur).removeClass('menu-flottant-actif'); 208 $(elem).hide().css({'--max-h': '', 'margin-top': '', 'margin-left': '', 'left': '', 'top':''}); 209 } 210 }, 211 212 /** 213 * Fonction permettant de positionner le menu 214 */ 215 positionne: function(){ 216 var widget = this; 217 var elem = this.element; 218 var declencheur = widget.donneDeclencheur(); 219 220 var fleche = $(elem).find('.fleche'); 221 var hauteurDeclencheur = $(declencheur).outerHeight(false); 222 223 // Taille minimale 224 if(!$(elem).css('min-width')){ 225 $(elem).css('min-width', $(declencheur).width()); 226 } 227 228 // Menu racine 229 if(!$(elem).parents('.menu-flottant').length && $(elem).data('pref-placement') !== 'relatif'){ 230 // Positionnement vertical du menu 231 $(elem).css('top', $(declencheur).offset().top + hauteurDeclencheur + ($(declencheur).outerHeight() - hauteurDeclencheur)/2 +18+ 'px'); 232 233 // Positionnement horizontal du menu 234 switch($(elem).data('pref-pos')){ 235 case 'droite': 236 $(elem).css('left', ($(declencheur).offset().left + ($(declencheur).outerWidth() - $(elem).width())) + 'px'); 237 break; 238 case 'centre': 239 $(elem).css('left', ($(declencheur).offset().left + ($(declencheur).outerWidth() - $(elem).width())/2) + 'px'); 240 break; 241 default: 242 $(elem).css('left', ($(declencheur).offset().left) + 'px'); 243 break; 244 } 245 246 // Décalage à droite pour éviter un dépassement de la fenêtre 247 if(($(elem).offset().left) < 0){ 248 $(elem).css('left', 18 + 'px'); 249 } 250 251 // Décalage à gauche pour éviter un dépassement de la fenêtre 252 if(($(elem).offset().left + $(elem).outerWidth() + 18) > $(window).width()){ 253 $(elem).css('left', $(window).width() - ($(elem).outerWidth() + 18) + 'px'); 254 } 255 } 256 else{ 257 // Sous menu 258 if($(elem).parents('.menu-flottant').length){ 259 $(elem).css('margin-top', '-' + ($(declencheur).outerHeight()) + 'px'); 260 261 // Positionnement à droite du menu parent 262 $(elem).css('margin-left', $(elem).parent().outerWidth() + 'px'); 263 264 // Positionnement à droite du menu parent 265 if(($(elem).offset().left + $(elem).outerWidth()) > $(window).width()) { 266 $(elem).css('margin-left', '-' + $(elem).outerWidth() + 'px'); 267 } 268 } 269 else{ 270 $(elem).css('margin-top', '9px'); 271 272 // Positionnement horizontal du menu 273 switch($(elem).data('pref-pos')){ 274 case 'droite': 275 $(elem).css('margin-left', (($(declencheur).outerWidth() - $(elem).width())) + 'px'); 276 break; 277 case 'centre': 278 $(elem).css('margin-left', ((($(declencheur).width()/2) - ($(elem).outerWidth())/2)) + 'px'); 279 break; 280 default: 281 $(elem).css('margin-left', '0px'); 282 break; 283 } 284 285 // Décalage à droite pour éviter un dépassement de la fenêtre 286 if(($(elem).offset().left) < 0){ 287 $(elem).css('margin-left', 18 + 'px'); 288 } 289 290 // Décalage à gauche pour éviter un dépassement de la fenêtre 291 if(($(elem).offset().left + $(elem).outerWidth() + 18) > $(window).width()){ 292 $(elem).css('margin-left', $(window).width() - $(elem).offset().left - ($(elem).outerWidth() + 18) + 'px'); 293 } 294 } 295 } 296 297 298 // Ajustement du positionnement vertical pour éviter un dépassement de la fenêtre 299 if((($(elem).offset().top + $(elem).outerHeight())) > ($(window).scrollTop() + $(window).height())){ 300 if ($(elem).hasClass('active-on-hover')) { 301 $(elem).css('margin-top', '-' + (($(elem).offset().top - $(declencheur).offset().top) + $(elem).outerHeight() + $(declencheur).height() + 18 ) + 'px'); 302 } else { 303 $(elem).css('margin-top', '-' + (((($(elem).offset().top + $(elem).outerHeight()) + 54) - ($(window).scrollTop() + $(window).height()))) + 'px'); 304 } 305 } 306 307 308 // Positionnement horizontal de la flèche 309 switch($(elem).data('pref-pos')){ 310 case 'droite': 311 $(fleche).css('left', $(declencheur).offset().left - $(elem).offset().left + ($(declencheur).outerWidth()) - ($(fleche).outerWidth()) - 18 + 'px'); 312 break; 313 case 'centre': 314 $(fleche).css('left', $(declencheur).offset().left - $(elem).offset().left + ($(declencheur).outerWidth()/2) - ($(fleche).outerWidth()/2) + 'px'); 315 break; 316 default: 317 $(fleche).css('left', $(declencheur).offset().left - $(elem).offset().left + ($(fleche).outerWidth()/2) + 'px'); 318 break; 319 } 320 }, 321 322 /** 323 * Fonction permettant de désactiver le mode flottant 324 */ 325 desactiveModeFlottant: function(){ 326 var widget = this; 327 var elem = this.element; 328 var declencheur = widget.donneDeclencheur(); 329 330 widget.masque(); 331 $(elem).insertAfter(declencheur).attr('style', '').removeClass('mode-flottant'); 332 widget.modeFlottant = false;
333 }, 334 335 /** 336 * Fonction permettant d'activer le mode flottant 337 */ 338 activeModeFlottant: function(){ 339 var widget = this; 340 var elem = this.element; 341 342 $(elem).addClass('mode-flottant'); 343 widget.modeFlottant = true; 344 } 345 346}); 347 348 // Initialisation des menus flottants 349 $('.menu-flottant').menuflottant(); 350 351});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.