1let isIE, resizeTimer, firstTab = false; 2let bkjs = { 3 commons: { 4 // Declaración correcta sin leak global 5 isIE: false, 6 7 msieversion() { 8 this.isIE = /MSIE|Trident|Edge/.test(window.navigator.userAgent); 9 return this.isIE; 10 }, 11 12 goToIdTarget() { 13 // 1. Inyectar parámetro idtarget en enlaces 14 document.querySelectorAll('[id-target]').forEach((elem) => { 15 const href = elem.getAttribute('href') || ''; 16 const separator = href.includes('?') ? '&' : '?'; 17 const targetId = elem.getAttribute('id-target'); 18 elem.setAttribute('href', `${href}${separator}idtarget=${targetId}`); 19 }); 20 21 // 2. Procesar navegación por idtarget en URL 22 const params = new URLSearchParams(document.location.search); 23 const tabId = params.get('idtarget'); 24 25 if (tabId) { 26 const targetElem = document.getElementById(tabId); 27 if (targetElem) { 28 const button = targetElem.querySelector('button') || targetElem; 29 button.click(); 30 location.href = `#${tabId}`; 31 } 32 } 33 }, 34 35 toggleHeaderSize() { 36 if (this.isIE) return; 37 38 const header = document.querySelector('.header_NW'); 39 if (!header || header.classList.contains('privada_NW')) return; 40 41 const logo = document.getElementById('logo_NW'); 42 const logoIE = document.getElementById('logo_IE_min'); 43 const scrollLimit = 5; 44 45 window.addEventListener('scroll', () => { 46 if (document.body.getBoundingClientRect().width < 990) return; 47 48 const isScrolled = window.pageYOffset > scrollLimit; 49 50 if (logo) logo.classList.toggle('logo_NW_min', isScrolled); 51 header.classList.toggle('min', isScrolled); 52 53 if (logoIE) { 54 const mainLogo = logoIE.querySelector('.logo_IE'); 55 const minLogo = logoIE.querySelector('.logo_IE_min'); 56 57 if (mainLogo) mainLogo.classList.toggle('d-none', isScrolled); 58 if (minLogo) minLogo.classList.toggle('d-none', !isScrolled); 59 } 60 }, { passive: true }); 61 }, 62 63 setMainContentPaddingTop() { 64 const mainContent = document.querySelector('.main-content:not(.blog)'); 65 const headerBkWem = document.querySelector('.header-bk-wem'); 66 const secondLevel = document.querySelector('.secondLevel'); 67 const header = document.querySelector('header'); 68 const reporting = document.querySelector('.header-rp'); 69 70 if (reporting) { 71 document.documentElement.style.height = '100%'; 72 } 73 74 if (header && !headerBkWem && !reporting && mainContent) { 75 let totalPadding = header.getBoundingClientRect().height; 76 if (secondLevel) { 77 totalPadding += secondLevel.getBoundingClientRect().height; 78 } 79 mainContent.style.paddingTop = `${totalPadding}px`; 80 } 81 }, 82 83 cleanMenuRoboadvisor() { 84 document.querySelectorAll('.header-bk-wem__sublistul').forEach((menu) => { 85 if (menu.firstElementChild) { 86 menu.firstElementChild.classList.remove('col-lg-8'); 87 } 88 }); 89 }, 90 91 setMenuActiveOption() { 92 const currentPath = document.location.pathname; 93 94 document.querySelectorAll('.header-bk-wem__sublist-link').forEach((link) => { 95 const isPathMatch = link.pathname === currentPath && !link.href.includes('#'); 96 const isHrefIncluded = currentPath.includes(link.getAttribute('href')); 97 98 if (isPathMatch || isHrefIncluded) { 99 link.setAttribute('header-link-submenu-active', 'true'); 100 } 101 }); 102 103 const activeSubMenu = document.querySelector('.header-bk-wem__sublist-link--active-link'); 104 if (activeSubMenu) { 105 const parentListItem = activeSubMenu.closest('.header-bk-wem__list-item'); 106 if (parentListItem) { 107 const subLink = parentListItem.querySelector('.header-bk-wem__sublist-link'); 108 if (subLink) subLink.classList.add('header-bk-wem__sublist-link--active'); 109 } 110 } 111 }, 112 113 setBodyMarginBottom() { 114 const footer = document.querySelector('.footer'); 115 if (footer) { 116 const isDesktop = document.body.getBoundingClientRect().width > 990; 117 const footerHeight = isDesktop ? footer.getBoundingClientRect().height : 0; 118 document.body.style.marginBottom = `${footerHeight}px`; 119 } 120 }, 121 122 loadingButton() { 123 document.querySelectorAll('.btn--loading').forEach((btn) => { 124 btn.addEventListener('click', (e) => { 125 const target = e.currentTarget; 126 target.classList.add('btn--loading-disabled'); 127 target.setAttribute('disabled', 'true'); 128 }); 129 }); 130 }, 131 132 closeLayer() { 133 document.querySelectorAll('.element-to-close').forEach((layer) => { 134 const closeBtn = layer.querySelector('.close'); 135 if (closeBtn) { 136 closeBtn.addEventListener('click', () => { 137 layer.style.display = 'none'; 138 }); 139 } 140 }); 141 }, 142 143 classesToEl(element, action, className) { 144 if (!element) return; 145 if (action === 'add') element.classList.add(className); 146 else if (action === 'remove') element.classList.remove(className); 147 else if (action === 'toggle') element.classList.toggle(className); 148 }, 149 150 disableButton(element) { 151 if (element) element.setAttribute('disabled', 'true'); 152 }, 153 154 enableButton(element) { 155 if (element) element.removeAttribute('disabled'); 156 }, 157 158 isElementInScreen(selector, jsonArray = []) { 159 const element = document.querySelector(selector); 160 if (!element) return; 161 162 const screenBottom = window.innerHeight; 163 let eventFired = false;
164 165 const checkAndTrigger = () => { 166 if (!eventFired && element.getBoundingClientRect().bottom <= screenBottom) { 167 jsonArray.forEach((json) => bkjs.gtm.doEventAnalyticsPromoViewEEC(json)); 168 eventFired = true; 169 } 170 }; 171 172 checkAndTrigger(); 173 window.addEventListener('scroll', checkAndTrigger, { passive: true }); 174 }, 175 176 isElementContentBoxInScreen(selector, jsonArray = []) { 177 const element = document.querySelector(selector); 178 if (!element) return; 179 180 const marker = element.closest('.content-box'); 181 if (!marker) return; 182 183 const screenBottom = window.innerHeight; 184 let eventFired = false; 185 186 const checkAndTrigger = () => { 187 if (!eventFired && marker.getBoundingClientRect().bottom <= screenBottom) { 188 jsonArray.forEach((json) => bkjs.gtm.doEventAnalyticsPromoViewEEC(json)); 189 eventFired = true; 190 } 191 }; 192 193 checkAndTrigger(); 194 window.addEventListener('scroll', checkAndTrigger, { passive: true }); 195 }, 196 197 mainBannerCarousel() { 198 document.querySelectorAll('.main-banner-carrousel .main-banner__square').forEach((btn) => { 199 btn.addEventListener('click', function () { 200 const firstSlide = this.closest('.main-banner-carrousel__slide:first-child'); 201 if (!firstSlide) return; 202 203 const nextSlide = firstSlide.nextElementSibling; 204 if (nextSlide) { 205 nextSlide.classList.add('active'); 206 firstSlide.classList.remove('active'); 207 208 const lastSlide = document.querySelector('.main-banner-carrousel__slide:last-child'); 209 if (lastSlide) { 210 setTimeout(() => lastSlide.after(firstSlide), 600); 211 } 212 } 213 }); 214 }); 215 }, 216 217 setElementSticky(selector) { 218 const element = document.querySelector(selector); 219 if (!element) return; 220 221 const screenBottom = window.innerHeight; 222 const footer = document.querySelector('.footer') || document.querySelector('.footer-gray'); 223 const footerHeight = footer ? footer.getBoundingClientRect().height : 0; 224 const stickyHeight = element.getBoundingClientRect().height; 225 const featuredBox = document.querySelector('.featured-box'); 226 227 const isBlocked = featuredBox && ( 228 featuredBox.classList.contains('featured-box_sticky--bloqued') || 229 featuredBox.classList.contains('featured-box--sticky-bloqued') 230 ); 231 232 if (isBlocked) { 233 element.classList.add('featured-box_sticky'); 234 return true; 235 } 236 237 window.addEventListener('scroll', () => { 238 let totalHeight; 239 const isDesktop = document.body.getBoundingClientRect().width >= 768; 240 const isSticky = element.classList.contains('featured-box_sticky'); 241 242 if (isDesktop && !isSticky && element.getBoundingClientRect().bottom <= screenBottom) { 243 element.classList.add('featured-box_sticky'); 244 totalHeight = footerHeight + stickyHeight; 245 246 if (footer) { 247 footer.style.paddingBottom = `${stickyHeight}px`; 248 footer.style.bottom = `-${stickyHeight}px`; 249 } 250 } 251 252 const wrapper = element.closest('.featured-box__wrapper'); 253 if (isSticky && wrapper && wrapper.getBoundingClientRect().top > (screenBottom - element.getBoundingClientRect().height)) { 254 element.classList.remove('featured-box_sticky'); 255 } 256 257 if (document.body.getBoundingClientRect().width > 990) { 258 document.body.style.marginBottom = totalHeight ? `${totalHeight}px` : '0px'; 259 } 260 }, { passive: true }); 261 }, 262 263 equalSize(parentSelector, childSelector, extraHeight = 0) { 264 const extra = typeof extraHeight === 'number' ? extraHeight : 0; 265 266 document.querySelectorAll(parentSelector).forEach((parent) => { 267 if (!parent || !parent.firstElementChild) return; 268 269 const isEqualSize = parent.classList.contains('equal-size') || parent.firstElementChild.classList.contains('equal-size'); 270 if (!isEqualSize) return; 271 272 const children = parent.querySelectorAll(childSelector); 273 let maxHeight = 0; 274
275 children.forEach((child) => { 276 child.removeAttribute('style'); 277 const height = child.getBoundingClientRect().height; 278 if (height > maxHeight) maxHeight = height; 279 }); 280 281 maxHeight += extra; 282 const isMobile = window.innerWidth < 576; 283 284 children.forEach((child) => { 285 child.style.height = isMobile ? 'auto' : `${maxHeight}px`; 286 }); 287 }); 288 }, 289 290 equalSizeNoParentElement(selector) { 291 const boxes = document.querySelectorAll(selector); 292 if (!boxes.length) return; 293 294 let maxHeight = 0; 295 boxes.forEach((box) => { 296 const height = box.getBoundingClientRect().height; 297 if (height > maxHeight) maxHeight = height; 298 }); 299 300 boxes.forEach((box) => { 301 box.style.height = `${maxHeight}px`; 302 }); 303 }, 304 305 analyzeFormContent() { 306 const inputGroups = document.querySelectorAll('.form__input-group'); 307 inputGroups.forEach((group) => { 308 const input = group.querySelector('input'); 309 if (input && input.value !== '') { 310 input.classList.add('has-contain'); 311 } 312 }); 313 this.changeFormEvent(inputGroups); 314 }, 315 316 changeFormEvent(groups) { 317 groups.forEach((group) => { 318 const input = group.querySelector('input'); 319 if (!input) return; 320 321 const type = input.getAttribute('type'); 322 if (type === 'button' || type === 'submit') return; 323 324 input.addEventListener('input', function () { 325 this.classList.toggle('has-contain', this.value !== ''); 326 }); 327 }); 328 }, 329 330 setFocusOnOpenedElement(element) { 331 if (element && typeof element.focus === 'function') { 332 element.focus(); 333 } 334 }, 335 336 opinatorPagaComodoAbandono() { 337 try { 338 const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); 339 if (isMobile || window.location.href.includes('creditopagacomodo')) return; 340 341 const flagOpi = sessionStorage.getItem('mostrarOpiPagaComodo'); 342 if (flagOpi !== 'S') return; 343 344 const persCript = sessionStorage.getItem('persCript'); 345 const opiDestino = 'BK-APP-PARTICULARES-PAGACOMODO-ABANDONO'; 346 347 const scriptTag = document.createElement('script'); 348 scriptTag.src = '/res/js/bancaParticulares/opina/opina-min-23.js'; 349 const firstScript = document.getElementsByTagName('script')[0]; 350 firstScript.parentNode.insertBefore(scriptTag, firstScript); 351 352 setTimeout(() => { 353 if (window.OPINATOR) { 354 OPINATOR.mustShowOpi( 355 opiDestino, 356 persCript, 357 () => { 358 OPINATOR.showOpi(opiDestino, persCript); 359 console.log('sat ok'); 360 }, 361 () => console.log('sat ko') 362 ); 363 } 364 }, 2000); 365 366 sessionStorage.removeItem('mostrarOpiPagaComodo'); 367 sessionStorage.removeItem('persCript'); 368 } catch (error) { 369 // Manejo silencioso original 370 } 371 } 372 }, 373 374 animateHeight: { 375 collapseSectionAccesible(element) { 376 if (!element) return; 377 const target = element.nextElementSibling || element; 378 379 // Medir la altura actual antes de colapsar 380 const sectionHeight = target.scrollHeight; 381 const elementTransition = target.style.transition; 382 383 // Preparar el elemento para la transición desde su altura actual 384 target.style.transition = ''; 385 requestAnimationFrame(() => { 386 target.style.height = `${sectionHeight}px`; 387 target.style.transition = elementTransition; 388 389 // En el siguiente frame, colapsamos a 0 390 requestAnimationFrame(() => { 391 target.style.height = '0px'; 392 element.setAttribute('data-collapsed', 'true'); 393 }); 394 }); 395 396 // Ocultar al finalizar la transición o forzar el atributo de accesibilidad 397 target.setAttribute('hidden', 'hidden'); 398 }, 399 400 expandSectionAccesible(element) { 401 if (!element) return; 402 const target = element.nextElementSibling || element; 403 404 target.removeAttribute('hidden'); 405 target.style.height = ''; 406 element.setAttribute('data-collapsed', 'false'); 407 } 408 }, 409 components: { 410 slideRiskIndicator(riskIndicatorId) { 411 const element = document.getElementById(riskIndicatorId); 412 if (!element) return; 413 414 const buttons = element.querySelectorAll('.carousel__controls__button'); 415 const isSpecialIndicator = riskIndicatorId.includes('risk-indicator02b'); 416 const prevElem = element.previousElementSibling; 417 418 if (isSpecialIndicator && prevElem) { 419 let legend = prevElem.querySelector('.risk-indicator-legend'); 420 if (!legend) { 421 legend = document.createElement('div'); 422 legend.className = 'risk-indicator-legend'; 423 legend.textContent = 'Cuenta y Depósito'; 424 prevElem.appendChild(legend); 425 } 426 } 427 428 buttons.forEach((btn) => { 429 btn.addEventListener('click', (e) => { 430 const currentBtn = e.currentTarget; 431 432 // Cambiar botón activo 433 const activeBtn = element.querySelector('.carousel__controls__button.active'); 434 if (activeBtn) activeBtn.classList.remove('active'); 435 currentBtn.classList.add('active'); 436 437 // Eliminar clases 'slide1'..'slide5' de forma limpia 438 element.className = element.className.replace(/\bslide\d+\b/g, '').trim(); 439 440 // Agregar la nueva clase de slide 441 const targetSlide = currentBtn.dataset.slide;
442 if (targetSlide) { 443 element.classList.add(`slide${targetSlide}`); 444 } 445 446 // Actualizar leyenda en caso especial 447 if (isSpecialIndicator && prevElem) { 448 const legend = prevElem.querySelector('.risk-indicator-legend'); 449 if (legend) { 450 legend.textContent = (targetSlide === '3') ? 'Sólo para el Depósito' : 'Cuenta y Depósito'; 451 } 452 } 453 }); 454 }); 455 }, 456 toggleDropdown() { 457 let elements = document.querySelectorAll('.dropdown-toggle'); 458 459 function clickToggleDropdown(e) { 460 this.closest('.dropdown').classList.toggle('opened'); 461 if (this.closest('.dropdown').classList.contains('opened')) { 462 e.currentTarget.setAttribute('aria-expanded', 'true'); 463 bkjs.commons.setFocusOnOpenedElement(this.closest('.dropdown').querySelector('.dropdown-menu')); 464 e.currentTarget.closest('.dropdown').querySelector('.dropdown-menu').querySelectorAll('li')[0].querySelector('a').focus(); 465 } else { 466 e.currentTarget.setAttribute('aria-expanded', 'false'); 467 e.currentTarget.blur(); 468 } 469 } 470 471 function focusDropdown(e) { 472 if (e.keyCode === 38 && document.activeElement === childElements[0]) { 473 e.preventDefault(); 474 e.stopPropagation(); 475 return false; 476 } else { 477 document.activeElement.closest('li').previousElementSibling.querySelector('a').focus(); 478 } 479 if (e.keyCode === 40 && document.activeElement === childElements[elementsLength]) { 480 e.preventDefault(); 481 e.stopPropagation(); 482 return false; 483 } else { 484 document.activeElement.closest('li').nextElementSibling.querySelector('a').focus(); 485 } 486 if (e.keyCode === 27) { 487 document.activeElement.closest('.dropdown').classList.remove('opened'); 488 document.activeElement.closest('.dropdown').querySelector('.dropdown-toggle').focus(); 489 } 490 } 491 492 for (let i = elements.length - 1; i >= 0; i--) { 493 elements[i].addEventListener('click', clickToggleDropdown); 494 let childElements = elements[i].closest('.dropdown').querySelector('.dropdown-menu').querySelectorAll('li a'); 495 for (let j = 0; j < childElements.length; j++) { 496 let child = childElements[j]; 497 child.addEventListener('keydown', focusDropdown); 498 } 499 } 500 let elements2 = document.querySelectorAll('.dropdown__toggle'); 501 502 function clickDropdown(e) { 503 this.closest('.dropdown').classList.toggle('dropdown--opened'); 504 if (this.closest('.dropdown').classList.contains('dropdown--opened')) { 505 e.currentTarget.setAttribute('aria-expanded', 'true'); 506 bkjs.commons.setFocusOnOpenedElement(this.closest('.dropdown').querySelector('.dropdown__menu')); 507 e.currentTarget.closest('.dropdown').querySelector('.dropdown__menu').querySelectorAll('li')[0].querySelector('a').focus(); 508 } else { 509 e.currentTarget.setAttribute('aria-expanded', 'false'); 510 e.currentTarget.blur(); 511 } 512 } 513 514 for (let w = elements2.length - 1; w >= 0; w--) { 515 elements2[w].addEventListener('click', clickDropdown); 516 let childElements2 = elements2[w].closest('.dropdown').querySelector('.dropdown__menu').querySelectorAll('li a'); 517 for (let d = 0; d < childElements2.length; d++) { 518 let elementsLength2 = childElements2.length - 1; 519 let child2 = childElements2[d]; 520 child2.addEventListener('keydown', function (e) { 521 if (e.keyCode === 38) { 522 e.preventDefault(); 523 if (document.activeElement === childElements2[0]) { 524 return false; 525 } else { 526 document.activeElement.closest('li').previousElementSibling.querySelector('a').focus(); 527 } 528 e.stopPropagation(); 529 } else if (e.keyCode === 40) { 530 e.preventDefault(); 531 if (document.activeElement === childElements2[elementsLength2]) { 532 return false;
533 } else { 534 document.activeElement.closest('li').nextElementSibling.querySelector('a').focus(); 535 } 536 e.stopPropagation(); 537 } else if (e.keyCode === 27) { 538 document.activeElement.closest('.dropdown').classList.remove('dropdown--opened'); 539 document.activeElement.closest('.dropdown').querySelector('.dropdown__toggle').focus(); 540 } 541 }); 542 } 543 } 544 }, 545 toggleCheckboxEllipsis() { 546 document.querySelectorAll('.checkbox-ellipsis').forEach((element) => { 547 // Manejador de click 548 element.addEventListener('click', (e) => { 549 const target = e.currentTarget; 550 bkjs.commons.classesToEl(target, 'toggle', 'checkbox-ellipsis--opened'); 551 552 const isOpened = target.classList.contains('checkbox-ellipsis--opened'); 553 target.setAttribute('aria-expanded', isOpened ? 'true' : 'false'); 554 }); 555 556 // Manejador para la interacción con teclado (Enter / Espacio) 557 element.addEventListener('keyup', (e) => { 558 const isEnter = e.key === 'Enter' || e.keyCode === 13; 559 const isSpace = e.key === ' ' || e.key === 'Spacebar' || e.keyCode === 32; 560 561 if (isEnter || isSpace) { 562 e.preventDefault(); 563 e.currentTarget.click(); 564 } 565 }); 566 }); 567 }, 568 toggleInfoAdd() { 569 document.querySelectorAll('.additional-info__desplegable').forEach((element) => { 570 // Manejador de click 571 element.addEventListener('click', (e) => { 572 const target = e.currentTarget; 573 bkjs.commons.classesToEl(target, 'toggle', 'additional-info__desplegable--opened'); 574 575 const isOpened = target.classList.contains('additional-info__desplegable--opened'); 576 target.setAttribute('aria-expanded', isOpened ? 'true' : 'false'); 577 }); 578 579 // Manejador de interacción por teclado (Enter / Espacio) 580 element.addEventListener('keyup', (e) => { 581 const isEnter = e.key === 'Enter' || e.keyCode === 13; 582 const isSpace = e.key === ' ' || e.key === 'Spacebar' || e.keyCode === 32; 583 584 if (isEnter || isSpace) { 585 e.preventDefault(); 586 e.currentTarget.click(); 587 } 588 }); 589 }); 590 }, 591 _toggleVideoControl(selector, targetRelation) { 592 document.querySelectorAll(selector).forEach((btn) => { 593 btn.addEventListener('click', (e) => { 594 const current = e.currentTarget; 595 const target = targetRelation === 'next' ? current.nextElementSibling : current.previousElementSibling; 596 597 if (target) { 598 bkjs.commons.classesToEl(current, 'add', 'd-none'); 599 bkjs.commons.classesToEl(target, 'remove', 'd-none'); 600 } 601 }); 602 }); 603 }, 604 playVideo() { 605 this._toggleVideoControl('.video__container__controls__play', 'next'); 606 }, 607 pauseVideo() { 608 this._toggleVideoControl('.video__container__controls__pause', 'prev'); 609 }, 610 volumeOffVideo() { 611 this._toggleVideoControl('.video__container__controls__volume_on', 'prev'); 612 }, 613 volumeOnVideo() { 614 this._toggleVideoControl('.video__container__controls__volume_off', 'next'); 615 }, 616 expandVideo() { 617 this._toggleVideoControl('.video__container__controls__expand', 'next'); 618 }, 619 restoreVideo() { 620 this._toggleVideoControl('.video__container__controls__restore', 'prev'); 621 }, 622 sliderVentajas(startSlider) { 623 const element = document.getElementById(startSlider); 624 if (!element) return; 625 626 element.querySelectorAll('.carousel__controls__button').forEach((btn) => { 627 btn.addEventListener('click', (e) => { 628 const currentBtn = e.currentTarget; 629 630 // Quitar estado activo del botón anterior y activado del actual 631 const activeBtn = element.querySelector('.carousel__controls__button.active'); 632 if (activeBtn) { 633 bkjs.commons.classesToEl(activeBtn, 'remove', 'active'); 634 } 635 bkjs.commons.classesToEl(currentBtn, 'add', 'active'); 636 637 // Limpiar todas las clases de tipo slideN dinámicamente 638 element.className = element.className.replace(/\bslide\d+\b/g, '').trim(); 639 640 // Aplicar la nueva clase según el dataset 641 const slideIndex = currentBtn.dataset.slide; 642 if (slideIndex) { 643 bkjs.commons.classesToEl(element, 'add', `slide${slideIndex}`); 644 } 645 }); 646 }); 647 }, 648 649 openModal() { 650 const elements = document.querySelectorAll('.launch-modal'); 651
652 elements.forEach((btn) => { 653 btn.addEventListener('click', (e) => { 654 e.stopPropagation(); 655 e.preventDefault(); 656 657 const rootModalElement = document.activeElement; 658 const modalTarget = e.currentTarget.dataset.target; 659 if (!modalTarget) return; 660 661 const modalEl = document.getElementById(modalTarget); 662 if (!modalEl) return; 663 664 // 1. Añadir clases de apertura al modal y al body 665 bkjs.commons.classesToEl(modalEl, 'add', 'opened'); 666 bkjs.commons.classesToEl(modalEl, 'add', 'modal--opened'); 667 bkjs.commons.classesToEl(document.body, 'add', 'no-scroll'); 668 669 // 2. Ajuste dinámico de dimensiones de imagen (Scoped al modal actual) 670 const modalContent = modalEl.querySelector('.modal__content'); 671 if (modalContent) { 672 const altoModal = modalContent.clientHeight; 673 const modalImage = modalEl.querySelector('.modal__image'); 674 const modalImgTag = modalEl.querySelector('.modal__image img'); 675 676 if (modalImage) { 677 modalImage.style.height = `${altoModal}px`; 678 } 679 if (modalImgTag) { 680 modalImgTag.style.width = `${altoModal}px`; 681 } 682 } 683 684 // 3. Métodos accesibilidad y controles 685 if (bkjs.components) { 686 if (typeof bkjs.components.closeModalBtnFooter === 'function') { 687 bkjs.components.closeModalBtnFooter(); 688 } 689 if (typeof bkjs.components.accesibleModal === 'function') { 690 bkjs.components.accesibleModal(rootModalElement, 'modal1'); 691 } 692 } 693 694 // 4. Analytics 695 if (typeof callAnalyticsEvent === 'function') { 696 const isOtp = modalEl.classList.contains('otp'); 697 callAnalyticsEvent({ 698 component_name: isOtp ? modalTarget : 'html libre', 699 type: 'modal', 700 event_name: 'modal_open', 701 position: modalTarget.toLowerCase(), 702 event: 'eventga' 703 }); 704 } 705 }); 706 }); 707 }, 708 709 closeModal(rootModalElement) { 710 // Función auxiliar para desbloquear el scroll del body sólo si no quedan modales abiertos 711 const checkAndUnlockScroll = () => { 712 const openModalsSelector = ` 713 .modal.opened:not(.modal--demo), 714 .modal.modal--opened:not(.modal--demo), 715 .modal-empresas.opened:not(.modal--demo), 716 .modal-empresas.modal--opened:not(.modal--demo), 717 .modal-filtro.opened, 718 .modal-filtro.modal--opened 719 `; 720 721 const hasOpenModals = document.querySelectorAll(openModalsSelector).length > 0; 722 if (!hasOpenModals) { 723 bkjs.commons.classesToEl(document.body, 'remove', 'no-scroll'); 724 } 725 }; 726 727 // 1. Manejador unificado para modales estándar y de empresas 728 const closeButtons = document.querySelectorAll('.modal__close-button, .message__close'); 729 closeButtons.forEach((btn) => { 730 btn.addEventListener('click', (e) => { 731 e.stopPropagation(); 732 733 const modal = e.currentTarget.closest('.modal') || e.currentTarget.closest('.modal-empresas'); 734 if (!modal) return; 735 736 bkjs.commons.classesToEl(modal, 'remove', 'opened'); 737 bkjs.commons.classesToEl(modal, 'remove', 'modal--opened'); 738 739 checkAndUnlockScroll(); 740 741 if (rootModalElement && typeof rootModalElement.focus === 'function') { 742 rootModalElement.focus(); 743 } 744 }); 745 }); 746 747 // 2. Manejador unificado para modales de tipo filtro 748 const filterCloseButtons = document.querySelectorAll('.modal-filtro__close-button'); 749 filterCloseButtons.forEach((btn) => { 750 btn.addEventListener('click', (e) => { 751 e.stopPropagation(); 752 753 const modal = e.currentTarget.closest('.modal-filtro'); 754 if (!modal) return; 755 756 bkjs.commons.classesToEl(modal, 'remove', 'opened'); 757 bkjs.commons.classesToEl(modal, 'remove', 'modal--opened'); 758 759 checkAndUnlockScroll(); 760
761 if (rootModalElement && typeof rootModalElement.focus === 'function') { 762 rootModalElement.focus(); 763 } 764 }); 765 }); 766 }, 767 768 closeModalBtnFooter() { 769 document.querySelectorAll('.modal').forEach((modal) => { 770 const footerCloseBtn = modal.querySelector('.modal__close-button--footer'); 771 const headerCloseBtn = modal.querySelector('.modal__close-button'); 772 773 if (footerCloseBtn && headerCloseBtn && !footerCloseBtn.dataset.boundClose) { 774 footerCloseBtn.dataset.boundClose = 'true'; 775 footerCloseBtn.addEventListener('click', () => { 776 headerCloseBtn.click(); 777 }); 778 } 779 }); 780 }, 781 782 accesibleModal(rootModalElement, modalType) { 783 const modal = document.querySelector('.modal--opened'); 784 if (!modal) return; 785 786 const getFocusList = (element) => { 787 if (!element) return []; 788 const selector = 'a[href], area[href], input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [tabindex="0"]'; 789 return Array.from(element.querySelectorAll(selector)); 790 }; 791 792 const getModalFocusableElements = (type) => { 793 if (type === 'modal2') { 794 const message = modal.querySelector('.modal__content__message'); 795 return getFocusList(message); 796 } 797 798 if (type === 'modal1') { 799 const header = modal.querySelector('.modal__content__header'); 800 const body = modal.querySelector('.modal__content__body'); 801 const footer = modal.querySelector('.modal__content__footer'); 802 803 return [ 804 ...getFocusList(header), 805 ...getFocusList(body), 806 ...getFocusList(footer) 807 ]; 808 } 809 810 return []; 811 }; 812 813 const focusableEls = getModalFocusableElements(modalType); 814 if (!focusableEls.length) return; 815 816 // Enfocar automáticamente el primer elemento interactivo 817 focusableEls[0].focus(); 818 819 modal.addEventListener('keydown', (e) => { 820 const isTab = e.key === 'Tab' || e.keyCode === 9; 821 const isEsc = e.key === 'Escape' || e.keyCode === 27; 822 823 if (isTab) { 824 if (focusableEls.length === 1) { 825 e.preventDefault(); 826 return; 827 } 828 829 const firstFocusableEl = focusableEls[0]; 830 const lastFocusableEl = focusableEls[focusableEls.length - 1]; 831 832 if (e.shiftKey && document.activeElement === firstFocusableEl) { 833 e.preventDefault();
834 lastFocusableEl.focus(); 835 } else if (!e.shiftKey && document.activeElement === lastFocusableEl) { 836 e.preventDefault(); 837 firstFocusableEl.focus(); 838 } 839 } else if (isEsc) { 840 const currentModal = e.currentTarget.closest('.modal, .modal-empresas, .modal-filtro'); 841 if (currentModal) { 842 bkjs.commons.classesToEl(currentModal, 'remove', 'opened'); 843 bkjs.commons.classesToEl(currentModal, 'remove', 'modal--opened'); 844 } 845 846 const openModalsSelector = '.modal.opened, .modal.modal--opened, .modal-empresas.opened, .modal-empresas.modal--opened, .modal-filtro.opened, .modal-filtro.modal--opened'; 847 if (document.querySelectorAll(openModalsSelector).length === 0) { 848 bkjs.commons.classesToEl(document.body, 'remove', 'no-scroll'); 849 } 850 851 if (rootModalElement && typeof rootModalElement.focus === 'function') { 852 rootModalElement.focus(); 853 } 854 } 855 }); 856 }, 857 openClausula() { 858 let element = document.querySelector('.clausula__show'); 859 if (element) { 860 element.addEventListener('click', function (e) { 861 e.stopPropagation(); 862 e.preventDefault(); 863 document.querySelector('.clausula_text').classList.add('clausula_text--show'); 864 }); 865 } 866 }, 867 closeClausula() { 868 let element = document.querySelector('.clausula__close'); 869 if (element) { 870 element.addEventListener('click', function (e) { 871 e.stopPropagation(); 872 e.preventDefault(); 873 document.querySelector('.clausula_text').classList.remove('clausula_text--show'); 874 }); 875 } 876 }, 877 closeButtonSticky() { 878 let iconCloseSticky = document.querySelector('.featured-box_sticky button .icon--close-16'); 879 if (iconCloseSticky) { 880 iconCloseSticky.closest('button').addEventListener('click', function (e) { 881 e.stopPropagation(); 882 e.preventDefault(); 883 this.closest('.featured-box__wrapper').classList.add('d-none'); 884 }); 885 } 886 }, 887 closeBackdropModal() { 888 let elements = document.querySelectorAll('.modal'); 889 for (let ff = 0; ff < elements.length; ff++) { 890 if (elements[ff].dataset.closeBackdrop) { 891 if (!elements[ff].classList.contains('modal--bloqueada')) { 892 elements[ff].querySelectorAll('.modal__backdrop')[0].addEventListener('click', function (e) { 893 e.stopPropagation(); 894 bkjs.commons.classesToEl(e.currentTarget.closest('.modal'), 'remove', 'opened'); 895 if(e.currentTarget.closest('.modal').classList.contains('otp')){ 896 callAnalyticsEvent({ 897 'component_name': e.currentTarget.closest('.modal').getAttribute('id'), 898 'event_name': 'modal_close', 899 'type': 'modal', 900 'position': e.currentTarget.closest('.modal').getAttribute('id'), 901 'element': '[]', 902 'event': 'eventga' 903 }); 904 } 905 if (document.querySelectorAll('.modal.opened').length == 0) { 906 bkjs.commons.classesToEl(document.body, 'remove', 'no-scroll'); 907 } 908 }); 909 } else { 910 elements[ff].querySelectorAll('.modal__backdrop')[0].addEventListener('click', function (e) { 911 e.stopPropagation(); 912 }); 913 } 914 } 915 } 916 917 let elementsBEM = document.querySelectorAll('.modal'); 918 for (let gg = 0; gg < elementsBEM.length; gg++) { 919 if (elementsBEM[gg].dataset.closeBackdrop) { 920 elementsBEM[gg].querySelectorAll('.modal__backdrop')[0].addEventListener('click', function (e) { 921 e.stopPropagation(); 922 bkjs.commons.classesToEl(e.currentTarget.closest('.modal'), 'remove', 'modal--opened'); 923 if (document.querySelectorAll('.modal.opened, .modal.modal--opened').length == 0) { 924 bkjs.commons.classesToEl(document.body, 'remove', 'no-scroll'); 925 } 926 }); 927 } 928 } 929 }, 930 openMessage: function () { 931 function clickOpenMessage(e) {
932 rootModalElement = document.activeElement; 933 e.stopPropagation(); 934 e.preventDefault(); 935 let elementToShow = e.currentTarget.closest('.modal'); 936 if (elementToShow) { 937 let buttonToDisable = elementToShow.querySelector('.modal__close-button'); 938 bkjs.commons.classesToEl(elementToShow, 'add', 'message_opened'); 939 bkjs.commons.disableButton(buttonToDisable); 940 } 941 bkjs.components.accesibleModal(rootModalElement, 'modal2'); 942 } 943 944 let elements = document.querySelectorAll('.message__show'); 945 let rootModalElement; 946 for (let hh = 0; hh < elements.length; hh++) { 947 elements[hh].addEventListener('click', clickOpenMessage); 948 } 949 950 function clickOpenMessageBEM(e) { 951 rootModalElement = document.activeElement; 952 e.stopPropagation(); 953 e.preventDefault(); 954 let elementToShow = e.currentTarget.closest('.modal'); 955 let buttonToDisable = elementToShow.querySelector('.modal__close-button'); 956 bkjs.commons.classesToEl(elementToShow, 'add', 'modal--message-opened'); 957 bkjs.commons.disableButton(buttonToDisable); 958 bkjs.components.accesibleModal(rootModalElement, 'modal2'); 959 } 960 961 let elementsBEM = document.querySelectorAll('.modal__message-show'); 962 for (let ii = 0; ii < elementsBEM.length; ii++) { 963 elementsBEM[i].addEventListener('click', clickOpenMessageBEM); 964 } 965 }, 966 closeMessage: function () { 967 function clickMessage(e) { 968 e.stopPropagation(); 969 e.preventDefault(); 970 let elementToShow = e.currentTarget.closest('.modal'); 971 let body = document.querySelector('body'); 972 bkjs.commons.classesToEl(elementToShow, 'remove', 'message_opened'); 973 bkjs.commons.classesToEl(elementToShow, 'remove', 'opened'); 974 if (document.querySelectorAll('.modal.opened').length == 0) { 975 bkjs.commons.classesToEl(body, 'remove', 'no-scroll'); 976 } 977 let buttonToEnable = elementToShow.querySelector('.modal__close-button'); 978 bkjs.commons.enableButton(buttonToEnable); 979 } 980 981 let elements = document.querySelectorAll('.message__close'); 982 for (let i = 0; i < elements.length; i++) { 983 elements[i].addEventListener('click', clickMessage); 984 } 985 986 function clickMessageBEM(e) { 987 e.stopPropagation(); 988 e.preventDefault(); 989 let elementToShowBEM = e.currentTarget.closest('.modal'); 990 bkjs.commons.classesToEl(elementToShowBEM, 'remove', 'modal--message-opened'); 991 let buttonToEnableBEM = elementToShowBEM.querySelector('.modal__close-button'); 992 bkjs.commons.enableButton(buttonToEnableBEM); 993 } 994 995 let elementsBEM = document.querySelectorAll('.message__close'); 996 for (let r = 0; r < elementsBEM.length; r++) { 997 elementsBEM[r].addEventListener('click', clickMessageBEM); 998 } 999 }, 1000 getValueFilterTabs: function (group, elements, gtmUrl) { 1001 let parentElement = document.querySelector(group); 1002 let childElements = parentElement.querySelectorAll(elements); 1003 let elementValue; 1004 1005 function clickFilterTabs(e) { 1006 elementValue = e.currentTarget.dataset.elementValue; 1007 let activeElement = parentElement.querySelector('.filters__element_active'); 1008 if (activeElement) { 1009 bkjs.commons.classesToEl(activeElement, 'remove', 'filters__element_active'); 1010 activeElement.removeAttribute('aria-selected'); 1011 } 1012 bkjs.commons.classesToEl(e.currentTarget, 'add', 'filters__element_active'); 1013 e.currentTarget.setAttribute('aria-selected', true); 1014 bkjs.components.showElementsFilterTabs(elementValue); 1015 } 1016 1017 for (let ll = childElements.length - 1; ll >= 0; ll--) { 1018 childElements[ll].addEventListener('click', clickFilterTabs); 1019 } 1020 }, 1021 showElementsFilterTabs(elementValue) { 1022 document.querySelector('.filter__boxes__show-all').querySelector('button').click(); 1023 document.querySelector('.filter__boxes__show-all').classList.add('d-none'); 1024 let parentElement = document.querySelector('.filter__boxes'); 1025 let childElements = parentElement.querySelectorAll('[data-match-values]'); 1026 let childElementsShown; 1027 for (let i = childElements.length - 1; i >= 0; i--) { 1028 let possibleValues = childElements[i].dataset.matchValues; 1029 if (elementValue === 'reset' || possibleValues.indexOf(elementValue) > -1) { 1030 bkjs.components.orderElementsFilter(elementValue, childElements); 1031 let classes = Array.from(childElements[i].classList); 1032 for (let j = 0; j < classes.length; j++) { 1033 if (classes[j].indexOf('order') > -1) { 1034 childElements[i].classList.remove(classes[j]); 1035 } 1036 } 1037 bkjs.commons.classesToEl(childElements[i], 'add', 'order-' + childElements[i].dataset.f
1037ilterOrder); 1038 if (childElements[i].querySelector('[data-order]')) { 1039 childElements[i].querySelector('[data-order]').setAttribute('data-order', childElements[i].dataset.filterOrder); 1040 } 1041 bkjs.commons.classesToEl(childElements[i], 'remove', 'd-none'); 1042 } else { 1043 bkjs.commons.classesToEl(childElements[i], 'add', 'd-none'); 1044 bkjs.commons.classesToEl(parentElement.querySelector('.filter__boxes__show-all'), 'add', 'd-none'); 1045 } 1046 } 1047 childElementsShown = parentElement.querySelectorAll('[data-match-values]:not(.d-none)'); 1048 for (let jj = 0; jj < childElementsShown.length; jj++) { 1049 childElementsShown[jj].setAttribute('data-gtm-order', jj + 1); 1050 } 1051 }, 1052 orderElementsFilter: function (elementValue, childElements) { 1053 let subChildElements = Array.from(childElements); 1054 subChildElements = subChildElements.splice(1); 1055 let ingresosFijosValues = [1, 2, 3, 4, 5, 6, 7, 8, 9]; 1056 let noIngresosFijosValues = [5, 6, 7, 1, 8, 3, 2, 4, 9]; 1057 let compratidosValues = [4, 5, 6, 2, 1, 7, 3, 8, 9]; 1058 let menor22Values = [2, 3, 4, 5, 6, 1, 7, 8, 9]; 1059 switch (elementValue) { 1060 case 'ingresosFijos': 1061 for (let v = 0; v < subChildElements.length; v++) { 1062 subChildElements[v].setAttribute('data-filter-order', ingresosFijosValues[v]); 1063 } 1064 break; 1065 case 'noIngresosFijos': 1066 for (let f = 0; f < subChildElements.length; f++) { 1067 subChildElements[f].setAttribute('data-filter-order', noIngresosFijosValues[f]); 1068 } 1069 break; 1070 case 'compratidos': 1071 for (let l = 0; l < subChildElements.length; l++) { 1072 subChildElements[l].setAttribute('data-filter-order', compratidosValues[l]); 1073 } 1074 break; 1075 case 'menor22': 1076 for (let p = 0; p < subChildElements.length; p++) { 1077 subChildElements[p].setAttribute('data-filter-order', menor22Values[p]); 1078 } 1079 break; 1080 default: 1081 for (let w = 0; w < subChildElements.length; w++) { 1082 subChildElements[w].setAttribute('data-filter-order', (w + 1)); 1083 } 1084 } 1085 }, 1086 showAllElements() { 1087 let showAllButtons = document.querySelectorAll('.filter__boxes__show-all'); 1088 for (let z = showAllButtons.length - 1; z >= 0; z--) { 1089 showAllButtons[z].querySelector('button').addEventListener('click', function (e) { 1090 let contenedorDivs = document.querySelector('.filter__boxes_truncated'); 1091 if (contenedorDivs) { 1092 let qchildren = contenedorDivs.querySelectorAll('.content-box__footer'); 1093 for (let c = 0; c < qchildren.length; c++) { 1094 if (qchildren[c].querySelector('.text-link')) { 1095 let posicion = qchildren[c].querySelector('.text-link'); 1096 bkjs.commons.classesToEl(posicion, 'remove', 'd-none'); 1097 } 1098 } 1099 } 1100 bkjs.commons.classesToEl(e.currentTarget.closest('.filter__boxes'), 'remove', 'filter__boxes_truncated'); 1101 bkjs.commons.classesToEl(e.currentTarget.closest('.filter__boxes__show-all'), 'add', 'd-none'); 1102 }); 1103 } 1104 }, 1105 showBoxesElements() { 1106 let showAllButtons = document.querySelector('.filter__boxes__show-all'); 1107 let topTodos = showAllButtons.getBoundingClientRect().top; 1108 let contenedorDivs = document.querySelector('.filter__boxes_truncated'); 1109 if (contenedorDivs !== -1) { 1110 let qchildren = contenedorDivs.getElementsByClassName('content-box__footer'); 1111 for (let o = 0; o < qchildren.length; o++) { 1112 let posicion = qchildren[o].querySelector('.text-link'); 1113 if (posicion !== -1) { 1114 let posBox = posicion.getBoundingClientRect().bottom; 1115 if (posBox > topTodos) { 1116 bkjs.commons.classesToEl(posicion, 'add', 'd-none'); 1117 } 1118 } 1119 } 1120 } 1121 }, 1122 launchJumpContent() { 1123 const jumpContent = document.getElementById('jumpContent'); 1124 if (jumpContent) { 1125 jumpContent.addEventListener('keydown', (e) => { 1126 if (e.key === 'Enter') { 1127 const button = e.target.closest('button'); 1128 if (!button) return; 1129 const href = button.getAttribute('href'); 1130 if (!href) return; 1131 const targetElement = document.querySelector(href); 1132 if (targetElement) { 1133 targetElement.focus(); 1134 } 1135 } 1136 }); 1137 document.addEventListener('keydown', (event) => { 1138 if (event.key === 'Tab') { 1139 document.getElementById('jumpContent').style.display = 'block'; 1140 } else { 1141 document.getElementById('jumpContent').style.display = 'none'; 1142 } 1143 }); 1144 } 1145 }, 1146 toggleConditionsFaqAccesible() { 1147 let elements = document.querySelectorAll('.conditions-faqs__item__clickable'); 1148 for (let u = elements.length - 1; u >= 0; u--) { 1149 elements[u].addEventListener('click', function (e) { 1150 let initialHeight = e.currentTarget.offsetHeight + parseInt(window.getComputedStyle(e.currentTarget).marginTop) + parseInt(window.getComputedStyle(e.currentTarget).marginBottom); 1151 let collapsibleElement = e.currentTarget.closest('.conditions-faqs__item__collapsible'); 1152 let isCollapsed = collapsibleElement.getAttribute('data-collapsed') === 'true'; 1153 if (isCollapsed) { 1154 bkjs.animateHeight.expandSectionAccesible(collapsibleElement); 1155 e.currentTarget.closest('.conditions-faqs__item__collapsible').setAttribute('data-collapsed', 'false'); 1156 e.currentTarget.closest('.conditions-faqs__item__collapsible').setAttribute('aria-expanded', 'true'); 1157 } else { 1158 bkjs.animateHeight.collapseSectionAccesible(collapsibleElement, initialHeight); 1159 e.currentTarget.closest('.conditions-faqs__item__collapsible').setAttribute('aria-expanded', 'false'); 1160 } 1161 }); 1162 } 1163 let faqsDesplegable = document.querySelectorAll('.conditions-faqs__item'); 1164 faqsDesplegable.forEach(function (desplegable) { 1165 let desplegableTrigger = desplegable.querySelector('.conditions-faqs__title'); 1166 let desplegableContent = desplegable.querySelector('.conditions-faqs__content'); 1167 if (desplegableTrigger) { 1168 desplegableTrigger.addEventListener("click", () => { 1169 if (desplegable && desplegableContent) { 1170 if (desplegable.getAttribute('data-collapsed') == "true") { 1171 desplegable.style.overflow = "initial"; 1172 desplegableContent.style.overflow = "initial"; 1173 } else { 1174 desplegable.style.overflow = "hidden"; 1175 desplegableContent.style.overflow = "hidden"; 1176 } 1177 } 1178 }); 1179 } 1180 }); 1181 1182 let elemOpen = document.querySelectorAll('.conditions-faqs--opened .conditions-faqs__item') 1183 if (document.querySelectorAll('.conditions-faqs--opened').length > 0) {
1184 elemOpen.forEach(function (_value, index) { 1185 elemOpen[index].setAttribute("data-collapsed", "false"); 1186 elemOpen[index].setAttribute("aria-expanded", "true"); 1187 elemOpen[index].setAttribute('style', ''); 1188 if (elemOpen[index].nextElementSibling) { 1189 elemOpen[index].nextElementSibling.removeAttribute('hidden'); 1190 } 1191 }); 1192 } 1193 let elementsFocusable = document.querySelectorAll('.conditions-faqs__item'); 1194 for (let t = elementsFocusable.length - 1; t >= 0; t--) { 1195 elementsFocusable[t].addEventListener('keyup', function (e) { 1196 let key = event.which || event.keyCode; 1197 if (key === 13 || key === 32) { 1198 if (e.currentTarget.querySelector('.conditions-faqs__item__toggle')) e.currentTarget.querySelector('.conditions-faqs__item__toggle').click(); 1199 if (e.currentTarget.querySelector('.conditions-faqs__toggle')) e.currentTarget.querySelector('.conditions-faqs__toggle').click(); 1200 } 1201 }); 1202 } 1203 let elementsBEM = document.querySelectorAll('.conditions__item-clickable'); 1204 for (let r = elementsBEM.length - 1; r >= 0; r--) { 1205 elementsBEM[r].addEventListener('click', function (e) { 1206 let initialHeight = e.currentTarget.offsetHeight + parseInt(window.getComputedStyle(e.currentTarget).marginTop) + parseInt(window.getComputedStyle(e.currentTarget).marginBottom); 1207 let collapsibleElement = e.currentTarget.closest('.conditions__item-collapsible'); 1208 let isCollapsed = collapsibleElement.getAttribute('data-collapsed') === 'true'; 1209 if (isCollapsed) { 1210 bkjs.animateHeight.expandSectionAccesible(collapsibleElement); 1211 e.currentTarget.closest('.conditions__item-collapsible').setAttribute('data-collapsed', 'false'); 1212 } else { 1213 bkjs.animateHeight.collapseSectionAccesible(collapsibleElement, initialHeight); 1214 } 1215 }); 1216 } 1217 }, 1218 toggleContentBoxTab() { 1219 let productFeaturesList = document.getElementsByClassName('product-features'); 1220 let buttons = document.querySelectorAll('.toggle-content-box-tab'); 1221 1222 function clickToggleContentBoxTab(e) { 1223 let pfeat = e.currentTarget.closest('.product-features'); 1224 let activeButton = pfeat ? pfeat.querySelector('.opened') : null; 1225 if (productFeaturesList.length > 1) { 1226 for (let k = 0; k < productFeaturesList.length; k++) { 1227 let openedList = productFeaturesList[k].querySelectorAll('.opened'); 1228 for (let h = 0; h < openedList.length; h++) { 1229 if (!e.currentTarget.classList.contains('opened')) { 1230 openedList[h].classList.remove('opened'); 1231 } 1232 } 1233 } 1234 } 1235 if (activeButton && activeButton !== e.currentTarget) { 1236 bkjs.commons.classesToEl(activeButton, 'remove', 'opened'); 1237 } 1238 if (e.currentTarget.classList.contains('opened')) { 1239 bkjs.commons.classesToEl(e.currentTarget, 'remove', 'opened'); 1240 let selfItem = e.currentTarget.getAttribute('data-tab-value'); 1241 let openedItem = document.querySelector('#tab' + selfItem); 1242 if (openedItem) { 1243 openedItem.setAttribute('aria-expanded', false); 1244 } 1245 1246 } else { 1247 bkjs.commons.classesToEl(e.currentTarget, 'add', 'opened'); 1248 let selfItem2 = e.currentTarget.getAttribute('data-tab-value'); 1249 let openedItem2 = document.querySelector('#tab' + selfItem2); 1250 if (openedItem2) { 1251 openedItem2.setAttribute('aria-expanded', true); 1252 } 1253 } 1254 let tabValue = e.currentTarget.dataset.tabValue; 1255 let activeContent = document.querySelector('.openedContent'); 1256 if (activeContent && activeContent.dataset.tabContent !== tabValue) { 1257 let previousActiveContent = activeContent.getAttribute('data-tab-content'); 1258 let openedItem3 = document.querySelector('#tab' + previousActiveContent); 1259 if (openedItem3) { 1260 openedItem3.setAttribute('aria-expanded', false); 1261 } 1262 bkjs.commons.classesToEl(activeContent, 'remove', 'openedContent'); 1263 } 1264 let contentToActive = document.querySelector('[data-tab-content="' + tabValue + '"]'); 1265 bkjs.commons.classesToEl(contentToActive, 'toggle', 'openedContent'); 1266 } 1267 1268 for (let i = buttons.length - 1; i >= 0; i--) { 1269 buttons[i].addEventListener('click', clickToggleContentBoxTab); 1270 } 1271 }, 1272 accesibleIconSelectorRadio() { 1273 let radioIconSelector = document.querySelectorAll('.icon-selector input[type="radio"]'); 1274 if (radioIconSelector && radioIconSelector.length) { 1275 for (let i = 0; i < radioIconSelector.length; i++) { 1276 radioIconSelector[i].addEventListener('click', clickIconSelectorRadioOptions.bind(this)); 1277 radioIconSelector[i].addEventListener('keydown', keydownIconSelectorRadioOptions.bind(this, i)); 1278 } 1279 } 1280 1281 function clickIconSelectorRadioOptions(e) { 1282 let counter = 0; 1283 for (i = 0; i < radioIconSelector.length; i++) { 1284 if (radioIconSelector[i].checked) { 1285 counter++; 1286 radioIconSelector[i].parentNode.setAttribute('aria-checked', 'true'); 1287 } else { 1288 radioIconSelector[i].parentNode.setAttribute('aria-checked', 'false'); 1289 } 1290 } 1291 } 1292 1293 function keydownIconSelectorRadioOptions(idx) { 1294 if (event.keyCode === 32 || event.keyCode === 13) { 1295 event.preventDefault(); 1296 radioIconSelector[idx].checked = !radioIconSelector[idx].checked; 1297 let radioArr = Array.prototype.slice.call(radioIconSelector); 1298 radioArr.forEach(function (radio) { 1299 radio.parentNode.setAttribute('aria-checked', 'false'); 1300 }); 1301 let hasChecked = radioArr.some(function (radioIconSelector) { 1302 return radioIconSelector.checked; 1303 }); 1304 if (hasChecked) { 1305 radioIconSelector[idx].parentNode.setAttribute('aria-checked', 'true'); 1306 } else { 1307 radioIconSelector[idx].parentNode.setAttribute('aria-checked', 'false'); 1308 } 1309 } 1310 if (event.keyCode === 37) { 1311 event.preventDefault(); 1312 if (idx > 0) { 1313 radioIconSelector[idx - 1].focus(); 1314 } 1315 } 1316 if (event.keyCode === 39) { 1317 event.preventDefault(); 1318 if (idx < radioIconSelector.length - 1) { 1319 radioIconSelector[idx + 1].focus(); 1320 } 1321 } 1322 } 1323 }, 1324 initSmoothHrefMode() { 1325 document.querySelectorAll('a[href^="#"]').forEach(function (anchor) { 1326 anchor.addEventListener('click', function (e) { 1327 var href = this.getAttribute('href'); 1328 1329 if (!href || !href.startsWith('#')) { 1330 if (href) { 1331 location.href = href; 1332 } 1333 } else { 1334 e.preventDefault(); 1335 if (href !== '#') { 1336 try { 1337 var target = document.querySelector(href); 1338 if (target) { 1339 target.scrollIntoView({ 1340 behavior: 'smooth' 1341 }); 1342 } 1343 } catch (error) { 1344 // Manejo de errores por selectores inválidos 1345 } 1346 } 1347 } 1348 }); 1349 }); 1350 },
1351 clickFiltersModal() { 1352 let filters = document.querySelectorAll('.modal-filtro .filter'); 1353 for (let i = 0; i < filters.length; i++) { 1354 filters[i].addEventListener('click', function (e) { 1355 let filterActive = e.currentTarget.querySelector('.filter__content--active'); 1356 if (filterActive) { 1357 e.currentTarget.closest('.modal-filtro__content').querySelector('.action-bar--filter').classList.add('d-none'); 1358 } else { 1359 e.currentTarget.closest('.modal-filtro__content').querySelector('.action-bar--filter').classList.remove('d-none'); 1360 } 1361 }); 1362 } 1363 }, 1364 clickFilters() { 1365 let FILTER = 'filter'; 1366 let SELECTOR = 'filter--selector'; 1367 let CALENDAR = 'filter--calendar'; 1368 let RANGE = 'filter--range'; 1369 1370 function clickOut(evt) { 1371 if (!evt) return; 1372 const actions = [ 1373 { 1374 selector: SELECTOR, 1375 nodes: '.filter__selector', 1376 action: node => node.classList.add('d-none') 1377 }, 1378 { 1379 selector: FILTER, 1380 nodes: '.modal-filtro .action-bar--filter', 1381 action: node => node.classList.remove('d-none'), 1382 single: true 1383 }, 1384 { 1385 selector: CALENDAR, 1386 nodes: '.filter--calendar__content', 1387 action: node => node.parentNode.classList.remove('filter__content--active') 1388 }, 1389 { 1390 selector: RANGE, 1391 nodes: '.filter__bloq-range', 1392 action: node => node.parentNode.classList.remove('filter__content--active') 1393 } 1394 ]; 1395 actions.forEach(({ selector, nodes, action, single }) => { 1396 if (!hasSomeParentTheClass(evt.target, selector)) { 1397 const elements = single ? [document.querySelector(nodes)].filter(Boolean) : document.querySelectorAll(nodes); 1398 elements.forEach(action); 1399 } 1400 }); 1401 } 1402 1403 if (document.body) document.body.addEventListener("click", clickOut); 1404 1405 function hasSomeParentTheClass(element, className) { 1406 do { 1407 if (element.classList && element.classList.contains(className)) { 1408 return true; 1409 } 1410 element = element.parentNode; 1411 } while (element); 1412 return false; 1413 } 1414 }, 1415 ctaStickyMobile() { 1416 if (window.innerWidth < 768) { 1417 if (document.querySelector('.cta-box--fixed-mobile')) { 1418 document.querySelector('footer').style.bottom = document.querySelector('.cta-box--fixed-mobile').querySelector('.cta-box__wrapper').clientHeight + 'px'; 1419 } 1420 } 1421 }, 1422 toggleCtaInterval(initElement, endElement) { 1423 if (window.innerWidth > 767) { 1424 if (document.querySelector('.cta-box--interval-init')) { 1425 let element = document.querySelector(initElement); 1426 let elementEnd = document.querySelector(endElement); 1427 let windowHeight = window.innerHeight; 1428 bkjs.components.toggleCtaBox(element, elementEnd, windowHeight); 1429 window.addEventListener('scroll', function () { 1430 if (window.innerWidth > 767) { 1431 bkjs.components.toggleCtaBox(element, elementEnd, windowHeight); 1432 } 1433 }, { 1434 passive: true 1435 }); 1436 } 1437 } 1438 bkjs.components.calcPositionFixed(); 1439 }, 1440 toggleCtaBox(element, elementEnd, windowHeight) { 1441 if (element.getBoundingClientRect().top <= 100 && elementEnd.getBoundingClientRect().top >= document.querySelector('.cta-box--interval-init').clientHeight + 100) { 1442 document.querySelector('.cta-box--interval-init').classList.remove('cta-box--sticky'); 1443 document.querySelector('.cta-box--interval-init').classList.add('cta-box--interval'); 1444 document.querySelector('.cta-box--interval-init').removeAttribute('style'); 1445 1446 } else { 1447 if (element.getBoundingClientRect().top <= 100 && elementEnd.getBoundingClientRect().top > 0) { 1448 document.querySelector('.cta-box--interval-init').classList.remove('cta-box--sticky'); 1449 document.querySelector('.cta-box--interval-init').classList.add('cta-box--interval'); 1450 let pixeles = document.querySelector('.cta-box--interval-init').clientHeight - elementEnd.getBoundingClientRect().top; 1451 if (pixeles > 0 || -1 * pixeles < 100) pixeles = -1 * pixeles; 1452 document.querySelector('.cta-box--interval-init').style.top = pixeles + 'px'; 1453 } else { 1454 document.querySelector('.cta-box--interval-init').removeAttribute('style'); 1455 document.querySelector('.cta-box--interval-init').classList.add('cta-box--sticky'); 1456 document.querySelector('.cta-box--interval-init').classList.remove('cta-box--interval'); 1457 } 1458 1459 } 1460 }, 1461 calcPositionFixed() { 1462 if (window.innerWidth > 767) { 1463 if (document.querySelector('.cta-box--fixed')) { 1464 if (document.querySelector('.cta-box--fixed.cta-box--fixed-left')) { 1465 let fixedElement = document.querySelector('.cta-box--fixed-left'); 1466 let positionLeft = (window.innerWidth - document.querySelector('.container').offsetWidth - 16) / 2; 1467 let positionVertical = window.innerHeight / 4; 1468 fixedElement.style.position = 'fixed'; 1469 fixedElement.style.left = positionLeft + 'px'; 1470 fixedElement.style.top = positionVertical + 'px'; 1471 } else { 1472 let fixedElement = document.querySelector('.cta-box--fixed'); 1473 let positionRight = (window.innerWidth - document.querySelector('.container').offsetWidth - 16) / 2; 1474 let positionVertical = window.innerHeight / 4; 1475 fixedElement.style.position = 'fixed'; 1476 fixedElement.style.right = positionRight + 'px'; 1477 fixedElement.style.top = positionVertical + 'px'; 1478 } 1479 } 1480 } 1481 } 1482 }, 1483 swipe: { 1484 position(e) { 1485 const touch = e.changedTouches ? e.changedTouches[0] : e; 1486 return { 1487 x: touch.pageX, 1488 y: touch.pageY 1489 }; 1490 }, 1491 1492 onSwipe(elem, callback) { 1493 if (!elem || typeof callback !== 'function') return; 1494 1495 const minDistance = 80; 1496 const maxTime = 400; 1497 let startTime = 0; 1498 let startPos = { x: 0, y: 0 }; 1499 1500 const start = (e) => { 1501 startTime = Date.now(); 1502 startPos = this.position(e); 1503 }; 1504 1505 const end = (e) => { 1506 if (!startTime) return; 1507 1508 const elapsedTime = Date.now() - startTime; 1509 const newPos = this.position(e); 1510 const offsetX = newPos.x - startPos.x; 1511 const offsetY = newPos.y - startPos.y; 1512 const absX = Math.abs(offsetX); 1513 const absY = Math.abs(offsetY); 1514 1515 let direction = ''; 1516 let distance = 0; 1517 1518 if (absX > absY) { 1519 direction = offsetX > 0 ? 'right' : 'left'; 1520 distance = absX; 1521 } else { 1522 direction = offsetY > 0 ? 'down' : 'up'; 1523 distance = absY; 1524 } 1525 1526 if (elapsedTime <= maxTime && distance >= minDistance) { 1527 callback(direction); 1528 } 1529 }; 1530 1531 elem.addEventListener('touchstart', start, { passive: true }); 1532 elem.addEventListener('mousedown', start); 1533 elem.addEventListener('touchend', end, { passive: true }); 1534 elem.addEventListener('mouseup', end); 1535 } 1536 }, 1537 gtm: { 1538 // Variables de estado para el carrusel 1539 _carouselState: { 1540 nodo: null, 1541 initialX: 0 1542 }, 1543 1544 _pushToDataLayer(data) { 1545 if (typeof window.dataLayer !== 'undefined') { 1546 window.dataLayer.push(data); 1547 } 1548 }, 1549 1550 doEventAnalytics(category, action, label, value) { 1551 this._pushToDataLayer({ category, action, label, value, event: 'eventga' }); 1552 }, 1553 1554 doEventAnalyticsExtended(category, action, label, type, position, element, order, value) { 1555 this._pushToDataLayer({ 1556 category, 1557 action, 1558 label, 1559 type, 1560 position, 1561 element, 1562 order, 1563 value, 1564 event: 'eventga' 1565 }); 1566 }, 1567 1568 doEventAnalyticsEdit(e, category, action, label, type, position, element, order, value) { 1569 const target = e ? e.currentTarget : null; 1570 const elementText = target ? target.innerText : ''; 1571 const finalLabel = target ? target.href : label; 1572 1573 // Sanitización moderna de acentos/diacrÃticos usando NFD + Regex limpia 1574 let cleanElement = elementText 1575 .normalize('NFD') 1576 .replace(/[\u0300-\u036f]/g, '') 1577 .toLowerCase() 1578 .replace(/[^a-z0-9]/g, ''); 1579 1580 this._pushToDataLayer({ 1581 category, 1582 action, 1583 label: finalLabel, 1584 type, 1585 position, 1586 element: cleanElement, 1587 order, 1588 value, 1589 event: 'eventga' 1590 }); 1591 }, 1592 1593 doEventAnalyticsTabs(category, action, label, type, position, element, order, value) { 1594 const activeFilter = document.querySelector('.filters__element_active'); 1595 const positionAX = activeFilter ? activeFilter.getAttribute('aria-controls') : position; 1596 1597 this._pushToDataLayer({ 1598 category, 1599 action, 1600 label, 1601 type, 1602 position: positionAX, 1603 element, 1604 order, 1605 value, 1606 event: 'eventga' 1607 }); 1608 }, 1609 1610 doEventAnalyticsSmart(category, action, label, type, position, element, order, value) { 1611 this._pushToDataLayer({ 1612 category, 1613 action, 1614 label, 1615 type, 1616 position: `${position} - cabecera`, 1617 element, 1618 order, 1619 value, 1620 event: 'eventga' 1621 }); 1622 }, 1623 1624 doVirtualUrl(virtualUrl) { 1625 this._pushToDataLayer({ virtualUrl, event: 'virtualurl' }); 1626 }, 1627 1628 launchGtmAccordion(element, dataPosition, dataElement, order) { 1629 if (!element) return; 1630 const parentDiv = element.closest('div'); 1631 const isParentOpened = parentDiv && parentDiv.classList.contains('opened'); 1632 const isElementOpened = element.classList.contains('opened'); 1633 1634 if (!isParentOpened || !isElementOpened) { 1635 this.doEventAnalyticsExtended('Navegacion', 'Enlace interno', '#', 'enlace', dataPosition, dataElement, order, undefined); 1636 } 1637 }, 1638 1639 launchGtmFaqs(element, order) { 1640 if (element && !element.classList.contains('opened')) { 1641 this.doEventAnalyticsExtended('Navegacion', 'Enlace interno', '#', 'enlace', 'Faqs', 'Preguntas frecuentes', order, undefined); 1642 } 1643 }, 1644 1645 doEventAnalyticsWithDimensions(category, action, label, value, dimensions = {}) { 1646 if (typeof window.dataLayer === 'undefined') return; 1647 1648 const objEvent = { 1649 category, 1650 action, 1651 label, 1652 value, 1653 event: 'eventga', 1654 ...dimensions 1655 }; 1656 1657 window.dataLayer.push(objEvent); 1658 }, 1659 1660 doEventAnalyticsWithCarrusel(e) { 1661 const activeSlide = document.querySelector('.carousel__slide--active'); 1662 if (activeSlide && e.touches && e.touches[0]) { 1663 this._carouselState.nodo = activeSlide.getAttribute('data-description'); 1664 this._carouselState.initialX = e.touches[0].clientX; 1665 } 1666 }, 1667 1668 doEventAnalyticsWithCarruselEnd(e, product) { 1669 const { initialX, nodo } = this._carouselState; 1670 if (!initialX || !e.touches || !e.touches[0]) return; 1671 1672 const currentX = e.touches[0].clientX; 1673 const etiqueta = initialX > currentX ? 'Desplazar Izquierda' : 'Desplazar Derecha'; 1674 1675 this._carouselState.initialX = 0; 1676 1677 setTimeout(() => { 1678 const activeSlide = document.querySelector('.carousel__slide--active'); 1679 if (!activeSlide) return; 1680 1681 const descriptionNew = activeSlide.getAttribute('data-description');
1682 if (nodo !== descriptionNew) { 1683 const position = activeSlide.getAttribute('data-index-number'); 1684 this.doEventAnalyticsWithDimensions('Interaccion', 'Carrusel', etiqueta, undefined, { 1685 product, 1686 position: 'caracteristicas producto', 1687 element: descriptionNew, 1688 type: 'swipe', 1689 order: position 1690 }); 1691 } 1692 }, 200); 1693 }, 1694 1695 doEventAnalyticsEnhancedEEC(name, id, price, brand, category) { 1696 this._pushToDataLayer({ 1697 event: 'detail', 1698 ecommerce: { 1699 detail: { 1700 products: [{ name, id, price, brand, category }] 1701 } 1702 } 1703 }); 1704 }, 1705 1706 doEventAnalyticsEnhancedAddEEC(name, id, price, brand, category, quantity) { 1707 this._pushToDataLayer({ 1708 event: 'addToCart', 1709 ecommerce: { 1710 currencyCode: 'EUR', 1711 add: { 1712 products: [{ name, id, price, brand, category, quantity }] 1713 } 1714 } 1715 }); 1716 }, 1717 1718 doEventAnalyticsPromoViewEEC(json) { 1719 if (json) this._pushToDataLayer(json); 1720 } 1721 }, 1722 nbol:{ 1723 launchModal() { 1724 const translations = { 1725 es: { 1726 cerrarModal: "Cerrar modal", 1727 messageTitleCliente: "Soy cliente", 1728 messageTitleTextCliente: "Haciendo clic en el enlace, abandonarás la página web de Bankinter y serás redirigido a una página web externa propiedad de Mapfre.", 1729 btnCliente: "Simula y contrata", 1730 messageTitleNoCliente: "No soy cliente", 1731 messageTitleTextNoCliente: "Para continuar con la simulación y<br>posterior contratación de tu seguro,<br>llama al <strong>901 13 13 13</strong>." 1732 }, 1733 en: { 1734 cerrarModal: "Close modal window", 1735 messageTitleCliente: "I'm a customer", 1736 messageTitleTextCliente: "When you click on the link you will leave the Bankinter website and be redirected to an external website owned by Mapfre.", 1737 btnCliente: "Calculate it then purchase it", 1738 messageTitleNoCliente: "I'm not a customer", 1739 messageTitleTextNoCliente: "To continue with the calculation and<br>then purchase your policy,<br>call <strong>901 13 13 13</strong>." 1740 }, 1741 ca: { 1742 cerrarModal: "Tancar modal", 1743 messageTitleCliente: "Soc client", 1744 messageTitleTextCliente: "Fent clic a l'enllaç, abandonaràs el lloc web de Bankinter i seràs redirigit a una pà gina web externa propietat de Mapfre.", 1745 btnCliente: "Simula i contracta", 1746 messageTitleNoCliente: "No soc client", 1747 messageTitleTextNoCliente: "Per continuar amb la simulació i<br>posterior contractació de la teva assegurança,<br> truca al <strong>901 13 13 13</strong>." 1748 } 1749 }; 1750 1751 const lang = (document.documentElement.lang || "es").slice(0, 2).toLowerCase(); 1752 const t = translations[lang] || translations.es; 1753 1754 const htmlModal = ` 1755 <div class="modal" id="modalNav" data-close-backdrop="true" tabindex="-1" role="dialog" style="z-index: 2000;"> 1756 <div class="modal__backdrop"></div> 1757 <div class="container" role="document"> 1758 <div class="row justify-content-center"> 1759 <div class="col-12 col-md-7 h-75"> 1760 <div class="modal__content"> 1761 <div class="modal__content__header"> 1762 <button type="button" class="btn btn--dark btn--rounded modal__close-button"> 1763 <span class="icon-fallback-text"> 1764 <span class="icon icon--close-16 icon--24" aria-hidden="true"></span> 1765 <span class="text">${t.cerrarModal}</span> 1766 </span> 1767 </button> 1768 </div> 1769 <div class="modal__content__body"> 1770 <div class="modal__content__body__wrapper row"> 1771 <div class="col-12 col-lg-6"> 1772 <div> 1773 <span class="d-flex h5 margin-bottom_16 message__title">${t.messageTitleCliente}</span> 1774 ${t.messageTitleTextCliente} 1775 </div> 1776 <a href="https://precio.mapfre.es/calcular-seguro-salud-global/es
1776/fecha-inicio-seguro?origen=BKT&PPPO=MAPFRES**" 1777 onclick="bkjs.gtm.doEventAnalyticsExtended('Interaccion','Simulador seguro salud','Iniciar proceso clientes','Boton','popup','simula y contrata','1','1')" 1778 target="_blank" 1779 class="btn btn--primary margin-top_16 margin-bottom_16" 1780 tabindex="0"> 1781 <span class="text">${t.btnCliente}</span> 1782 </a> 1783 </div> 1784 <div class="col-12 col-lg-6"> 1785 <div> 1786 <span class="d-flex h5 margin-bottom_16 message__title">${t.messageTitleNoCliente}</span> 1787 ${t.messageTitleTextNoCliente} 1788 </div> 1789 </div> 1790 </div> 1791 <div class="modal__content__footer"></div> 1792 </div> 1793 </div> 1794 </div> 1795 </div> 1796 </div> 1797 </div>`; 1798 1799 document.querySelectorAll('.header-bk-wem__sublist-item a[data-target]').forEach((link) => { 1800 link.classList.add('launch-modal'); 1801 link.href = '#'; 1802 }); 1803 1804 const mainEl = document.querySelector('main'); 1805 if (mainEl) { 1806 mainEl.insertAdjacentHTML('afterend', htmlModal); 1807 1808 } 1809 } 1810 } 1811 1812}; 1813 1814(() => { 1815 // ========================================== 1816 // 1. OBJETO BKJSBLOG OPTIMIZADO 1817 // ========================================== 1818 window.bkjsBlog = { 1819 _carouselState: { nodo: null, initialX: 0 }, 1820 1821 components: { 1822 toggleDropdownElement(selector, targetClass, activeClass) { 1823 const targets = document.querySelectorAll(selector); 1824 const overlay = document.querySelector(".overlay"); 1825 1826 targets.forEach((el) => { 1827 el.addEventListener("click", (e) => { 1828 const target = e.currentTarget.closest(targetClass); 1829 if (!target) return; 1830 1831 const isOpened = target.classList.contains(activeClass); 1832 bkjs.commons.classesToEl(target, isOpened ? "remove" : "add", activeClass); 1833 if (overlay) { 1834 bkjs.commons.classesToEl(overlay, isOpened ? "remove" : "add", "overlay--opened"); 1835 } 1836 }); 1837 }); 1838 1839 if (overlay && !overlay.dataset.hasDropdownListener) { 1840 overlay.addEventListener("click", () => { 1841 const header = document.querySelector(".header-blog"); 1842 if (header) { 1843 bkjs.commons.classesToEl(header, "remove", "header-blog--menu-opened"); 1844 bkjs.commons.classesToEl(header, "remove", "header-blog--search-opened"); 1845 } 1846 bkjs.commons.classesToEl(overlay, "remove", "overlay--opened"); 1847 }); 1848 overlay.dataset.hasDropdownListener = "true"; 1849 } 1850 }, 1851 1852 toggleMenuList() { 1853 const menuBox = document.querySelector(".menu-box"); 1854 1855 document.querySelectorAll(".menu-box__show-more").forEach((btn) => { 1856 btn.addEventListener("click", (e) => { 1857 e.stopPropagation(); 1858 const isOpened = e.currentTarget.classList.contains("menu-box__show-more--opened"); 1859 const action = isOpened ? "remove" : "add"; 1860 1861 if (menuBox) bkjs.commons.classesToEl(menuBox, action, "menu-box--opened"); 1862 bkjs.commons.classesToEl(e.currentTarget, action, "menu-box__show-more--opened"); 1863 }); 1864 }); 1865 }, 1866 1867 formFullWidth() { 1868 document.querySelectorAll('.form-fw input[type="text"]').forEach((input) => { 1869 input.addEventListener("keyup", (e) => { 1870 const form = e.currentTarget.closest(".form-fw"); 1871 if (!form) return; 1872 1873 const hasValue = Boolean(e.currentTarget.value && e.currentTarget.value !== "undefined"); 1874 bkjs.commons.classesToEl(form, hasValue ? "add" : "remove", "form-fw--submit"); 1875 }); 1876 }); 1877 }, 1878 1879 toggleTabs(tabSelector, contentSelector) { 1880 const tabClass = tabSelector.replace(".", "") + "--active"; 1881 const contentClass = contentSelector.replace(".", "") + "--active"; 1882 1883 document.querySelectorAll(tabSelector).forEach((tab) => { 1884 tab.addEventListener("click", (e) => { 1885 e.stopPropagation(); 1886 const targetId = e.currentTarget.dataset.elementValue; 1887 const container = e.currentTarget.closest(":has(" + tabSelector + ")") || e.currentTarget.parentElement.parentElement.parentElement; 1888 1889 container.querySelectorAll(tabSelector).forEach((el) => bkjs.commons.classesToEl(el, "remove", tabClass)); 1890 bkjs.commons.classesToEl(e.currentTarget, "add", tabClass); 1891 1892 container.querySelectorAll(contentSelector).forEach((el) => bkjs.commons.classesToEl(el, "remove", contentClass)); 1893 1894 const targetEl = document.getElementById(targetId); 1895 if (targetEl) { 1896 bkjs.commons.classesToEl(targetEl, "add", contentClass); 1897 targetEl.focus(); 1898 } 1899 }); 1900 }); 1901 }, 1902 1903 popover() { 1904 const popovers = document.querySelectorAll(".popover"); 1905 const windowWidth = window.innerWidth; 1906 const sideMargins = windowWidth >= 768 ? 35 : -3; 1907
1908 popovers.forEach((popover, index) => { 1909 popover.id = `popover-${index}`; 1910 const items = popover.querySelectorAll(".popover__item"); 1911 1912 items.forEach((item) => { 1913 item.id = `popover-text-${index}`; 1914 const rect = item.getBoundingClientRect(); 1915 1916 if (rect.right > windowWidth) { 1917 item.style.left = `${windowWidth - sideMargins - rect.right}px`; 1918 } else if (rect.left > windowWidth) { 1919 item.style.left = `${windowWidth + sideMargins - rect.left}px`; 1920 } else if (rect.left <= 100) { 1921 item.style.left = "0px"; 1922 item.style.marginLeft = "0px"; 1923 } 1924 }); 1925 }); 1926 }, 1927 1928 whenElementContentBoxInScreen(selector, t, o, n, s, r, a, c) { 1929 const element = document.querySelector(selector); 1930 if (!element) return; 1931 1932 const container = element.closest(".crm-messages__container"); 1933 if (!container) return; 1934 1935 let triggered = false; 1936 1937 const observer = new IntersectionObserver( 1938 (entries) => { 1939 entries.forEach((entry) => { 1940 if (entry.isIntersecting && !triggered) { 1941 triggered = true; 1942 1943 if (r && window.innerWidth >= 768) { 1944 bkjsBlog.gtm.doEventAnalyticsPromoViewEEC(t, o, n, s); 1945 bkjsBlog.gtm.doEventAnalyticsPromoViewEEC(a, c, n, s); 1946 } else { 1947 bkjsBlog.gtm.doEventAnalyticsPromoViewEEC(t, o, n, s); 1948 } 1949 1950 observer.disconnect(); 1951 } 1952 }); 1953 }, 1954 { threshold: 1.0 } 1955 ); 1956 1957 observer.observe(container); 1958 }, 1959 }, 1960 1961 gtm: { 1962 _pushToDataLayer(data) { 1963 if (typeof dataLayer !== "undefined") { 1964 dataLayer.push(data); 1965 } 1966 }, 1967 1968 doEventAnalytics(category, action, label, value) { 1969 this._pushToDataLayer({ category, action, label, value, event: "eventga" }); 1970 }, 1971 1972 doEventAnalyticsExtended(category, action, label, type, position, element, order, value) { 1973 this._pushToDataLayer({ category, action, label, type, position, element, order, value, event: "eventga" }); 1974 }, 1975 1976 doVirtualUrl(virtualUrl) { 1977 this._pushToDataLayer({ virtualUrl, event: "virtualurl" }); 1978 }, 1979 1980 launchGtmAccordion(el, label, type, position) { 1981 const parentDiv = el.closest("div"); 1982 const isOpened = parentDiv?.classList.contains("opened") && el.classList.contains("opened"); 1983 1984 if (!isOpened) { 1985 bkjs.gtm.doEventAnalyticsExtended("Navegacion", "Enlace interno", "#", "enlace", label, type, position, undefined); 1986 } 1987 }, 1988 1989 launchGtmFaqs(el, order) { 1990 if (!el.classList.contains("opened")) { 1991 bkjs.gtm.doEventAnalyticsExtended("Navegacion", "Enlace interno", "#", "enlace", "Faqs", "Preguntas frecuentes", order, undefined); 1992 } 1993 }, 1994 1995 doEventAnalyticsWithDimensions(category, action, label, value, dimensions) { 1996 if (typeof dataLayer === "undefined") return; 1997 1998 const payload = { category, action, label, value, event: "eventga" }; 1999 if (dimensions && typeof dimensions === "object") { 2000 Object.assign(payload, dimensions); 2001 } 2002 dataLayer.push(payload); 2003 }, 2004 2005 doEventAnalyticsWithCarrusel(e) { 2006 const activeSlide = document.querySelector(".carousel__slide--active"); 2007 const description = activeSlide?.getAttribute("data-description") || null; 2008 const x = e?.touches?.[0]?.clientX ?? null; 2009 2010 bkjsBlog._carouselState.nodo = description; 2011 bkjsBlog._carouselState.initialX = x; 2012 }, 2013 2014 doEventAnalyticsWithCarruselEnd(e, product) { 2015 const { initialX, nodo } = bkjsBlog._carouselState; 2016 2017 if (initialX && initialX !== 0 && e?.touches?.[0]) { 2018 const currentX = e.touches[0].clientX; 2019 const etiqueta = initialX > currentX ? "Desplazar Izquierda" : "Desplazar Derecha"; 2020 bkjsBlog._carouselState.initialX = 0; 2021 2022 setTimeout(() => { 2023 const activeSlide = document.querySelector(".carousel__slide--active"); 2024 const descriptionNew = activeSlide?.getAttribute("data-description") || null; 2025
2026 if (nodo !== descriptionNew && activeSlide) { 2027 const order = activeSlide.getAttribute("data-index-number"); 2028 bkjs.gtm.doEventAnalyticsWithDimensions("Interaccion", "Carrusel", etiqueta, undefined, { 2029 product, 2030 position: "caracteristicas producto", 2031 element: descriptionNew, 2032 type: "swipe", 2033 order, 2034 }); 2035 } 2036 }, 200); 2037 } 2038 }, 2039 2040 doEventAnalyticsEnhancedEEC(name, id, price, brand, category) { 2041 this._pushToDataLayer({ 2042 event: "detail", 2043 ecommerce: { detail: { products: [{ name, id, price, brand, category }] } }, 2044 }); 2045 }, 2046 2047 doEventAnalyticsEnhancedAddEEC(name, id, price, brand, category, quantity) { 2048 this._pushToDataLayer({ 2049 event: "addToCart", 2050 ecommerce: { 2051 currencyCode: "EUR", 2052 add: { products: [{ name, id, price, brand, category, quantity }] }, 2053 }, 2054 }); 2055 }, 2056 2057 doEventAnalyticsPromoViewEEC(id, name, creative, position) { 2058 this._pushToDataLayer({ 2059 event: "ecommerce.js", 2060 ecommerce: { promoView: { promotions: [{ id, name, creative, position }] } }, 2061 }); 2062 }, 2063 2064 doEventAnalyticsPromoClickEEC(id, name, creative, position) { 2065 if (typeof dataLayer === "undefined") return; 2066 2067 dataLayer.push({ 2068 event: "ecommerce.js", 2069 ecommerce: { promoClick: { promotions: [{ id, name, creative, position }] } }, 2070 }); 2071 dataLayer.push({ event: "eventga" }); 2072 }, 2073 2074 _getSubscriptionValue() { 2075 const checkboxes = document.querySelectorAll(".suscribirse__checkbox--modal"); 2076 if (checkboxes.length < 2) return undefined; 2077 2078 const [cb1, cb2] = checkboxes; 2079 if (cb1.checked && cb2.checked) return "Diario-Semanal"; 2080 if (cb1.checked) return "Diario"; 2081 if (cb2.checked) return "Semanal"; 2082 return undefined; 2083 }, 2084 2085 doEventAnalyticsSubscription() { 2086 this._pushToDataLayer({ 2087 category: "Interaccion", 2088 action: "Newsletter - Blog", 2089 label: "Solicitar suscripcion", 2090 value: this._getSubscriptionValue(), 2091 event: "eventga", 2092 }); 2093 }, 2094 2095 doEventAnalyticsCorrectSubscription() { 2096 this._pushToDataLayer({ 2097 category: "Conversion", 2098 action: "Newsletter - Blog", 2099 label: "Confirmar suscripcion", 2100 value: this._getSubscriptionValue(), 2101 event: "eventga", 2102 }); 2103 }, 2104 2105 doEventAnalyticsSocialNetwork(action, label, position) { 2106 this._pushToDataLayer({ category: "Interaccion", action, label, position, event: "eventga" }); 2107 }, 2108 2109 doEventInteractionPromotion(id, name, creative, position) { 2110 this._pushToDataLayer({ 2111 event: "ecommerce.js", 2112 ecommerce: { promoClick: { promotions: [{ id, name, creative, position }] } }, 2113 eventCallback() {}, 2114 }); 2115 }, 2116 }, 2117 2118 setShareSticky(selector) { 2119 const el = document.querySelector(selector); 2120 if (!el) return; 2121 2122 const initialTop = el.getBoundingClientRect().top + window.scrollY; 2123 2124 window.addEventListener( 2125 "scroll", 2126 () => { 2127 const isSticky = window.scrollY >= initialTop; 2128 const hasClass = el.classList.contains("share__content--sticky"); 2129 2130 if (isSticky && !hasClass) { 2131 bkjs.commons.classesToEl(el, "add", "share__content--sticky"); 2132 } else if (!isSticky && hasClass) { 2133 bkjs.commons.classesToEl(el, "remove", "share__content--sticky"); 2134 } 2135 }, 2136 { passive: true } 2137 ); 2138 }, 2139 }; 2140 2141 // Matriz compartida para cálculos de equalSize (reutilizada en init y resize) 2142 const EQUAL_SIZE_PAIRS = [ 2143 ['.product-features', '.section-heading__title'], 2144 ['.product-features', '.section-heading__description'], 2145 ['.product-features', '.section-heading'], 2146 ['.product-features', '.content-box__content__title'], 2147 ['.product-features', '.content-box__content-title'], 2148 ['.product-features', '.content-box__content p'], 2149 ['.simple-info', '.simple-info__title'], 2150 ['.simple-info', 'p'], 2151 ['.content-box', '.section-heading__title'], 2152 ['.content-box', '.section-heading__description'], 2153 ['.content-box', '.section-heading p'], 2154 ['.filter__boxes', '.section-heading__title'], 2155 ['.filter__boxes', '.content-box__content'], 2156 ['.simulador-result', '.nombre-simulador'],
2157 ['.simulador-result', '.pagos-simulador'], 2158 ['.simulador-result', '.impuestos-simulador'], 2159 ['.simulador-result', '.button-simulador'], 2160 ['.carousel__inner', '.content-box'], 2161 ['.content-swap', '.content-box__content'], 2162 ['.cols-equal-size', '.content-box p'], 2163 ['.cols-equal-size', '.section-heading_second'], 2164 ['.cols-equal-size', '.content-box__content'], 2165 ['.featured-box__multiple', '.featured-box'] 2166 ]; 2167 2168 // Helper Debounce 2169 function debounce(fn, delay = 150) { 2170 let timeoutId; 2171 return function (...args) { 2172 clearTimeout(timeoutId); 2173 timeoutId = setTimeout(() => fn.apply(this, args), delay); 2174 }; 2175 } 2176 2177 // ========================================== 2178 // 2. INICIALIZACIÃN DOMCONTENTLOADED 2179 // ========================================== 2180 document.addEventListener("DOMContentLoaded", function () { 2181 const dSiteName = document.body?.dataset?.sitename ?? null; 2182 if (dSiteName === 'NBOL') { 2183 bkjs.nbol.launchModal(); 2184 } 2185 2186 bkjs.components.closeModal(); 2187 2188 // --- LÃGICA DEL BLOG --- 2189 if (dSiteName === 'Blog') { 2190 const { components, setShareSticky } = bkjsBlog; 2191 components.toggleDropdownElement(".button__header-menu", ".header-blog", "header-blog--menu-opened"); 2192 components.toggleDropdownElement(".button__header-search", ".header-blog", "header-blog--search-opened"); 2193 components.toggleMenuList(); 2194 components.formFullWidth(); 2195 setShareSticky(".share__content"); 2196 ajustFooterMobile(); 2197 2198 if (window.innerWidth <= 1165) { 2199 requestAnimationFrame(() => components.popover()); 2200 } 2201 2202 const socialBtn = document.querySelector(".button__header-menu-social"); 2203 if (socialBtn) { 2204 const socialMediaMenu = document.querySelector(".header-blog__menu-social-media"); 2205 const socialIcon = document.querySelector(".header-blog__social"); 2206 const linkSueldo = document.querySelector(".header-blog__link-calculadora-sueldo-neto"); 2207 2208 socialBtn.addEventListener("click", () => { 2209 socialMediaMenu?.classList.toggle("d-none"); 2210 2211 if (socialIcon) { 2212 const isShare = socialIcon.classList.contains("icon--share-16"); 2213 socialIcon.classList.toggle("icon--share-16", !isShare); 2214 socialIcon.classList.toggle("icon--close-16", isShare); 2215 2216 if (linkSueldo && window.innerWidth >= 768) { 2217 linkSueldo.classList.toggle("d-none", isShare); 2218 linkSueldo.classList.toggle("d-md-block", !isShare); 2219 } 2220 } 2221 }); 2222 } 2223 } 2224 2225 2226 // --- COMMONS Y COMPONENTS GENERALES --- 2227 const { commons, components } = bkjs; 2228 2229 commons.msieversion(); 2230 commons.toggleHeaderSize(); 2231 commons.setMainContentPaddingTop(); 2232 commons.loadingButton(); 2233 2234 if (dSiteName === 'roboadvisor') { 2235 commons.cleanMenuRoboadvisor(); 2236 components.closeButtonSticky(); 2237 } 2238 2239 2240 commons.setMenuActiveOption(); 2241 commons.closeLayer(); 2242 commons.analyzeFormContent(); 2243 components.toggleDropdown(); 2244 commons.opinatorPagaComodoAbandono(); 2245 components.toggleCheckboxEllipsis(); 2246 components.openModal(); 2247 components.openMessage(); 2248 components.closeMessage(); 2249 components.openClausula(); 2250 components.closeClausula(); 2251 components.accesibleIconSelectorRadio(); 2252 components.clickFilters(); 2253 components.clickFiltersModal(); 2254 components.initSmoothHrefMode(); 2255 commons.mainBannerCarousel(); 2256 components.launchJumpContent(); 2257 commons.equalSizeNoParentElement('.card--simple-equal-size'); 2258 commons.equalSizeNoParentElement('.card__body-grid-equal-size'); 2259 2260 // --- AJUSTES POR SITENAME --- 2261 if (['NBOL', 'Broker'].includes(dSiteName)) { 2262 if (document.querySelector('.breadcrumbs__item')) { 2263 document.querySelector('.header-bk-wem')?.classList.add('header-bk-wem--container-mobile--breadcrumb'); 2264 } 2265 } 2266 2267 if (['NBOL', 'Empresas', 'Broker'].includes(dSiteName)) { 2268 const footerGray = document.querySelector('.footer-gray'); 2269 const featuredSticky = document.querySelector('.featured-box_sticky'); 2270 const footer = document.querySelector('.footer'); 2271 2272 if (footerGray) { 2273 document.body.classList.add('footer-gray-body'); 2274 if (featuredSticky) { 2275 footerGray.style.paddingBottom = '104px'; 2276 } 2277 } 2278 2279 if (footer && featuredSticky) { 2280 footer.style.paddingBottom = `${featuredSticky.offsetHeight}px`; 2281 } 2282 } 2283 2284 commons.goToIdTarget(); 2285 components.toggleCtaInterval('#init-cta', '#end-cta'); 2286 components.ctaStickyMobile(); 2287 2288 // --- CÃLCULO INICIAL EQUAL-SIZE --- 2289 if (document.querySelector('.equal-size')) { 2290 requestAnimationFrame(() => { 2291 EQUAL_SIZE_PAIRS.forEach(([parent, target]) => commons.equalSize(parent, target)); 2292 2293 const extraSize = window.innerWidth >= 768 ? 64 : 100; 2294 commons.equalSize('.filter__boxes--element-wrapper', '.filter__boxes--element', extraSize); 2295 2296 if (window.innerWidth >= 1024) { 2297 commons.equalSize('.graph-row', '.container-graph'); 2298 } 2299 }); 2300 } 2301 2302 // --- EVENTO DE CLICK EN FILTROS (ASIGNACIÃN ÃNICA) --- 2303 document.querySelectorAll('.filters__element').forEach((element) => { 2304 element.addEventListener('click', () => { 2305 const extraSize = window.innerWidth >= 768 ? 64 : 100; 2306 bkjs.commons.equalSize('.filter__boxes--element-wrapper', '.filter__boxes--element', extraSize); 2307 }); 2308 }); 2309 2310 if (document.querySelector('.simple-info--equal-size') && window.innerWidth > 991) { 2311 commons.equalSizeNoParentElement('.simple-info--equal-size'); 2312 } 2313 2314 jsPropagateParamsUrl(); 2315 }); 2316 2317 // ========================================== 2318 // 3. EVENTO RESIZE CON DEBOUNCE 2319 // ========================================== 2320 const handleResize = () => { 2321 const { commons, components } = bkjs; 2322 const dSiteName = document.body?.dataset?.sitename ?? null; 2323 commons.setMainContentPaddingTop(); 2324 components.calcPositionFixed(); 2325 components.ctaStickyMobile(); 2326 2327 // B) Lógica especÃfica del Blog en Resize 2328 if (dSiteName === 'Blog') { 2329 if (typeof ajustFooterMobile === 'function') ajustFooterMobile(); 2330 2331 document.querySelectorAll('.popover__item').forEach((item) => { 2332 item.style.left = ''; 2333 }); 2334 2335 if (window.innerWidth <= 1165) { 2336 bkjsBlog.components.popover(); 2337 } 2338 } 2339 2340 // C) Lógica de Cajas e Info Simple 2341 const simpleInfoBoxes = document.querySelectorAll('.simple-info--equal-size'); 2342 if (simpleInfoBoxes.length > 0) {
2343 simpleInfoBoxes.forEach((box) => box.removeAttribute('style')); 2344 if (window.innerWidth >= 992) { 2345 commons.equalSizeNoParentElement('.simple-info--equal-size'); 2346 } 2347 } 2348 2349 // D) Recálculo de alturas con requestAnimationFrame 2350 requestAnimationFrame(() => { 2351 EQUAL_SIZE_PAIRS.forEach(([parent, target]) => commons.equalSize(parent, target)); 2352 2353 const extraSize = window.innerWidth >= 768 ? 64 : 100; 2354 commons.equalSize('.filter__boxes--element-wrapper', '.filter__boxes--element', extraSize); 2355 2356 if (window.innerWidth >= 1024) { 2357 commons.equalSize('.graph-row', '.container-graph'); 2358 } 2359 }); 2360 }; 2361 2362 window.addEventListener('resize', debounce(handleResize, 150)); 2363})(); 2364 2365 2366function elementVisible(e) { 2367 if (null == e) return !1; 2368 let t = e.getBoundingClientRect(); 2369 return t.top >= 0 && t.left >= 0 && t.right <= (window.innerWidth || document.documentElement.clientWidth) && t.bottom <= (window.innerHeight || document.documentElement.clientHeight); 2370} 2371 2372function ajustFooterMobile() { 2373 setTimeout(function () { 2374 if (window.innerWidth < 576) { 2375 if (document.querySelector('.share')) { 2376 document.querySelector('footer').style.paddingBottom = document.querySelector('.share').clientHeight + 'px'; 2377 if (document.querySelector('.floating-link--sticky')) { 2378 document.querySelector('.floating-link--sticky').querySelector('.featured-box').style.bottom = document.querySelector('.share').clientHeight; 2379 document.querySelector('footer').style.paddingBottom = (document.querySelector('.share').clientHeight + document.querySelector('.floating-link--sticky').querySelector('.featured-box').clientHeight) + 'px'; 2380 } 2381 if (document.querySelector('.featured-box--sticky-bloqued')) { 2382 document.querySelector('.featured-box--sticky-bloqued').style.bottom = document.querySelector('.share').clientHeight + 'px'; 2383 document.querySelector('footer').style.paddingBottom = (document.querySelector('.share').clientHeight + document.querySelector('.featured-box--sticky-bloqued').clientHeight) + 'px'; 2384 } 2385 } else { 2386 if (document.querySelector('.floating-link--sticky')) { 2387 document.querySelector('footer').style.paddingBottom = document.querySelector('.floating-link--sticky').querySelector('.featured-box').clientHeight + 'px'; 2388 } 2389 if (document.querySelector('.featured-box--sticky-bloqued')) { 2390 document.querySelector('footer').style.paddingBottom = +document.querySelector('.featured-box--sticky-bloqued').clientHeight + 'px'; 2391 } 2392 } 2393 } 2394 }, 1000); 2395} 2396 2397//UCPM 2398async function sha256(value) { 2399 const encoder = new TextEncoder(); 2400 const data = encoder.encode(value); 2401 const hashBuffer = await crypto.subtle.digest('SHA-256', data); 2402 const hashBytes = new Uint8Array(hashBuffer); 2403 return Array.from(hashBytes, byte => byte.toString(16).padStart(2, '0')).join(''); 2404} 2405 2406function formatIntNumberE164(phone) { 2407 const cleaned = phone.replace(/[^\d+]/g, ""); 2408 if (cleaned.startsWith("+")) return cleaned; 2409 if (cleaned.startsWith("00")) return `+${cleaned.slice(2)}`; 2410 return `+34${cleaned}`; 2411} 2412 2413async function callUCPM(data) { 2414 const input = document.querySelector('[name="ucpm-code"]'); 2415 if (!input || !input.value) { 2416 return; 2417 } 2418 const token = await callUCPMobtainToken(input.value); 2419 if (!token) return; 2420 return await callUCPMSaveElem(token, data); 2421} 2422 2423 2424async function callUCPMobtainToken(code) { 2425 const hostnameAPiUcpm = typeof hostnameApi !== "undefined" ? hostnameApi : "https://brokerapi.bankinter.com"; 2426 const url = `${hostnameAPiUcpm}/api/consentmanager/v1/collectionPoints/${encodeURIComponent(code)}/token`; 2427 try { 2428 const response = await fetch(url, { 2429 headers: { "Accept": "application/json" } 2430 }); 2431 if (!response.ok) throw new Error(`HTTP Error: ${response.status}`); 2432 return await response.json(); 2433 } catch (error) { 2434 console.log("Error llamando al endpoint:", error); 2435 return null; 2436 } 2437} 2438 2439async function callUCPMSaveElem(JWTcode, data) { 2440 const hostnameAPiUcpm = typeof hostnameApi !== "undefined" ? hostnameApi : "https://brokerapi.bankinter.com"; 2441 const url = `${hostnameAPiUcpm}/api/consentmanager/v1/request/consentReceipts`; 2442 const dataObject = objectToKeyValueArray(data); 2443 const dataMap = Object.fromEntries( 2444 dataObject.map(({ key, value }) => [key, value]) 2445 ); 2446 2447 const componentName = dataMap.component_name; 2448 const purposes = dataMap.purposes; 2449 2450 const keyMap = { 2451 mkt_hash_id_02: "PhoneHashed", 2452 mkt_hash_id_01: "EmailHashed", 2453 mkt_id_02: "Phone", 2454 mkt_id_01: "Email", 2455 nombre_apellidos: "Name" 2456 }; 2457 2458 const dataObjectFilteredRenamed = dataObject 2459 .filter(({ key }) =>
2459 key in keyMap) 2460 .map(({ key, value }) => ({ 2461 key: keyMap[key], 2462 value 2463 })); 2464 2465 const mktInfo = getMktInfo(dataObject); 2466 2467 const hn = window.location.hostname; 2468 const isTest = !(hn.endsWith('.com') || hn.endsWith('.es') || hn.endsWith('.ie')); 2469 2470 const body = { 2471 requestInformation: JWTcode.token, 2472 identifier: mktInfo.id, 2473 identifierType: mktInfo.type, 2474 dataElements: dataObjectFilteredRenamed, 2475 purposes: purposes, 2476 customPayload: [ 2477 {key:"formProcess", value: componentName}, 2478 {key:"formStep",value:"paso1"}, 2479 {key:"formUrl",value: window.location.href}, 2480 2481 ], 2482 test: isTest 2483 }; 2484 2485 try { 2486 const response = await fetch(url, { 2487 method: "POST", 2488 headers: { 2489 "Content-Type": "application/json" 2490 }, 2491 body: JSON.stringify(body) 2492 }); 2493 2494 return response.ok ? "OK" : "KO"; 2495 } catch (error) { 2496 console.log("Error al llamar al endpoint:", error); 2497 return "KO"; 2498 } 2499} 2500 2501function getMktInfo(obj) { 2502 const mkt01 = obj.find(el => el.key === 'mkt_id_01'); 2503 if (mkt01) return { 2504 id: mkt01.value, 2505 type: "Email" 2506 }; 2507 const mkt02 = obj.find(el => el.key === 'mkt_id_02'); 2508 if (mkt02) return { 2509 id: mkt02.value, 2510 type: "Phone" 2511 }; 2512 return null; 2513} 2514 2515function objectToKeyValueArray(obj) { 2516 return Object.entries(obj) 2517 .filter(([_, value]) => 2518 typeof value === 'string' || 2519 (Array.isArray(value) && value.every(v => typeof v === 'string')) 2520 ) 2521 .map(([key, value]) => ({ 2522 key, 2523 value 2524 })); 2525} 2526 2527function obtenerUCPMPurposes() { 2528 const inputs = document.querySelectorAll('input[type="checkbox"][ucpm-purpose]:checked'); 2529 const values = Array.from(inputs, input => input.getAttribute('ucpm-purpose')).filter(Boolean); 2530 return [...new Set(values)]; 2531} 2532 2533let codeOTPOperative=''; 2534 2535async function launchOTPUCPM(data) { 2536 try{ 2537 bkrRestDataNew.commons.loadRestHeader(); 2538 }catch(error){} 2539 const modal = data.closest('.modal'); 2540 if (!modal) return; 2541 const email = modal.querySelector('.otp-email').value; 2542 const name = modal.querySelector('.otp-name').value; 2543 2544 let hostnameApiOTP = typeof hostnameApi !== "undefined" ? hostnameApi : "https://brokerapi.bankinter.com"; 2545 const url = `${hostnameApiOTP}/api/investmentacademymgmt/v1/otpOperatives`; 2546 try { 2547 const response = await fetch(url, { 2548 method: "POST", 2549 headers: {"Content-Type": "application/json"}, 2550 body: JSON.stringify({ email, name, operativeType: 'investment_academy_access' }) 2551 }); 2552 2553 if (!response.ok) { 2554 throw new Error(`Error HTTP: ${response.status}`); 2555 } 2556 const resjson = await response.json(); 2557 codeOTPOperative =resjson.id; 2558 } catch (error) { 2559 console.log("Error al llamar al endpoint:", error); 2560 } 2561} 2562async function launchOTPUCPMCode(data) { 2563 const code = data.closest('.modal').querySelector('.otp-code').value; 2564 const hostnameApiOTP = typeof hostnameApi !== "undefined" ? hostnameApi : "https://brokerapi.bankinter.com"; 2565 const url = `${hostnameApiOTP}/api/investmentacademymgmt/v1/otpOperatives/${codeOTPOperative}`; 2566 try { 2567 const response = await fetch(url, { 2568 method: "POST", 2569 headers: {"Content-Type": "application/json"}, 2570 body: JSON.stringify({otp: code}) 2571 }); 2572 return response.ok ? "OK" : "KO"; 2573 } catch (error) { 2574 console.log("Error al llamar al endpoint:", error); 2575 return "KO"; 2576 } 2577} 2578 2579function jsPropagateParamsUrl(){ 2580 const landingParams = new URLSearchParams(window.location.search); 2581 if (!landingParams.toString()) { 2582 return; 2583 } 2584 document.querySelectorAll('.js-propagate-params').forEach(function (link) { 2585 const url = new URL(link.href, window.location.origin); 2586 2587 landingParams.forEach(function (value, key) { 2588 if (!url.searchParams.has(key)) { 2589 url.searchParams.append(key, value); 2590 } 2591 }); 2592 2593 link.href = url.toString(); 2594 }); 2595} 2596 2597document.addEventListener('click', function(event) { 2598 const link = event.target.closest('a.link-with-params-onboarding'); 2599 if (!link) return; 2600 event.preventDefault(); 2601 const originalHref = link.getAttribute('href'); 2602 2603 try { 2604 const url = new URL(originalHref, window.location.origin); 2605 // Comprobamos si la variable existe, es un objeto y no es null 2606 if (typeof URL_PARAMS === 'object' && URL_PARAMS !== null) {
2607 Object.entries(URL_PARAMS).forEach(([key, value]) => { 2608 if (value !== null && value !== undefined && value !== '') { 2609 url.searchParams.set(key, value); 2610 } 2611 }); 2612 } 2613 window.location.href = url.toString(); 2614 } catch (error) { 2615 window.location.href = originalHref; 2616 } 2617});
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.