1//Ajax 2var urlAjax = js_params.ajaxurl; 3 4//Scroll 5var scroll_inicial = 0; 6var scroll_contador = 0; 7var scroll_ga = 1; 8var scroll_pos_init = 0; 9 10//Arranque 11 12jQuery(document).ready(function () { 13 jQuery(".choice input").change(function () { 14 if (jQuery(".choice input.kitepos[type=radio]").is(":checked")) { 15 jQuery(".add-cart-product-qty").removeClass("d-flex").addClass("d-none"); 16 jQuery(".btn-cart").removeClass("d-flex").addClass("d-none"); 17 jQuery("#btn-kit").show(); 18 } else { 19 jQuery(".add-cart-product-qty").removeClass("d-none").addClass("d-flex"); 20 jQuery(".btn-cart").removeClass("d-none").addClass("d-flex"); 21 jQuery("#btn-kit").hide(); 22 jQuery("#form-kit").hide(); 23 } 24 }); 25 26 //Añadimos los enlaces legales a los formularios 27 if (jQuery(".gf-legal a").length) { 28 jQuery(".gf-legal a").each(function (index) { 29 var link = ""; 30 if (jQuery(".link-politica-privacidad").attr("href")) { 31 //Si el botón está en un menú 32 link = jQuery(this).attr("href"); 33 } else { 34 link = jQuery(this).find("a").attr("href"); 35 } 36 37 jQuery(this).attr("href", link); 38 jQuery(this).attr("target", "_blank"); 39 }); 40 } 41 //Añadimos La página a los envÃos de formulario 42 if (jQuery(".gf-page").length) { 43 jQuery(".gf-page").each(function (index) { 44 var $input = jQuery(this).find("input"); 45 $input.val(document.title); 46 }); 47 } 48 49 //Cookies 50 if (!localStorage.getItem("cookies")) { 51 jQuery(".cookies").css("display", "block"); 52 jQuery(".cookies-boton").click(function (e) { 53 localStorage.setItem("cookies", "activa"); 54 jQuery(".cookies").slideUp("fast"); 55 return false; 56 }); 57 } 58 //GTM envÃo confirmación 59 jQuery(document).bind("gform_confirmation_loaded", function (event, formId) { 60 gtm_tipo = "gtm-pageview"; 61 gtm_pag_pag = "/gracias-page" + window.location.pathname; 62 gtm_pag_tit = "Gracias - " + document.title; 63 gtm_pasar(); 64 }); 65 66 //Añadimos los cierres a los desplegables 67 if (jQuery(".desplegable-lat").length) { 68 jQuery(".desplegable-lat").each(function (index) { 69 var id = jQuery(this).attr("id"); 70 jQuery(this).append( 71 '<a href="javascript:void(0)" class="desplegable-fondo desplegable-plegar" data-obj="#' + 72 id + 73 '"></a>', 74 ); 75 jQuery(this) 76 .find(".desplegable-lat-bloque-contain") 77 .append( 78 '<a href="javascript:void(0)" class="desplegable-plegar btn-cerrar" data-obj="#' + 79 id + 80 '"><span class="fa fa-times" aria-hidden="true"></span></a>', 81 ); 82 }); 83 } 84 85 if (jQuery(".popup").length) { 86 jQuery(".popup").each(function (index) { 87 var id = jQuery(this).attr("id"); 88 if (!jQuery(this).find("desplegable-fondo").length) { 89 jQuery(this) 90 .find(".popup-bloque") 91 .append( 92 '<a href="javascript:void(0)" class="desplegable-fondo desplegable-plegar" data-obj="#' + 93 id + 94 '"></a>', 95 ); 96 } 97 if (!jQuery(this).find(".btn-cerrar").length) { 98 jQuery(this) 99 .find(".popup-bloque-contain") 100 .append( 101 '<a href="javascript:void(0)" class="desplegable-plegar btn-cerrar" data-obj="#' + 102 id + 103 '"><span class="fa fa-times" aria-hidden="true"></span></a>', 104 ); 105 } 106 }); 107 } 108 109 //Añadimos el botón para desplegar los submenús verticales 110 if (jQuery(".menu-ver .menu-item-has-children").length) { 111 jQuery(".menu-ver .menu-item-has-children").each(function (index) { 112 var btn = '<div class="menu-ver-btn"></div>'; 113 jQuery(this).append(btn); 114 }); 115 } 116 117 //Animaciones Scroll 118 scroll_pos_init = jQuery(window).scrollTop() + jQuery(window).height(); 119 posScroll(); 120 let posScrollTicking = false; 121 jQuery(window).scroll(function () { 122 if (!posScrollTicking) { 123 window.requestAnimationFrame(function () { 124 posScroll(); 125 posScrollTicking = false; 126 }); 127 posScrollTicking = true; 128 } 129 }); 130 131 //Resize 132 maquetacion(); 133 jQuery(window).resize(maquetacion); 134 135 // Cerrar menú on click fuera 136 jQuery(document).click(function (event) { 137 var click = jQuery(event.target); 138 var _open = jQuery(".navbar-collapse").hasClass("show"); 139 if (_open === true && !click.hasClass("navbar-toggler")) { 140 jQuery(".navbar-toggler").click(); 141 } 142 }); 143 144 let closedCats = true; 145 jQuery(".colapsar-categorias-blog").click(function () { 146 if (closedCats) { 147 jQuery(this) 148 .find("i") 149 .removeClass("fa-chevron-down") 150 .addClass("fa-chevron-up"); 151 jQuery(this).find(".colapse-vermas").addClass("d-none"); 152 jQuery(this).find(".colapse-vermenos").removeClass("d-none"); 153 closedCats = false; 154 } else { 155 jQuery(this) 156 .find("i") 157 .removeClass("fa-chevron-up") 158 .addClass("fa-chevron-down"); 159 jQuery(this).find(".colapse-vermenos").addClass("d-none"); 160 jQuery(this).find(".colapse-vermas").removeClass("d-none"); 161 closedCats = true; 162 } 163 }); 164}); 165 166jQuery(document).on("updated_checkout", function () { 167 //Inicializamos popover 168 jQuery('[data-toggle="popover"]').popover({ html: true });
169 jQuery(document).on("show.bs.popover", function () { 170 jQuery(".popover").not(this).popover("hide"); 171 }); 172}); 173 174jQuery(document).on("gform_post_render", function (e, f, p) { 175 let placeholder = "¿En qué estás interesado?"; 176 if (window.location.href.indexOf("lojahusqvarna") > -1) { 177 placeholder = "Que temas lhe interessam?"; 178 } 179 jQuery(".jquery-multiselect select").multiSelect({ 180 // Custom templates 181 containerHTML: '<div class="multi-select-container">', 182 menuHTML: '<div class="multi-select-menu">', 183 buttonHTML: '<span class="multi-select-button">', 184 menuItemsHTML: '<div class="multi-select-menuitems">', 185 menuItemHTML: '<label class="multi-select-menuitem">', 186 presetsHTML: '<div class="multi-select-presets">', 187 188 // sets some HTML (eg: <div class="multi-select-modal">) to enable the modal overlay. 189 modalHTML: undefined, 190 191 // Active CSS class 192 activeClass: "multi-select-container--open", 193 194 // Text to show when no option is selected 195 noneText: placeholder, 196 197 // Text to show when all options are selected 198 allText: undefined, 199 200 // an array of preset option groups 201 // presets: [{ 202 // name: 'All categories', 203 // all: true // select all 204 // },{ 205 // name: 'My categories', 206 // options: ['a', 'c'] 207 // }] 208 presets: undefined, 209 210 // CSS class added to the container, when the menu is about to extend beyond the right edge of the position<a href="https://www.jqueryscript.net/menu/">Menu</a>Within element 211 positionedMenuClass: "multi-select-container--positioned", 212 213 // If you provide a jQuery object here, the plugin will add a class (see positionedMenuClass option) to the container when the right edge of the dropdown menu is about to extend outside the specified element, giving you the opportunity to use CSS to prevent the menu extending, for example, by allowing the option labels to wrap onto multiple lines. 214 positionMenuWithin: undefined, 215 216 // The plugin will attempt to keep this distance, in pixels, clear between the bottom of the menu and the bottom of the viewport, by setting a fixed height style if the menu would otherwise approach this distance from the bottom edge of the viewport. 217 viewportBottomGutter: 20, 218 219 // minimal height 220 menuMinHeight: 200, 221 }); 222}); 223 224//------------------------------------------------------------------------- Scroll 225function posScroll() { 226 var nav_ancho = jQuery(window).width(); 227 var nav_alto = jQuery(window).height(); 228 var scroll_pos = jQuery(window).scrollTop(); 229 230 var $header = jQuery(".header"); 231 if (scroll_pos > 30) { 232 $header.addClass("header-scroll"); 233 234 if (scroll_pos > 200) { 235 jQuery(".comprar-flotante").addClass("add-cart-product-float"); 236 if (scroll_pos <= scroll_inicial) { 237 $header.removeClass("header-scroll-hide"); 238 } else { 239 $header.addClass("header-scroll-hide"); 240 scroll_contador = 0; 241 } 242 } 243 //Desplazador 244 jQuery(".desplazador-top").addClass("desplazador-top-show"); 245 } else { 246 $header.removeClass("header-scroll header-scroll-hide"); 247 jQuery(".desplazador-top").removeClass("desplazador-top-show"); 248 jQuery(".comprar-flotante").removeClass("add-cart-product-float"); 249 scroll_inicial = 0; 250 } 251 252 //Animaciones Scroll 253 jQuery(".anim-scroll").each(function (index) { 254 var pos = jQuery(this).offset().top; 255 var pos_anim = scroll_pos + nav_alto; 256 if (scroll_pos_init > pos) { 257 jQuery(this).addClass("anim-start"); 258 } else if (pos <= pos_anim) { 259 jQuery(this).addClass("anim-start"); 260 } 261 }); 262 263 //Delimitador 264 scroll_inicial = scroll_pos; 265} 266 267//---------------------------------------------------------------------------------------------------------- Maquetación 268function maquetacion() {} 269 270//----------------------------------------------------------------------------------------------------------- Formulario 271 272jQuery(document).on("gform_post_render", function (e, f, p) { 273 jQuery("#gform_ajax_frame_" + f).attr("src", "about:blank"); //Prevenimos que se envién duplicados en el formulario 274}); 275//------------------------------------------------------------------------------------------------------------ MENÃS 276 277//--------- Mostrar submenus horizontales 278jQuery(document).on( 279 "mouseenter", 280 ".menu-hor.menu-pc .menu-item-has-children", 281 function (e) { 282 if (jQuery("body").css("overflow") != "hidden") { 283 var $obj = jQuery(this).find("> .sub-menu"); 284 $obj.slideDown("fast", function () { 285 jQuery($obj).css("overflow", "visible"); 286 }); 287 } 288 }, 289); 290 291jQuery(document).on( 292 "mouseleave", 293 ".menu-hor.menu-pc .menu-item-has-children", 294 function (e) { 295 if (jQuery("body").css("overflow") != "hidden") { 296 var $obj = jQuery(this).find("> .sub-menu"); 297 $obj.slideUp(0); 298 } 299 }, 300); 301 302//--------- Mostrar submenus Verticales 303jQuery(document).on( 304 "click", 305 ".menu-ver .menu-item-has-children .menu-ver-btn", 306 function (e) { 307 var $obj = jQuery(this).siblings(".sub-menu");
308 if (jQuery(this).parent().attr("data-estado")) { 309 $obj.slideUp("fast"); 310 jQuery(this).parent().removeAttr("data-estado"); 311 } else { 312 $obj.slideDown("fast", function () { 313 jQuery($obj).css("overflow", "visible"); 314 }); 315 jQuery(this).parent().attr("data-estado", "on"); 316 } 317 }, 318); 319 320//------------------------------------------------------------------------------------------------------------ DESPLEGABLES LATERALES 321 322jQuery(document).on("click", ".desplegable-desplegar", function (e) { 323 var obj = jQuery(this).attr("data-obj"); 324 obj; 325 var $obj = jQuery(obj); 326 327 //Si hay que cambiar el texto 328 if (jQuery(this).data("txt-off")) { 329 jQuery(this).html(jQuery(this).data("txt-off")); 330 } 331 332 //Si hay que cambiar iconos 333 if (jQuery(this).data("ico-on") && jQuery(this).data("ico-off")) { 334 jQuery(this).find(".fa").removeClass(jQuery(this).data("ico-off")); 335 jQuery(this).find(".fa").addClass(jQuery(this).data("ico-on")); 336 } 337 338 //Cambio de elemento si tiene cierre 339 if ( 340 jQuery(this).data("txt-on") || 341 jQuery(this).data("ico-on") || 342 jQuery(this).data("off") 343 ) { 344 jQuery(this).removeClass("desplegable-desplegar"); 345 jQuery(this).addClass("desplegable-plegar"); 346 } 347 348 //Función de despliege 349 desplegar_desplegable($obj); 350 351 event.preventDefault(); 352}); 353 354function desplegar_desplegable($obj) { 355 if ($obj.hasClass("desplegable-lat")) { 356 //Si es botón lateral 357 $obj.addClass("desplegable-lat-visible"); 358 } else if ($obj.hasClass("popup")) { 359 //Si es botón lateral 360 $obj.fadeIn("fast"); 361 } else { 362 //Si es desplegable simple 363 $obj.slideDown("fast", function () { 364 jQuery($obj).css("overflow", "visible"); 365 }); 366 jQuery(this).removeClass("desplegable-desplegar"); 367 jQuery(this).addClass("desplegable-plegar"); 368 } 369 370 //Si hay fondo oscuro 371 if ($obj.find(".desplegable-fondo").length) { 372 $obj.find(".desplegable-fondo").fadeIn("800"); 373 jQuery("body").css({ 374 height: "100%", 375 overflow: "hidden", 376 }); 377 } 378} 379 380//--------- Desplegable Plegar 381jQuery(document).on("click", ".desplegable-plegar", function (e) { 382 e.preventDefault(); 383 // Buscamos el popup padre más cercano 384 var $popup = jQuery(this).closest(".popup"); 385 if ($popup.length) { 386 $popup.fadeOut("fast"); 387 // Si hay fondo, lo cerramos también 388 $popup.find(".desplegable-fondo").fadeOut("800"); 389 jQuery("body").css({ height: "auto", overflow: "visible" }); 390 } 391}); 392jQuery(document).on("click", ".desplegable-plegar", function (e) { 393 var obj = jQuery(this).attr("data-obj"); 394 var $obj = jQuery(obj); 395 396 if ($obj.hasClass("desplegable-lat")) { 397 //Si es botón lateral 398 $obj.removeClass("desplegable-lat-visible"); 399 } else if ($obj.hasClass("popup")) { 400 //Si es botón lateral 401 $obj.fadeOut("fast"); 402 } else { 403 //Si es desplegable simple 404 $obj.slideUp("fast"); 405 if (jQuery(this).data("txt-on") || jQuery(this).data("ico-on")) { 406 jQuery(this).removeClass("desplegable-plegar"); 407 jQuery(this).addClass("desplegable-desplegar"); 408 } 409 } 410 411 //Si hay fondo oscuro 412 if ($obj.find(".desplegable-fondo").length) { 413 $obj.find(".desplegable-fondo").fadeOut("800"); 414 jQuery("body").css({ 415 height: "auto", 416 overflow: "visible", 417 }); 418 } 419 420 //Si hay que cambiar el texto 421 if (jQuery(this).data("txt-on")) { 422 jQuery(this).html(jQuery(this).data("txt-on")); 423 } 424 425 //Si hay que cambiar iconos 426 if (jQuery(this).data("ico-on") && jQuery(this).data("ico-off")) { 427 jQuery(this).find(".fa").removeClass(jQuery(this).data("ico-on")); 428 jQuery(this).find(".fa").addClass(jQuery(this).data("ico-off")); 429 } 430 431 event.preventDefault(); 432}); 433 434//----------------------------------------------------------------------------------------------------------- Ocultar menú 435jQuery(document).on("click", ".menu-item > a", function (e) { 436 //Revisamos si el menú lateral esta desplegado 437 if (jQuery("body").css("overflow") == "hidden" && jQuery(this).attr("href")) { 438 jQuery("#header-contenedor-movil").css("right", "-100%"); 439 jQuery(".desplegable-fondo").fadeOut("800"); 440 jQuery(".desplegable-fondo").removeClass("desplegable-lat-plegar"); 441 jQuery("body").css({ 442 height: "auto", 443 overflow: "visible", 444 });
445 } 446}); 447 448//----------------------------------------------------------------------------------------------------------- Desplazar 449jQuery(document).on("click", ".desplazar", function (e) { 450 var destino = ""; 451 452 if (jQuery(this).attr("href")) { 453 //Si el botón está en un menú 454 destino = jQuery(this).attr("href"); 455 } else { 456 destino = jQuery(this).find("a").attr("href"); 457 } 458 459 //Revisamos si tiene una url completa 460 if (destino.indexOf("http") == -1) { 461 //Eliminamos la URL 462 destino = destino.split("#"); 463 destino = "#" + destino[1]; 464 } 465 466 //Revisamos si el menú lateral esta desplegado 467 if (jQuery("body").css("overflow") == "hidden") { 468 jQuery("#header-contenedor-movil").css("right", "-100%"); 469 jQuery(".desplegable-fondo").fadeOut("800"); 470 jQuery(".desplegable-fondo").removeClass("desplegable-lat-plegar"); 471 jQuery("body").css({ 472 height: "auto", 473 overflow: "visible", 474 }); 475 } 476 477 //REvisamos si existe el elemento en página para efectuar la animación 478 if (destino == "#") { 479 jQuery("body,html").animate({ scrollTop: 0 }, 500); 480 return false; 481 } else if (jQuery(destino).length) { 482 var distancia = jQuery(destino).offset().top - 20; 483 jQuery("body,html").animate({ scrollTop: distancia - 50 }, 500); 484 return false; 485 } 486}); 487 488//***************************************************************************************************************Recuperar parámetros 489 490function getParameterByName(name) { 491 //Recuperar el modo de llegada 492 name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); 493 var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), 494 results = regex.exec(location.search); 495 return results === null 496 ? "" 497 : decodeURIComponent(results[1].replace(/\+/g, " ")); 498} 499 500//***************************************************************************************************************limpiar Cadenas()*/ 501function limpiar_cadena(cadena) { 502 // Definimos los caracteres que queremos eliminar 503 var specialChars = "¡!@#$^&%*()+[]{}|:<>¿."; 504 // Los eliminamos todos 505 for (var i = 0; i < specialChars.length; i++) { 506 cadena = cadena.replace(new RegExp("\\" + specialChars[i], "gi"), ""); 507 } 508 // Lo queremos devolver limpio en minusculas 509 cadena = cadena.toLowerCase(); 510 // Quitamos espacios y los sustituimos por _ porque nos gusta mas asi 511 cadena = cadena.replace(/ /g, "_"); 512 // Quitamos acentos y "ñ". Fijate en que va sin comillas el primer parametro 513 cadena = cadena.replace(/-/gi, "_"); 514 cadena = cadena.replace(/,/gi, "|"); 515 cadena = cadena.replace(/á/gi, "a"); 516 cadena = cadena.replace(/é/gi, "e"); 517 cadena = cadena.replace(/Ã/gi, "i"); 518 cadena = cadena.replace(/ó/gi, "o"); 519 cadena = cadena.replace(/ú/gi, "u"); 520 cadena = cadena.replace(/ñ/gi, "n"); 521 cadena = cadena.replace(/Å/gi, "n"); 522 523 return cadena; 524} 525 526function solo_numeros(cadena) { 527 // Definimos los caracteres que queremos eliminar 528 cadena = cadena.replace(/[^\d]/, ""); 529 cadena = cadena.replace(/ /g, ""); 530 cadena = cadena.replace(/ /g, ""); 531 cadena = cadena.substr(5, cadena.length); 532 return cadena; 533} 534 535//***************************************************************************************************************Fechas()*/ 536function conseguir_fecha() { 537 var f = new Date(); 538 var f_ano = f.getFullYear(); 539 var f_mes = f.getMonth() + 1; 540 var f_dia = f.getDate(); 541 var f_hora = f.getHours(); 542 var f_min = f.getMinutes(); 543 var f_seg = f.getSeconds(); 544 var fecha_final = "" + f_ano + f_mes + f_dia + f_hora + f_min + f_seg; 545 return fecha_final; 546} 547 548//***************************************************************************************************************AnalÃtica*/ 549var gtm_tipo = undefined; 550var gtm_ev_cat = undefined; 551var gtm_ev_act = undefined; 552var gtm_ev_lab = undefined; 553var gtm_pag_pag = undefined; 554var gtm_pag_tit = undefined; 555 556function gtm_limpiar() { 557 gtm_tipo = undefined; 558 gtm_ev_cat = undefined; 559 gtm_ev_act = undefined; 560 gtm_ev_lab = undefined; 561 gtm_pag_pag = undefined; 562 gtm_pag_tit = undefined; 563} 564 565function gtm_pasar() { 566 dataLayer.push({ 567 event: gtm_tipo, 568 event_data: {
569 category: gtm_ev_cat, 570 action: gtm_ev_act, 571 label: gtm_ev_lab, 572 }, 573 pageview_data: { 574 page: gtm_pag_pag, 575 title: gtm_pag_tit, 576 }, 577 }); 578 579 gtm_limpiar(); 580} 581 582//----------------------------------------------------------------------------------------------------------- Seguimiento de contactos 583jQuery(document).on("click", ".link-contacto a", function (e) { 584 gtm_tipo = "gtm-event"; 585 gtm_ev_cat = "contacto"; 586 gtm_ev_act = "clic"; 587 gtm_ev_lab = "link"; 588 gtm_pasar(); 589}); 590 591jQuery(document).on("click", ".link-contacto-a", function (e) { 592 gtm_tipo = "gtm-event"; 593 gtm_ev_cat = "contacto"; 594 gtm_ev_act = "clic"; 595 gtm_ev_lab = "link"; 596 gtm_pasar(); 597}); 598 599//----------------------------------------------------------------------------------------------------------- Btn ver mais categorÃas 600document.addEventListener("DOMContentLoaded", function () { 601 var categoryList = document.querySelector(".category-list"); 602 var btnVerMasCategorias = document.querySelector(".btn-ver-mas-categorias"); 603 604 if (btnVerMasCategorias) { 605 // Solo si el botón existe 606 btnVerMasCategorias.addEventListener("click", function () { 607 var hiddenItems = categoryList.querySelectorAll("li"); 608 609 // Mostrar/ocultar categorÃas según el estado del botón 610 if (btnVerMasCategorias.textContent === "ver mais categorÃas") { 611 hiddenItems.forEach(function (item, index) { 612 if (index >= 3) { 613 item.classList.remove("toggler"); // Mostrar los items 614 } 615 }); 616 btnVerMasCategorias.textContent = "Ver menos categorÃas"; 617 } else { 618 hiddenItems.forEach(function (item, index) { 619 if (index >= 3) { 620 item.classList.add("toggler"); // Ocultar los items 621 } 622 }); 623 btnVerMasCategorias.textContent = "ver mais categorÃas"; 624 } 625 626 // // Hacer scroll a la lista si se colapsa 627 // if (btnVerMasCategorias.textContent === "ver mais categorÃas") { 628 // categoryList.scrollIntoView({ behavior: "smooth" }); 629 // } 630 }); 631 } 632}); 633jQuery(document).ready(function ($) { 634 // Seleccionamos el checkbox y el campo de la empresa 635 var $checkbox = $("#billing_eres_empresa"); 636 var $companyField = $("#billing_company_field"); 637 638 // Comprobamos el estado inicial (si está marcado al cargar la página) 639 if ($checkbox.is(":checked")) { 640 $companyField.removeClass("d-none"); 641 } else { 642 $companyField.addClass("d-none"); 643 } 644 645 // Al cambiar el estado del checkbox 646 $checkbox.on("change", function () { 647 if ($(this).is(":checked")) { 648 $companyField.removeClass("d-none"); 649 } else { 650 $companyField.addClass("d-none"); 651 } 652 }); 653 654 $(document).on("click", ".boton-add-cart-ficha", function (e) { 655 // e.preventDefault(); 656 // console.log("click"); 657 658 const button = this; 659 if (!$(button).hasClass("loading")) { 660 $(button).addClass("loading"); 661 setTimeout(() => $(button).removeClass("loading"), 3700); 662 } 663 }); 664 $(document).on("click", ".single_add_to_cart_button", function (e) { 665 const button = this; 666 if (!$(button).hasClass("loading")) { 667 $(button).addClass("loading"); 668 setTimeout(() => $(button).removeClass("loading"), 3700); 669 } 670 }); 671 jQuery(document.body).on( 672 "added_to_cart", 673 function (e, fragments, cart_hash, $button) { 674 cambio_boton_minicart(); 675 676 jQuery.ajax({ 677 type: "POST", 678 url: urlAjax, 679 data: { action: "cambio_minicart" }, 680 success: function (response) { 681 jQuery("#mini-cart-content").html(response); 682 var $miniCart = jQuery("#mini-cart"); 683 desplegar_desplegable($miniCart); 684 }, 685 }); 686 }, 687 ); 688}); 689document.addEventListener("DOMContentLoaded", function () { 690 document.body.addEventListener("click", function (e) { 691 const trigger = e.target.closest('[data-bs-toggle="popover"]'); 692 if (!trigger) return; 693 694 e.preventDefault(); 695 696 let pop = bootstrap.Popover.getInstance(trigger); 697 if (!pop) { 698 pop = new bootstrap.Popover(trigger, { 699 container: "body", 700 html: true, 701 trigger: "manual", 702 }); 703 pop.show(); 704 } else { 705 pop.toggle(); 706 } 707 }); 708}); 709document.addEventListener("DOMContentLoaded", function () { 710 // Backdrop propio para offcanvasCondiciones (z-index distinto al resto) 711 const offcanvasCondiciones = document.getElementById("offcanvasCondiciones"); 712 if (offcanvasCondiciones) { 713 offcanvasCondiciones.addEventListener("show.bs.offcanvas", function () { 714 requestAnimationFrame(function () { 715 const backdrops = document.querySelectorAll( 716 ".offcanvas-backdrop:not(.offcanvas-backdrop-condiciones)", 717 ); 718 const backdrop = backdrops[backdrops.length - 1]; 719 if (backdrop) backdrop.classList.add("offcanvas-backdrop-condiciones"); 720 }); 721 });
722 } 723}); 724 725document.addEventListener("DOMContentLoaded", function () { 726 document.querySelectorAll(".item-conditions").forEach(function (btn) { 727 btn.addEventListener("click", function () { 728 var condition = this.dataset.condition; 729 730 // Primero ocultar todos 731 document 732 .querySelectorAll("#offcanvasCondiciones [data-condition]") 733 .forEach(function (el) { 734 el.classList.add("d-none"); 735 }); 736 737 // Luego mostrar solo los del condition pulsado 738 document 739 .querySelectorAll( 740 '#offcanvasCondiciones [data-condition="' + condition + '"]', 741 ) 742 .forEach(function (el) { 743 el.classList.remove("d-none"); 744 }); 745 }); 746 }); 747}); 748 749document.addEventListener("DOMContentLoaded", function () { 750 // Navbar sticky al hacer scroll 751 (function () { 752 const navbar = document.querySelector(".navbar"); 753 const topbar = document.querySelector(".w-top-header"); 754 const promoBar = document.querySelector(".promo-bar"); 755 if (!navbar || !topbar) return; 756 757 let topbarHeight = topbar.offsetHeight; 758 let navbarHeight = navbar.offsetHeight; 759 let isSticky = false; 760 761 window.addEventListener("resize", function () { 762 topbarHeight = topbar.offsetHeight; 763 navbarHeight = navbar.offsetHeight; 764 }); 765 766 let ticking = false; 767 window.addEventListener("scroll", function () { 768 if (!ticking) { 769 window.requestAnimationFrame(function () { 770 const scrollY = window.scrollY; 771 if (scrollY > topbarHeight && !isSticky) { 772 navbar.classList.add("navbar-sticky"); 773 if (promoBar) { 774 promoBar.classList.add("promo-bar-sticky"); 775 promoBar.style.top = navbarHeight + "px"; 776 } 777 isSticky = true; 778 } else if (scrollY <= topbarHeight && isSticky) { 779 navbar.classList.remove("navbar-sticky"); 780 if (promoBar) { 781 promoBar.classList.remove("promo-bar-sticky"); 782 promoBar.style.top = ""; 783 } 784 isSticky = false; 785 } 786 ticking = false; 787 }); 788 ticking = true; 789 } 790 }); 791 })(); 792}); 793 794// Eventos del menú 795document.addEventListener("DOMContentLoaded", function () { 796 const megamenu = document.getElementById("offcanvasMegaMenu"); 797 const buscador = document.getElementById("offcanvasBuscador"); 798 const miniCart = document.getElementById("mini-cart"); 799 if (!megamenu) return; 800 801 // Helpers para cerrar cada elemento 802 function closeMegamenu() { 803 if (megamenu.classList.contains("show")) { 804 const inst = bootstrap.Offcanvas.getInstance(megamenu); 805 if (inst) inst.hide(); 806 } 807 } 808 function closeBuscador() { 809 if (buscador && buscador.classList.contains("show")) { 810 buscador.classList.remove("show"); 811 const overlay = document.querySelector(".algolia-overlay.show"); 812 if (overlay) overlay.classList.remove("show"); 813 } 814 } 815 function closeDropdowns() { 816 document.querySelectorAll(".dropdown-menu.show").forEach(function (menu) { 817 const toggle = menu.previousElementSibling; 818 if (toggle) { 819 const dropdown = bootstrap.Dropdown.getInstance(toggle); 820 if (dropdown) dropdown.hide(); 821 } 822 }); 823 } 824 function closeMiniCart() { 825 if (miniCart && miniCart.classList.contains("desplegable-lat-visible")) { 826 miniCart.classList.remove("desplegable-lat-visible"); 827 const fondo = miniCart.querySelector(".desplegable-fondo"); 828 if (fondo) jQuery(fondo).fadeOut("800"); 829 jQuery("body").css({ height: "auto", overflow: "visible" }); 830 } 831 } 832 833 // Al abrir megamenú â cerrar buscador, dropdowns y mini-cart 834 megamenu.addEventListener("show.bs.offcanvas", function () { 835 closeBuscador(); 836 closeDropdowns(); 837 closeMiniCart(); 838 }); 839 840 // Al abrir buscador â cerrar megamenú, dropdowns y mini-cart 841 if (buscador) { 842 const buscadorObserver = new MutationObserver(function () { 843 if (buscador.classList.contains("show")) { 844 closeMegamenu(); 845 closeDropdowns(); 846 closeMiniCart(); 847 addBlur(); 848 } else { 849 removeBlur(); 850 } 851 });
852 buscadorObserver.observe(buscador, { 853 attributes: true, 854 attributeFilter: ["class"], 855 }); 856 } 857 858 // Al hacer click en dropdown â cerrar megamenú, buscador y mini-cart 859 document 860 .querySelectorAll(".navbar-static-links .dropdown-toggle") 861 .forEach(function (toggle) { 862 toggle.addEventListener("click", function () { 863 closeMegamenu(); 864 closeBuscador(); 865 closeMiniCart(); 866 }); 867 }); 868 869 // Al abrir mini-cart â cerrar megamenú, buscador y dropdowns 870 if (miniCart) { 871 const miniCartObserver = new MutationObserver(function () { 872 if (miniCart.classList.contains("desplegable-lat-visible")) { 873 closeMegamenu(); 874 closeBuscador(); 875 closeDropdowns(); 876 } 877 }); 878 miniCartObserver.observe(miniCart, { 879 attributes: true, 880 attributeFilter: ["class"], 881 }); 882 } 883 884 // Toggle columnas megamenú 885 megamenu.addEventListener("click", function (e) { 886 const item = e.target.closest(".megamenu-parent-item"); 887 if (!item) return; 888 889 if (item.dataset.hasChildren === "0") { 890 window.location.href = item.dataset.url; 891 return; 892 } 893 894 const catId = item.dataset.catId; 895 896 megamenu 897 .querySelectorAll(".megamenu-parent-item") 898 .forEach((el) => el.classList.remove("is-active")); 899 item.classList.add("is-active"); 900 901 megamenu 902 .querySelectorAll(".megamenu-child-list") 903 .forEach((el) => el.classList.remove("is-active")); 904 const targetSubcats = megamenu.querySelector( 905 `.megamenu-child-list[data-cat-id="${catId}"]`, 906 ); 907 if (targetSubcats) targetSubcats.classList.add("is-active"); 908 909 megamenu 910 .querySelectorAll(".megamenu-popular-block") 911 .forEach((el) => el.classList.remove("is-active")); 912 const targetPopular = megamenu.querySelector( 913 `.megamenu-popular-block[data-cat-id="${catId}"]`, 914 ); 915 if (targetPopular) targetPopular.classList.add("is-active"); 916 917 megamenu 918 .querySelectorAll(".megamenu-promo-block") 919 .forEach((el) => el.classList.remove("is-active")); 920 const targetBanner = megamenu.querySelector( 921 `.megamenu-promo-block[data-cat-id="${catId}"]`, 922 ); 923 if (targetBanner) targetBanner.classList.add("is-active"); 924 }); 925 926 // Activo en trigger del megamenú 927 const megaMenuTrigger = document.querySelector('[href="#offcanvasMegaMenu"]'); 928 if (megaMenuTrigger) { 929 megamenu.addEventListener("show.bs.offcanvas", function () { 930 megaMenuTrigger.classList.add("active"); 931 }); 932 megamenu.addEventListener("hide.bs.offcanvas", function () { 933 megaMenuTrigger.classList.remove("active"); 934 }); 935 } 936 937 // Activo en dropdowns del walker 938 document 939 .querySelectorAll(".navbar-static-links .dropdown") 940 .forEach(function (li) { 941 li.addEventListener("show.bs.dropdown", function () { 942 li.querySelector(":scope > .dropdown-toggle")?.classList.add("active"); 943 }); 944 li.addEventListener("hide.bs.dropdown", function () { 945 li.querySelector(":scope > .dropdown-toggle")?.classList.remove( 946 "active", 947 ); 948 }); 949 }); 950 951 // Blur de fondo al abrir menús 952 function addBlur() { 953 document.body.classList.add("menu-blur"); 954 } 955 function removeBlur() { 956 const dropdownOpen = document.querySelector( 957 ".navbar-static-links .dropdown-menu.show", 958 ); 959 const megamenuOpen = megamenu.classList.contains("show"); 960 const buscadorOpen = buscador && buscador.classList.contains("show"); 961 if (!dropdownOpen && !megamenuOpen && !buscadorOpen) { 962 document.body.classList.remove("menu-blur"); 963 } 964 } 965 966 megamenu.addEventListener("show.bs.offcanvas", addBlur); 967 megamenu.addEventListener("hidden.bs.offcanvas", removeBlur); 968 969 if (buscador) { 970 buscador.addEventListener("show.bs.offcanvas", addBlur); 971 buscador.addEventListener("hidden.bs.offcanvas", removeBlur); 972 } 973 974 document 975 .querySelectorAll(".navbar-static-links .dropdown") 976 .forEach(function (li) { 977 li.addEventListener("show.bs.dropdown", addBlur); 978 li.addEventListener("hidden.bs.dropdown", removeBlur); 979 });
980}); 981 982document.addEventListener("DOMContentLoaded", function () { 983 const mobileMenu = document.getElementById("offcanvasMobileMenu"); 984 if (!mobileMenu) return; 985 986 const slider = mobileMenu.querySelector(".mobile-menu-slider"); 987 988 function slideToScreen(screen) { 989 if (screen === "subcats") { 990 slider.classList.add("subcats-open"); 991 } else { 992 slider.classList.remove("subcats-open"); 993 } 994 } 995 996 function syncTabs(panelId) { 997 mobileMenu.querySelectorAll(".mobile-menu-tab").forEach((t) => { 998 t.classList.toggle("is-active", t.dataset.panel === panelId); 999 }); 1000 } 1001 1002 function activatePanel(panelId) { 1003 mobileMenu.querySelectorAll(".mobile-panel").forEach((p) => { 1004 p.classList.remove("is-active"); 1005 p.style.cssText = ""; 1006 }); 1007 const target = mobileMenu.querySelector( 1008 `.mobile-panel[data-panel="${panelId}"]`, 1009 ); 1010 if (target) target.classList.add("is-active"); 1011 } 1012 1013 // Cambio de tab 1014 mobileMenu.addEventListener("click", function (e) { 1015 const tab = e.target.closest(".mobile-menu-tab"); 1016 if (!tab) return; 1017 1018 if (tab.dataset.hasChildren === "0") { 1019 window.location.href = tab.dataset.url; 1020 return; 1021 } 1022 1023 const panelId = tab.dataset.panel; 1024 slideToScreen("main"); 1025 syncTabs(panelId); 1026 activatePanel(panelId); 1027 }); 1028 1029 // Click en categorÃa padre â pantalla 2 1030 mobileMenu.addEventListener("click", function (e) { 1031 const catItem = e.target.closest(".mobile-panel-item--cat"); 1032 if (!catItem) return; 1033 1034 if (catItem.dataset.hasChildren === "0") { 1035 window.location.href = catItem.dataset.url; 1036 return; 1037 } 1038 1039 const catId = catItem.dataset.catId; 1040 const catName = catItem.querySelector("span").textContent; 1041 1042 const backLabel = mobileMenu.querySelector("#mobileBackLabel"); 1043 if (backLabel) backLabel.textContent = catName; 1044 1045 mobileMenu 1046 .querySelectorAll(".mobile-subcats-list") 1047 .forEach((l) => l.classList.add("d-none")); 1048 const targetList = mobileMenu.querySelector( 1049 `.mobile-subcats-list[data-cat-id="${catId}"]`, 1050 ); 1051 if (targetList) targetList.classList.remove("d-none"); 1052 1053 mobileMenu 1054 .querySelectorAll(".mobile-popular-block") 1055 .forEach((b) => b.classList.add("d-none")); 1056 const targetPopular = mobileMenu.querySelector( 1057 `.mobile-popular-block[data-cat-id="${catId}"]`, 1058 ); 1059 if (targetPopular) targetPopular.classList.remove("d-none"); 1060 1061 mobileMenu 1062 .querySelectorAll(".mobile-banner-block") 1063 .forEach((b) => b.classList.add("d-none")); 1064 const targetBanner = mobileMenu.querySelector( 1065 `.mobile-banner-block[data-cat-id="${catId}"]`, 1066 ); 1067 if (targetBanner) targetBanner.classList.remove("d-none"); 1068 1069 slideToScreen("subcats"); 1070 }); 1071 1072 // Botón volver 1073 mobileMenu.addEventListener("click", function (e) { 1074 if (!e.target.closest(".mobile-panel-back")) return; 1075 slideToScreen("main"); 1076 }); 1077 1078 // Reset al cerrar 1079 mobileMenu.addEventListener("hidden.bs.offcanvas", function () { 1080 slideToScreen("main"); 1081 slider.style.transition = "none"; 1082 setTimeout(() => { 1083 slider.style.transition = ""; 1084 }, 50); 1085 syncTabs("productos"); 1086 activatePanel("productos"); 1087 mobileMenu 1088 .querySelectorAll(".mobile-subcats-list") 1089 .forEach((l) => l.classList.add("d-none")); 1090 mobileMenu 1091 .querySelectorAll(".mobile-popular-block") 1092 .forEach((b) => b.classList.add("d-none")); 1093 mobileMenu 1094 .querySelectorAll(".mobile-banner-block") 1095 .forEach((b) => b.classList.add("d-none")); 1096 mobileMenu.querySelector("#mobileBackLabel").textContent = ""; 1097 }); 1098}); 1099document.addEventListener("DOMContentLoaded", function () { 1100 // Solo ejecutar si el banner existe (solo en portada) 1101 var bannerSenior = document.getElementById("banner-senior"); 1102 if (!bannerSenior) return; 1103 1104 setTimeout(function () { 1105 bannerSenior.classList.add("activo"); 1106 }, 25000); 1107 1108 document.addEventListener("click", function (e) { 1109 if (!e.target.closest("#banner-senior .close")) return; 1110 bannerSenior.classList.remove("activo"); 1111 }); 1112}); 1113 1114// fav-heart: marca los botones cuyo producto ya está en la wishlist y actualiza icono del header 1115function husqvarnaUpdateWishlistButtons() { 1116 if (typeof husqvarna_wishlist === "undefined" || !Array.isArray(husqvarna_wishlist.ids)) return;
1117 document.querySelectorAll(".fav-heart[data-product-id]").forEach(function(btn) { 1118 var id = parseInt(btn.dataset.productId, 10); 1119 var isAdded = husqvarna_wishlist.ids.indexOf(id) !== -1; 1120 btn.classList.toggle("added", isAdded); 1121 btn.title = isAdded ? "Eliminar dos favoritos" : "Adicionar aos favoritos"; 1122 }); 1123 var favIcon = document.getElementById("header-fav-icon"); 1124 if (favIcon) { 1125 favIcon.src = husqvarna_wishlist.ids.length > 0 ? favIcon.dataset.srcFilled : favIcon.dataset.srcEmpty; 1126 } 1127} 1128 1129// MutationObserver en #hits para re-marcar cuando Algolia re-renderiza (filtros, paginación) 1130document.addEventListener("DOMContentLoaded", function() { 1131 husqvarnaUpdateWishlistButtons(); 1132 var hits = document.getElementById("hits"); 1133 if (hits) { 1134 new MutationObserver(husqvarnaUpdateWishlistButtons).observe(hits, { childList: true, subtree: true }); 1135 } 1136}); 1137 1138// fav-heart: muestra el banner de confirmación con el texto indicado y lo oculta a los 6s 1139// opts.mode: "add" (por defecto, enlace "Ir a favoritos") o "remove" (enlace "Cancelar" para deshacer) 1140function husqvarnaShowFavoritosBanner(text, opts) { 1141 opts = opts || {}; 1142 var bannerFavoritos = document.getElementById("banner-favoritos"); 1143 if (!bannerFavoritos) return; 1144 var bannerFavoritosText = document.getElementById("banner-favoritos-text"); 1145 if (bannerFavoritosText) bannerFavoritosText.textContent = text; 1146 1147 var favLink = bannerFavoritos.querySelector(".fav-link"); 1148 if (favLink) { 1149 if (opts.mode === "remove") { 1150 favLink.textContent = "Cancelar"; 1151 favLink.setAttribute("href", "javascript:void(0)"); 1152 favLink.dataset.action = "cancel-remove"; 1153 favLink.dataset.productId = opts.productId; 1154 } else { 1155 favLink.textContent = "Ir para favoritos"; 1156 favLink.setAttribute("href", "/favoritos/"); 1157 delete favLink.dataset.action; 1158 delete favLink.dataset.productId; 1159 } 1160 } 1161 1162 bannerFavoritos.classList.add("activo"); 1163 clearTimeout(bannerFavoritos._husqvarnaTimeout); 1164 bannerFavoritos._husqvarnaTimeout = setTimeout(function() { 1165 bannerFavoritos.classList.remove("activo"); 1166 }, 6000); 1167} 1168 1169// fav-heart: botón de cierre manual del banner 1170document.addEventListener("click", function(e) { 1171 if (!e.target.closest(".close-fav")) return; 1172 var bannerFavoritos = document.getElementById("banner-favoritos"); 1173 if (!bannerFavoritos) return; 1174 clearTimeout(bannerFavoritos._husqvarnaTimeout); 1175 bannerFavoritos.classList.remove("activo"); 1176}); 1177 1178// fav-heart: añade un producto a la wishlist vÃa AJAX (usado tanto al pulsar el corazón como al cancelar una retirada) 1179function husqvarnaAddToWishlist(id, btn) { 1180 jQuery.ajax({ 1181 type: "POST", 1182 url: husqvarna_wishlist.ajax_url, 1183 data: { action: "husqvarna_add_to_wishlist", product_id: id, nonce: husqvarna_wishlist.nonce }, 1184 success: function(response) { 1185 if (!response.success) return; 1186 if (husqvarna_wishlist.ids.indexOf(id) === -1) husqvarna_wishlist.ids.push(id); 1187 husqvarnaUpdateWishlistButtons(); 1188 if (typeof window.dataLayer !== "undefined" && btn) { 1189 var favPrice = parseFloat(btn.dataset.price) || 0; 1190 window.dataLayer.push({ ecommerce: null }); 1191 window.dataLayer.push({ 1192 event: "add_to_wishlist", 1193 ecommerce: { 1194 currency: "EUR", 1195 value: favPrice, 1196 items: [{ 1197 item_id: btn.dataset.sku || String(id), 1198 item_name: btn.dataset.name || "", 1199 item_brand: "Husqvarna", 1200 item_category: btn.dataset.category || "", 1201 price: favPrice, 1202 quantity: 1 1203 }] 1204 } 1205 }); 1206 } 1207 } 1208 }); 1209} 1210 1211// fav-heart: enlace "Cancelar" del banner â deshace una retirada de favoritos reciente 1212document.addEventListener("click", function(e) { 1213 var cancelLink = e.target.closest('.fav-link[data-action="cancel-remove"]'); 1214 if (!cancelLink) return; 1215 e.preventDefault(); 1216 1217 var id = parseInt(cancelLink.dataset.productId, 10); 1218 if (!id) return; 1219
1220 var btn = document.querySelector('.fav-heart[data-product-id="' + id + '"]'); 1221 husqvarnaAddToWishlist(id, btn); 1222 1223 // Si la fila de favoritos aún no se ha eliminado del DOM, se restaura su visibilidad 1224 var row = document.getElementById("yith-wcwl-row-" + id); 1225 if (row) row.style.opacity = "1"; 1226 1227 var bannerFavoritos = document.getElementById("banner-favoritos"); 1228 if (bannerFavoritos) { 1229 clearTimeout(bannerFavoritos._husqvarnaTimeout); 1230 bannerFavoritos.classList.remove("activo"); 1231 } 1232}); 1233 1234// fav-heart: delegated handler â añade o elimina según estado del botón 1235document.addEventListener("click", function(e) { 1236 var btn = e.target.closest(".fav-heart"); 1237 if (!btn) return; 1238 e.preventDefault(); 1239 e.stopPropagation(); 1240 1241 if (typeof husqvarna_wishlist === "undefined") return; 1242 1243 var productId = btn.dataset.productId || btn.dataset.rowId; 1244 if (!productId) return; 1245 var id = parseInt(productId, 10); 1246 1247 if (!btn.classList.contains("added")) btn.classList.toggle("is-animating"); 1248 1249 if (btn.classList.contains("added")) { 1250 // Eliminar de la wishlist 1251 jQuery.ajax({ 1252 type: "POST", 1253 url: husqvarna_wishlist.ajax_url, 1254 data: { action: "husqvarna_remove_from_wishlist", product_id: id, nonce: husqvarna_wishlist.nonce }, 1255 success: function(response) { 1256 if (response.success) { 1257 var idx = husqvarna_wishlist.ids.indexOf(id); 1258 if (idx !== -1) husqvarna_wishlist.ids.splice(idx, 1); 1259 btn.classList.remove("added"); 1260 husqvarnaUpdateWishlistButtons(); 1261 husqvarnaShowFavoritosBanner("Eliminado dos favoritos.", { mode: "remove", productId: id }); 1262 if (typeof window.dataLayer !== "undefined") { 1263 var favPrice = parseFloat(btn.dataset.price) || 0; 1264 window.dataLayer.push({ ecommerce: null }); 1265 window.dataLayer.push({ 1266 event: "remove_from_wishlist", 1267 ecommerce: { 1268 currency: "EUR", 1269 value: favPrice, 1270 items: [{ 1271 item_id: btn.dataset.sku || String(id), 1272 item_name: btn.dataset.name || "", 1273 item_brand: "Husqvarna", 1274 item_category: btn.dataset.category || "", 1275 price: favPrice, 1276 quantity: 1 1277 }] 1278 } 1279 }); 1280 } 1281 // En la página de favoritos: ocultar y eliminar la card del DOM 1282 var row = document.getElementById("yith-wcwl-row-" + id); 1283 if (row) { 1284 row.style.transition = "opacity 0.3s"; 1285 row.style.opacity = "0"; 1286 setTimeout(function() { row.remove(); }, 300); 1287 } 1288 } 1289 } 1290 }); 1291 } else { 1292 // Añadir a la wishlist 1293 husqvarnaAddToWishlist(id, btn); 1294 husqvarnaShowFavoritosBanner("Adicionado aos favoritos!", { mode: "add" }); 1295 } 1296}, true); // capture phase: interceptamos antes de que el <a> padre procese el click 1297 1298document.addEventListener("touchstart", function(e) { 1299 var btn = e.target.closest(".fav-heart"); 1300 if (btn && !btn.classList.contains("added")) btn.classList.toggle("is-animating"); 1301}, { passive: true }); 1302 1303document.addEventListener("animationend", function(e) { 1304 if (e.target.classList.contains("fav-heart")) e.target.classList.toggle("is-animating"); 1305});
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.