1/* 2 __ ___ 3 /'\_/`\ /'\_/`\ /\ \ __ /\_ \ 4 __ __ /\ \ __ ___ __ __ /\ \ ___\ \ \____/\_\\//\ \ __ 5/\ \/\ \ \ \ \__\ \ /'__`\/' _ `\/\ \/\ \ \ \ \__\ \ / __`\ \ '__`\/\ \ \ \ \ /'__`\ 6\ \ \_/ | \ \ \_/\ \/\ __//\ \/\ \ \ \_\ \ \ \ \_/\ \/\ \L\ \ \ \L\ \ \ \ \_\ \_/\ __/ 7 \ \___/ \ \_\\ \_\ \____\ \_\ \_\ \____/ \ \_\\ \_\ \____/\ \_,__/\ \_\/\____\ \____\ 8 \/__/ \/_/ \/_/\/____/\/_/\/_/\/___/ \/_/ \/_/\/___/ \/___/ \/_/\/____/\/____/ 9 10 11 Version : 0.8 12 Date : 10/12/14 13 Auteurs : Vortex Solution / Mikhaël Bois 14 Langues supportées : Français et anglais 15 16*/ 17 18;(function ( $, window, document, undefined ) { 19 20 // Options par défaut 21 var pluginName = "vMenuMobile", 22 defaults = { 23 auto: true, 24 mode: "vertical", 25 type: 1, 26 langue: "fr", 27 position: "gauche", 28 idIcone: "iconeMenu", 29 texteIconeMenu: { 30 "ouvrir": { 31 "fr": "Ouvrir le menu", 32 "en": "Open menu" 33 }, 34 "fermer": { 35 "fr": "Fermer le menu", 36 "en": "Close menu" 37 } 38 }, 39 idMobile: "menuMobile", 40 classeMobile: "mobile", 41 classeBureau: "bureau", 42 classeOuverture: "vMenu-open", 43 classeAnimation: "vAnimationMargin", 44 largeurBureau: 960, 45 classeSousMenu: "avecSousMenu", 46 classeNePasCopierType1: "vNoCopy", 47 classeBtnType2: "vAfficherSousMenu", 48 classeWrapType2: "vWrapType2", 49 texteLienRetour: { 50 "fr": "Retour", 51 "en": "Back" 52 }, 53 classeLienRetour: "vRetour" 54 }; 55 56 // The actual plugin constructor 57 function Plugin ( element, options ) { 58 this.element = element; 59 this.settings = $.extend( {}, defaults, options ); 60 this._defaults = defaults; 61 this._name = pluginName; 62 this.init(); 63 } 64 65 66 // Avoid Plugin.prototype conflicts 67 $.extend(Plugin.prototype, { 68 init: function () { 69 // Initialisation du plugin 70 71 var _ = this; 72 73 // État du menu 74 _.isOpen = false; 75 76 /*! A fix for the iOS orientationchange zoom bug. Script by @scottjehl, rebound by @wilto.MIT / GPLv2 License.*/ 77 (function(a){function m(){d.setAttribute("content",g),h=!0}function n(){d.setAttribute("content",f),h=!1}function o(b){l=b.accelerationIncludingGravity,i=Math.abs(l.x),j=Math.abs(l.y),k=Math.abs(l.z),(!a.orientation||a.orientation===180)&&(i>7||(k>6&&j<8||k<8&&j>6)&&i>5)?h&&n():h||m()}var b=navigator.userAgent;if(!(/iPhone|iPad|iPod/.test(navigator.platform)&&/OS [1-5]_[0-9_]* like Mac OS X/i.test(b)&&b.indexOf("AppleWebKit")>-1))return;var c=a.document;if(!c.querySelector)return;var d=c.querySelector("meta[name=viewport]"),e=d&&d.getAttribute("content"),f=e+",maximum-scale=1",g=e+",maximum-scale=10",h=!0,i,j,k,l;if(!d)return;a.addEventListener("orientationchange",m,!1),a.addEventListener("devicemotion",o,!1)})(this); 78 79 // Détection de la version d'Android transféré dans le <head> 80 81 // Ajoute une classe si le menu s'ouvre à droite ou si le bouton du menu est à droite 82 if(_.settings.position === "droite"){ 83 $("html").addClass("vMenu-droit"); 84 } 85 86 // Change le titre du bouton menu 87 _.setIconTitle(); 88 89 // Menu vertical 90 if(_.settings.mode === "vertical"){ 91 92 // Replace le menu lorsque l'on change l'orientation de l'appareil. Évite certains bugs sur iPhone 93 if(window.addEventListener){ 94 window.addEventListener("orientationchange", function() {window.scrollTo(0, 0);}, false); 95 } 96 97 // Ajoute une classe au pour différencier le mode et le type du menu en CSS 98 $("html").addClass("vMenu-v-"+_.settings.type); 99 100 // Création du menu mobile automatiquement 101 if(_.settings.auto){ 102 $(_.element).clone().attr({ "id": _.settings.idMobile}).prependTo("body"); 103 } 104 105 // Vérifie si le plugin Swipe est inclu 106 if(!jQuery().swipe){ 107 console.log("Veuillez fournir le plugin Swipe"); 108 }else{ 109 // Création des sous-menus 110 _.initSousMenu(); 111 112 // Toggle du menu 113 $(document).on('click', "#"+_.settings.idIcone, function(e) { 114 e.preventDefault(); 115 _.isOpen ? _.toggleState("fermer") : _.toggleState("ouvrir"); 116 });
117 118 /* Ferme le menu si on clique à l'extérieur ou si on clique sur le bouton du menu */ 119 $(document).on('click', function(e) { 120 !$(e.target).closest("#"+_.settings.idMobile+",#"+_.settings.idIcone).length && _.isOpen ? _.toggleState("fermer") : ""; 121 }); 122 } 123 // Menu horizontal 124 }else if(_.settings.mode === "horizontal"){ 125 126 // Ajoute une classe au pour différencier le mode et le type du menu en CSS 127 $("html").addClass("vMenu-h-"+_.settings.type); 128 129 // Création des sous-menus 130 _.initSousMenu(); 131 132 // Déplace le menu vers le haut pour le cacher à sa pleine hauteur 133 _.moveMenuH(); 134 135 // Détecte lorsqu'on passe en mode bureau pour afficher le bon menu 136 _.checkMenuH(); 137 138 // Toggle du menu 139 $(document).on('click', "#"+_.settings.idIcone, function(e) { 140 e.preventDefault(); 141 _.isOpen ? _.toggleState("fermer") : _.toggleState("ouvrir"); 142 }); 143 // Erreur 144 }else{ 145 console.log("Veuillez spécifier le mode du menu"); 146 } 147 148 }, 149 initSousMenu: function () { 150 var _ = this; 151 152 // Menu mobile vertical 153 if(_.settings.mode === "vertical"){ 154 var $menuMobile = $("#"+_.settings.idMobile); 155 // Menu mobile horizontal 156 }else if (_.settings.mode === "horizontal"){ 157 var $menuMobile = $(_.element); 158 } 159 160 161 // Type 1 162 if(_.settings.type === 1){ 163 // Duplication du lien contenant le sous-menu 164 $menuMobile.find("."+_.settings.classeSousMenu+" > a").each(function(){ 165 // Ne copie pas si le lien a cette classe 166 if(!$(this).hasClass(_.settings.classeNePasCopierType1)){ 167 $(this).clone().prependTo($(this).next("ul")).wrap("<li class='vMenu-clone'></li>"); 168 } 169 }); 170 171 // Ouvre les sous-menus actifs 172 $menuMobile.find("."+_.settings.classeSousMenu+".actif > ul").slideDown(); 173 174 // Toggle des sous-menus 175 if(_.settings.mode === "vertical"){ 176 $menuMobile.find("."+_.settings.classeSousMenu+" > a").on('click',function(e){ 177 $this = $(this).closest("."+_.settings.classeSousMenu); 178 _.toggleSousMenu($this,e); 179 }); 180 }else if (_.settings.mode === "horizontal"){ 181 // Évite de garder la détection du click sur la version bureau 182 $menuMobile.find("."+_.settings.classeSousMenu+" > a").on('click',function(e){ 183 if($(_.element).hasClass(_.settings.classeMobile)){ 184 $this = $(this).closest("."+_.settings.classeSousMenu); 185 _.toggleSousMenu($this,e); 186 } 187 }); 188 } 189 } 190 191 192 // Type 2 193 if(_.settings.type === 2){ 194 // Ajoute un bouton pour séparer la détection du clique entre le texte et le + 195 $menuMobile.find("."+_.settings.classeSousMenu).each(function(){ 196 if(!$(this).find('> .'+_.settings.classeWrapType2).length){ 197 $(this).append("<a href='##' class='"+_.settings.classeBtnType2+"'><span></span></a>"); 198 $(this).children(":not(ul)").wrapAll("<div class='"+_.settings.classeWrapType2+"'></div>"); 199 } 200 }); 201 202 // Ouvre les sous-menus actifs 203 $menuMobile.find("."+_.settings.classeSousMenu+".actif > ul").slideDown(); 204 205 // Toggle des sous-menus 206 $menuMobile.find("."+_.settings.classeBtnType2).on('click',function(e){ 207 $this = $(this).closest("."+_.settings.classeSousMenu); 208 _.toggleSousMenu($this,e); 209 }); 210 } 211 212 213 // Type 3 214 if(_.settings.type === 3){ 215 // Duplication du lien contenant le sous-menu 216 $menuMobile.find("."+_.settings.classeSousMenu+" > a").each(function(){ 217 $(this).clone().prependTo($(this).next("ul")).wrap("<li class='vMenu-clone'></li>"); 218 }); 219 220 221 // Déplace les sous-menus et les organise un à la suite de l'autre 222 var decompteNiv1 = 0; 223 $menuMobile.find(" > ul:first-child").addClass("actif"); 224 $menuMobile.find(" > ul > li > ul").each(function(){ 225 var decompteNiv2 = 0; 226 decompteNiv1++; 227 228 $(this).parent("."+_.settings.classeSousMenu).attr("data-niv","1-"+decompteNiv1); 229 $(this).attr("id","niv1-"+decompteNiv1).appendTo($menuMobile).addClass("niv1"); 230 231 // Ajoute le lien de retour 232 $(this).prepend("<li><a href='#' class='"+_.settings.classeLienRetour+"'>"+_.settings.texteLienRetour[_.settings.langue]+"</a></li>"); 233 234 $(this).find("ul").each(function(){ 235 decompteNiv2++; 236 $(this).parent("."+_.settings.classeSousMenu).attr("data-niv","2-"+decompteNiv2); 237 $(this).attr("id","niv2-"+decompteNiv2).appendTo($menuMobile).addClass("niv2"); 238 239 // Ajoute le lien de retour 240 $(this).prepend("<li><a href='#' class='"+_.settings.classeLienRetour+"'>"+_.settings.texteLienRetour[_.settings.langue]+"</a></li>"); 241 });
242 }); 243 244 // Toggle des sous-menus 245 $menuMobile.find("."+_.settings.classeSousMenu+" > a").on('click',function(e){ 246 _.toggleSousMenu($(this),e); 247 }); 248 249 // Retour à l'arrière 250 $menuMobile.find("a."+_.settings.classeLienRetour).on('click',function(e){ 251 e.preventDefault(); 252 253 // Niveau 1 254 if($(this).closest("ul").hasClass("niv1")){ 255 $menuMobile.find("ul:first-child").removeClass("menuPrec"); 256 // Niveau 2 257 } else if($(this).closest("ul").hasClass("niv2")){ 258 $menuMobile.find("ul.niv1").removeClass("menuPrec"); 259 } 260 $(this).closest("ul").removeClass("actif"); 261 }); 262 } 263 }, 264 setIconTitle: function ($this,e) { 265 var _ = this; 266 267 // Attribut le "title" du bouton menu selon la langue et l'état du menu 268 if(_.isOpen){ 269 $("#"+_.settings.idIcone).attr("title",_.settings.texteIconeMenu["fermer"][_.settings.langue]); 270 }else{ 271 $("#"+_.settings.idIcone).attr("title",_.settings.texteIconeMenu["ouvrir"][_.settings.langue]); 272 } 273 }, 274 toggleSousMenu: function ($this,e) { 275 var _ = this; 276 277 // Type 3 Vertical seulement 278 if(_.settings.type === 3){ 279 if($this.parent("."+_.settings.classeSousMenu)){ 280 e.preventDefault(); 281 282 var idNiv = "niv"+$this.parent("."+_.settings.classeSousMenu).data("niv"); 283 $this.closest("ul").addClass("menuPrec"); 284 $("#"+idNiv).addClass("actif"); 285 } 286 287 // Types 1 et 2 288 }else{ 289 e.preventDefault(); 290 291 $this.siblings().removeClass("actif").find("ul").stop(1,1).slideUp().closest("."+_.settings.classeSousMenu).removeClass("actif"); 292 293 if(!$this.hasClass("actif")){ 294 $this.addClass("actif").find("> ul").stop(1,1).slideDown(); 295 }else{ 296 $this.removeClass("actif").find("ul").stop(1,1).slideUp().closest("."+_.settings.classeSousMenu).removeClass("actif"); 297 } 298 e.stopPropagation(); 299 } 300 }, 301 moveMenuH: function () { 302 // Mode horizontal seulement 303 304 var _ = this; 305 306 // Déplace le menu vers le haut pour le cacher à sa pleine hauteur 307 if($(_.element).hasClass(_.settings.classeMobile) && !_.isOpen){ 308 $(_.element).css("marginTop","-"+$(_.element).innerHeight()+"px"); 309 }else if($(_.element).hasClass(_.settings.classeMobile) && _.isOpen){ 310 $(_.element).css("marginTop",""); 311 }else{ 312 $(_.element).css({"marginTop":"","height":""}); 313 } 314 }, 315 checkMenuH: function () { 316 // Mode horizontal seulement 317 318 var _ = this; 319 320 // Détecte lorsqu'on passe en mode bureau pour afficher le bon menu 321 322 // window.innerWidth n'est pas supporté dans IE8 323 var largeurDocument = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; 324 325 if($(_.element).hasClass(_.settings.classeMobile) && largeurDocument >= _.settings.largeurBureau){ 326 $(_.element).removeClass(_.settings.classeMobile); 327 $(_.element).addClass(_.settings.classeBureau); 328 _.toggleState("fermer"); 329 }else if($(_.element).hasClass(_.settings.classeBureau) && largeurDocument < _.settings.largeurBureau){ 330 $(_.element).removeClass(_.settings.classeBureau); 331 $(_.element).addClass(_.settings.classeMobile); 332 } 333 if(largeurDocument < _.settings.largeurBureau){ 334 // Place le menu au cas on change d'orientation 335 _.moveMenuH(); 336 } 337 }, 338 toggleState: function (action) { 339 var _ = this; 340 341 // La classe "_.settings.classeAnimation" est utilisé pour l'animation du menu. 342 // Elle doit être retirée aussitôt terminée pour éviter des bugs visuelles 343 344 // Ouverture du menu 345 if(action === "ouvrir"){ 346 // Vertical 347 if(_.settings.mode === "vertical"){ 348 _.isOpen = true; 349 $("html").addClass(_.settings.classeOuverture+" "+_.settings.classeAnimation); 350 setTimeout(function(){ 351 $("html").removeClass(_.settings.classeAnimation); 352 },500); 353 354 /* Si le menu est ouvert, option de glisser/taper pour fermer */ 355 $(document).swipe({ 356 swipeLeft:function() { 357 // Menu gauche 358 _.isOpen && _.settings.position === "gauche" ? _.toggleState("fermer") : ""; 359 }, 360 swipeRight:function() { 361 // Menu droite 362 _.isOpen && _.settings.position === "droite" ? _.toggleState("fermer") : ""; 363 }, 364 tap:function(event, target) { 365 // Extérieur du menu 366 !$(target).closest("#"+_.settings.idMobile+",#"+_.settings.idIcone).length && _.isOpen ? _.toggleState("fermer") : ""; 367 }, 368 threshold:5 369 });
370 // Horizontal 371 }else if(_.settings.mode === "horizontal"){ 372 _.isOpen = true; 373 $("html").addClass(_.settings.classeOuverture+" "+_.settings.classeAnimation); 374 _.moveMenuH(); 375 setTimeout(function(){ 376 $("html").removeClass(_.settings.classeAnimation); 377 },500); 378 } 379 } 380 381 // Fermeture du menu 382 if(action === "fermer"){ 383 // Vertical 384 if(_.settings.mode === "vertical"){ 385 _.isOpen = false; 386 $("html").addClass(_.settings.classeAnimation).removeClass(_.settings.classeOuverture); 387 setTimeout(function(){ 388 $("html").removeClass(_.settings.classeAnimation); 389 },500); 390 391 // Retire la détection du swipe pour éviter des problèmes 392 $(document).swipe("destroy"); 393 // Horizontal 394 }else if(_.settings.mode === "horizontal"){ 395 _.isOpen = false; 396 $("html").addClass(_.settings.classeAnimation).removeClass(_.settings.classeOuverture); 397 398 // Retire le "display:block" pour les sous-menus 399 $(_.element).find("."+_.settings.classeSousMenu).removeClass("actif").find("ul").css("display","").closest("."+_.settings.classeSousMenu).removeClass("actif"); 400 401 _.moveMenuH(); 402 403 setTimeout(function(){ 404 $("html").removeClass(_.settings.classeAnimation); 405 },500); 406 } 407 } 408 409 // Change le titre du bouton menu 410 _.setIconTitle(); 411 }, 412 update: function () { 413 // Réinitialise le plugin 414 var _ = this; 415 // Retire le click sur le bouton du menu 416 $(document).off('click', "#"+_.settings.idIcone); 417 // Menu mobile vertical 418 if(_.settings.mode === "vertical"){ 419 var $menuMobile = $("#"+_.settings.idMobile); 420 // Menu mobile horizontal 421 }else if (_.settings.mode === "horizontal"){ 422 var $menuMobile = $(_.element); 423 } 424 // Retire le click sur les liens 425 $menuMobile.find("."+_.settings.classeSousMenu+" > a").off('click'); 426 // Retire toutes les classes ajoutées au html 427 $("html").removeClass('vMenu-droit vMenu-v-1 vMenu-v-2 vMenu-v-3 vMenu-h-1 vMenu-h-2'); 428 // Supprime les <li> étant dupliqué dans les types 1 et 3 429 $(".vMenu-clone").remove(); 430 // Supprime le bouton et le wrap ajoutés par le type 2 431 $(_.element).find("."+_.settings.classeWrapType2).children().unwrap(); 432 $(_.element).find("."+_.settings.classeBtnType2).remove(); 433 // Supprime le menu mobile dupliqué dans le menu horizontal 434 $("#"+_.settings.idMobile).remove(); 435 // Réinitialise 436 _.init(); 437 } 438 }); 439 440 441 // A really lightweight plugin wrapper around the constructor, 442 // preventing against multiple instantiations 443 $.fn[ pluginName ] = function ( options ) { 444 this.each(function() { 445 if ( !$.data( this, "plugin_" + pluginName ) ) { 446 $.data( this, "plugin_" + pluginName, new Plugin( this, options ) ); 447 } 448 }); 449 450 // chain jQuery functions 451 return this; 452 }; 453 454 455})( jQuery, window, document );
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.