(function ($, hotspots, undefined) { "use strict"; var Leaflet = L.noConflict(); var ua = window.navigator.userAgent, isiOS = !!ua.match(/iPad/i) || !!ua.match(/iPhone/i), isWebkit = !!ua.match(/WebKit/i), isWebkitiOS = isiOS && isWebkit, isMobileSafari = isiOS && isWebkit && !ua.match(/CriOS/i), getBrowserVersion = function () { var temp, M = ua.match( /(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i, ) || []; M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, "-?"]; if ((temp = ua.match(/version\/(\d+)/i)) != null) { M.splice(1, 1, temp[1]); } return parseInt(M[1]); }; // Store all the leaflets on the page in an array for access later var leaflets = []; // Store all image maps on the page in an object for access later var imageMaps = {}; // Store all the more info area hotspots in an object for access later hotspots.infoSpots = {}; // Intersection Observer to detect when hidden hotspots become visible var hotspotVisibilityObserver = null; const layoutsThatShowTitleOnFocus = [ "left", "right", "bottom", "top", "lightbox", ]; var setupHotspotVisibilityObserver = function () { if (!window.IntersectionObserver) { return; // Browser doesn't support Intersection Observer } hotspotVisibilityObserver = new IntersectionObserver( function (entries) { entries.forEach(function (entry) { if (entry.isIntersecting) { // Hotspot container has become visible var container = entry.target; var containerJQuery = $(container); // Check if this container was previously hidden if (containerJQuery.data("was-hidden")) { console.log("Hotspot container became visible:", container); hotspots.init(); // Reinitialize hotspots containerJQuery.removeData("was-hidden"); } } else { // Hotspot container has become hidden var container = entry.target; var containerJQuery = $(container); containerJQuery.data("was-hidden", true); } }); }, { threshold: 0.1, rootMargin: "10px", }, ); }; var observeHotspotContainer = function (container) { if (hotspotVisibilityObserver && container.length) { var containerElement = container.get(0); var rect = containerElement.getBoundingClientRect(); var isInitiallyHidden = rect.width === 0 || rect.height === 0 || window.getComputedStyle(containerElement).display === "none" || window.getComputedStyle(containerElement).visibility === "hidden"; if (isInitiallyHidden) { container.data("was-hidden", true); } hotspotVisibilityObserver.observe(containerElement); } }; var mapSetup = function () { $(".da-error").hide(); $(".hotspot-info").addClass("da-hidden"); setupHotspotVisibilityObserver(); var images = $("img.hotspots-image, picture.hotspots-image img"); // Select images as well as images inside picture elements images.each(function () { var img = $(this); var tester = new Image(); tester.onload = function () { markLoaded(img); moreInfoSetup(img); leafletSetup(img); var container = img.parents(".hotspots-container"); observeHotspotContainer(container); }; tester.src = img.attr("src"); }); if (isMobileSafari) { window.onpageshow = function (event) { if (event.persisted) { window.location.reload(); } }; } }; var markLoaded = function (img) { img.data("status", "loaded"); var container = img.parents(".hotspots-container").addClass("loaded"); img.attr("aria-hidden", true); }; var stopAudioVideo = function (el) { var iframe = el.querySelector("iframe[src*=youtube]"); var video = el.querySelector("video"); var audio = el.querySelector("audio"); if (iframe) { var iframeSrc = iframe.src; iframe.src = iframeSrc; } if (video) { video.pause(); } if (audio) { audio.pause(); } }; var moreInfoSetup = function (img) { var container = img.parents(".hotspots-container"); if (container.data("layout") == "tooltip") { return; } if (container.data("layout") == "lightbox") { lightboxSetup(container, img); return; } infoboxSetup(container, img); }; var infoboxSetup = function (container, img) { var initial = container.find(".hotspot-initial"); var content = container.find(".hotspots-placeholder"); initial.addClass("visible"); container.on("active.responsilight inactive.responsilight", function (e) { var data = $(e.target).data("areaData"); var info; if (e.type === "active") { info = $(data.href); } else { info = initial; } var visibleContent = content.children(".visible"); stopAudioVideo(visibleContent.get(0)); visibleContent.removeClass("visible"); info.removeClass("da-hidden").addClass("visible").appendTo(content); // Check for an embedded video player var video = info.find(".wp-video"); if (video.length) { if (!info.data("video-resized")) { info.data("video-resized", true); window.dispatchEvent(new Event("resize")); } } }); }; var lightboxSetup = function (container, img) { container.on("active.responsilight", function (e) { var data = $(e.target).data("areaData"), info = $(data.href), container = info.parent(), target = $(e.target), currentLightbox = $(".featherlight"); if (e.type === "active" && currentLightbox.length === 0) { $.featherlight('
', { closeLabel: drawattentionData.closeLabel, closeSpeed: 250, closeOnEsc: false, afterContent: function () { var content = $(".featherlight-inner"), lb = $(".featherlight-content"), mapNo = img.data("id"), lightboxContainer = $(".featherlight"); info.appendTo(content).show(); lb.addClass("lightbox-" + mapNo); // Apply accessibility attributes var hotspotTitle = info.find(".hotspot-title").text() || data.title || ""; lightboxContainer.attr({ tabindex: "-1", role: "dialog", "aria-modal": "true", "aria-label": hotspotTitle, }); // Fix accessibility issue - links not focusable by keyboard var untabbables = info.find("a[tabindex=-1]"); untabbables.attr("tabindex", 0); setTimeout(function () { var img = content.find("img"), contentHeight = content.get(0).scrollHeight, imgHeight = img.height(), lbHeight = lb.outerHeight(); if (contentHeight > lbHeight) { var diff = contentHeight - lbHeight + 50, newHeight = imgHeight - diff, minHeight = $(window).innerHeight() / 2; newHeight = newHeight < minHeight ? minHeight : newHeight; var naturalHeight = img.prop("naturalHeight"); if (newHeight < naturalHeight) { img.css({ width: "auto" }); img.animate( { height: newHeight, }, 200, ); } } }, 100); lightboxAnchorLinks(content, target); lightboxTrapFocus(); window.dispatchEvent(new Event("resize")); // Trigger window resize event for [video] shortcode JS }, afterOpen: function () { $("body").on("keyup", documentEsc); }, afterClose: function () { target.removeClass("hotspot-active"); $("body").off("keyup", documentEsc); }, beforeClose: function () { stopAudioVideo(document.querySelector(".featherlight-content")); setTimeout(function () { info.hide().appendTo(container); }, 500); // delay hiding content and moving it back outside the lightbox }, }); } }); }; var documentEsc = function (e) { if (e.keyCode === 27) { $.featherlight.current().close(); } }; var lightboxAnchorLinks = function (content, hotspot) { var links = content.find('.hotspot-content a[href^="#"]'); links.on("click", function (e) { e.preventDefault(); var targetEl = $(e.target.hash); var current = $.featherlight.current(); if (!current) return; current.afterClose = function () { hotspot.removeClass("hotspot-active"); $("html").removeClass("with-featherlight"); $("html, body").animate( { scrollTop: targetEl.offset().top, }, 500, ); }; current.close(); }); }; var lightboxTrapFocus = function () { var lightbox = $(".featherlight"); var focusableElements = lightbox.find( 'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [tabindex]:not([tabindex="-1"])', ); if (focusableElements.length === 0) { return; } var firstFocusable = focusableElements.first(); var lastFocusable = focusableElements.last(); // Set initial focus to the lightbox container lightbox.focus(); lightbox.on("keydown.focustrap", function (e) { if (e.key !== "Tab" && e.keyCode !== 9) { return; } if (e.shiftKey) { if ( document.activeElement === firstFocusable.get(0) || document.activeElement === lightbox.get(0) ) { e.preventDefault(); lastFocusable.focus(); } } else { if (document.activeElement === lastFocusable.get(0)) { e.preventDefault(); firstFocusable.focus(); } } }); // Clean up when lightbox closes lightbox.on("closed.featherlight", function () { lightbox.off("keydown.focustrap"); }); }; var showTooltip = function (shape, areaData) { var container = $(shape._map._container); var content = $(areaData.href).html(); var tip = Leaflet.responsivePopup({ autoPan: false, closeButton: areaData.trigger == "click", hasTip: container.width() > 840, maxHeight: container.height() * 0.9, offset: new Leaflet.Point(0, 0), }); tip.setContent(content); shape.bindPopup(tip); if (areaData.trigger === "click") { shape.on("click", function (e) { if (shape._path.classList.contains("hotspot-active")) { shape.closePopup(); } else { shape.openPopup(); } }); } else { shape.on("mouseover", function () { shape.openPopup(); }); shape.on("mouseout", function () { shape.closePopup(); }); } container.on("click", function (e) { e.stopPropagation(); }); $(document).on("click", function (e) { shape.closePopup(); shape._path.classList.remove("hotspot-active"); }); }; var leafletSetup = function (img) { var id = img.data("id"); var container = $( '
', ); var imgWidth = img.width(); var imgHeight = img.height(); container.css({ width: imgWidth + "px", height: imgHeight + "px", }); img.after(container); // Check to be sure the container is on the page // To prevent errors when loaded in Elementor popup var containerTest = $("#hotspots-map-container-" + id); if (!containerTest.length) { return; } var map = Leaflet.map("hotspots-map-container-" + id, { attributionControl: false, boxZoom: false, crs: Leaflet.CRS.Simple, doubleClickZoom: false, dragging: false, keyboard: false, minZoom: -20, scrollWheelZoom: false, // tap: !isWebkitiOS, tap: true, touchZoom: false, zoomControl: false, zoomSnap: 0, }); var domImg = img.get(0); var natHeight = domImg.naturalHeight; var natWidth = domImg.naturalWidth; img.data("natW", natWidth); img.data("natH", natHeight); var bounds = [ [0, 0], [natHeight, natWidth], ]; var imageAlt = img.attr("alt") || img.data("image-title") || ""; var imageLayer = Leaflet.imageOverlay(img.attr("src"), bounds, { alt: imageAlt, }).addTo(map); map.fitBounds(bounds); leaflets.push({ map: map, img: img, }); drawSpots(img, map); }; var showContextMenu = function (shape, areaData, e) { var hash = areaData.href; var container = $(shape._map._container); if (!hash) { return; } $(".da-address-wrapper").remove(); var windowAddress = window.location.href.split("#")[0]; var shapeAddress = windowAddress + hash; var div = $('
') .css({ left: e.originalEvent.pageX + "px", top: e.originalEvent.pageY + "px", }) .append("

" + shapeAddress + "

") .append('×') .appendTo(document.body); div.find(".da-address-close").on("click", function () { div.remove(); }); }; var drawSpots = function (img, map) { var id = img.data("id"); /* If the image has a usemap attribute, detach the map and store it in the imageMaps object */ if (img[0].hasAttribute("usemap")) { var mapName = img.attr("usemap").replace("#", ""); var imageMap = $('map[name="' + mapName + '"]'); imageMaps[id] = imageMap.detach(); img.removeAttr("usemap"); } else { /* Else we've already removed the image map, so we just need to get it */ var imageMap = imageMaps[id]; } var areas = imageMap.find("area"); var container = img.parents(".hotspots-container"); areas.each(function () { var area = $(this); var shape = area.attr("shape"); var coords = area.attr("coords").split(","); var areaData = { style: area.data("color-scheme") ? area.data("color-scheme") : "default", title: area.attr("title"), href: area.attr("href"), spot: area.data("id"), target: area.attr("target"), action: area.data("action"), layout: container.data("layout"), trigger: container.data("trigger"), }; switch (shape) { case "circle": renderCircle(coords, map, img, areaData); break; case "rect": renderPoly(coords, map, img, areaData); break; case "polygon": renderPoly(coords, map, img, areaData); break; case "poly": // Leaving this here for backward compatibility renderPoly(coords, map, img, areaData); break; } }); // A11y fixes after all the spots are drawn a11yFixes(img, map); // Link to area after all the spots are drawn hotspots.linkToArea(); }; var renderCircle = function (coords, map, img, areaData) { var x = coords[0]; var y = img.data("natH") - coords[1]; var rad = coords[2]; var circle = Leaflet.circle([y, x], { radius: rad, className: "hotspot-" + areaData.style, title: areaData.title, }); circle.on("add", function (e) { var $circle = $(e.target.getElement()); $circle.data("areaData", areaData); $circle.attr("tabindex", "0"); $circle.attr("aria-label", areaData.title); $circle.attr("name", areaData.title); }); circle.addTo(map); // If this is a more info hotspot, add it to the infoSpots object if (areaData.href.charAt(0) === "#") { var spotName = areaData.href.replace("#", ""); hotspots.infoSpots[spotName] = circle; } shapeEvents(circle, areaData); }; var renderPoly = function (coords, map, img, areaData) { var xCoords = []; var yCoords = []; for (var i = 0; i < coords.length; i++) { if (i % 2 == 0) { xCoords.push(coords[i]); } else { yCoords.push(coords[i]); } } var polyCoords = yCoords.map(function (coord, index) { return [img.data("natH") - coord, xCoords[index]]; }); var poly = Leaflet.polygon(polyCoords, { className: "hotspot-" + areaData.style, title: areaData.title, }); // Attach the area data to the path as soon as it's added to the map, a11y attributes poly.on("add", function (e) { var $poly = $(e.target.getElement()); $poly.data("areaData", areaData); $poly.attr("tabindex", "0"); $poly.attr("aria-label", areaData.title); $poly.attr("name", areaData.title); }); poly.addTo(map); // If this is a more info hotspot, add it to the infoSpots object if (areaData.href.charAt(0) === "#") { var spotName = areaData.href.replace("#", ""); hotspots.infoSpots[spotName] = poly; } shapeEvents(poly, areaData); }; var shapeOver = function (shape, areaData, e) { var $shape = $(e.target.getElement()); $shape.trigger("over.responsilight"); if ( areaData.trigger === "hover" && (e.type !== "touchstart") & (e.type !== "keypress") ) { $shape.addClass("hotspot-active"); $shape.trigger("active.responsilight"); } }; var shapeOut = function (shape, areaData, e) { var $shape = $(e.target.getElement()); $shape.trigger("out.responsilight"); if (areaData.trigger === "hover" && e.type !== "keypress") { $shape.removeClass("hotspot-active"); $shape.trigger("inactive.responsilight"); // If mouse user, blur hover spots when mouse moves out if (e.type === "mouseout") { $shape.trigger("blur"); } } }; var shapeClick = function (shape, areaData, e) { var $shape = $(e.target.getElement()); $shape.trigger("areaClick.responsilight"); if ( areaData.trigger === "hover" && e.type !== "touchstart" && e.type !== "keypress" && !isMobileSafari ) { return; } $shape.toggleClass("hotspot-active"); if ($shape.hasClass("hotspot-active")) { $shape.trigger("active.responsilight"); } else { $shape.trigger("inactive.responsilight"); } var oldActive = $shape.siblings(".hotspot-active"); if (oldActive.length) { oldActive.removeClass("hotspot-active"); } }; /** * Very Custom logic to just handle displaying the popup on focus * Why we had to do it this way: * shape.on('focus') doesn't fire similar to the other events * openPopup() would steal the focus and it's hard to then rely on focusout on shape to remove the popup, cause the focusout would fire right after calling openPopup() * closePopup() would also programmatically control/alter the tab behavior and that is another problem * */ var maybeDisplayPopupOnFocus = function (shape, areaData, nativeEvent) { if (areaData.trigger !== "hover") return; if (areaData.layout !== "tooltip") return; var $shape = $(nativeEvent.target); if ($shape.hasClass("hotspot-active")) { return; } $shape.addClass("hotspot-active"); $shape.trigger("over.responsilight"); shape.openPopup(); setTimeout(() => { const activeElement = document.activeElement; if (!activeElement.classList.contains("leaflet-rrose-content")) { return; } $shape.focus(); const closePopupAfterFocusIsLost = (e) => { shape.closePopup(); $shape.removeClass("hotspot-active"); $shape.trigger("out.responsilight"); $shape.off("focusout", closePopupAfterFocusIsLost); }; $shape.on("focusout", closePopupAfterFocusIsLost); }, 0); }; /** * Left, right, top, bottom & lightbox layout + click trigger * Display Title on focus */ var maybeDisplayTitleOnFocusForLayout = function ( shape, areaData, nativeEvent, ) { if (nativeEvent.type !== "focus") return; if (areaData.trigger !== "click") return; if (!layoutsThatShowTitleOnFocus.includes(areaData.layout)) return; const target = nativeEvent.target; target.dispatchEvent(new MouseEvent("mouseover", { bubbles: true })); target.addEventListener("focusout", function handleFocusOut(e) { target.dispatchEvent(new MouseEvent("mouseout", { bubbles: true })); target.removeEventListener("focusout", handleFocusOut); }); }; var shapeEvents = function (shape, areaData) { // Handle URL spots if (areaData.action == "url") { if (areaData.title) { shape.bindTooltip(areaData.title); } shape.on("click", function (e) { if (areaData.target == "_new" && !isMobileSafari) { // new window window.open(areaData.href, "_blank"); } else { // same window var first = areaData.href.charAt(0); var targetElem; try { targetElem = first === "#" ? $(areaData.href) : null; } catch (error) { targetElem = null; } if (targetElem && targetElem.length) { // hash link to existing target $("html, body").animate( { scrollTop: targetElem.offset().top - 50, }, 750, function () { // callback after scrolling history.pushState({}, "", areaData.href); }, ); } else { window.location = areaData.href; } } }); return; } // Show right-click context menu for logged-in admins only if (drawattentionData.isLoggedIn && drawattentionData.isAdmin) { shape.on("contextmenu", function (e) { showContextMenu(shape, areaData, e); }); } // Handle tooltip spots if (areaData.layout === "tooltip") { showTooltip(shape, areaData); } // Add styled tooltip to all non-hover areas if ( areaData.action === "url" || (areaData.trigger === "click" && areaData.layout !== "tooltip") ) { if (areaData.title) { shape.bindTooltip(areaData.title); } } // Handle all other spots var moved = false; shape.on( "touchstart touchmove touchend click mouseover mouseout keypress focus blur", function (e) { switch (e.type) { case "touchstart": moved = false; break; case "touchmove": moved = true; break; case "touchend": if (moved) { return; } shapeOver(shape, areaData, e); shapeClick(shape, areaData, e); break; case "click": shapeClick(shape, areaData, e); break; case "keypress": var key = e.originalEvent.which; if (key == 13 || key == 32) { e.originalEvent.preventDefault(); shapeClick(shape, areaData, e); } break; case "mouseover": if (!isMobileSafari || (isMobileSafari && getBrowserVersion < 13)) { shapeOver(shape, areaData, e); } if (isMobileSafari && !(getBrowserVersion() >= 12)) { shapeClick(shape, areaData, e); } break; case "focus": shapeOver(shape, areaData, e); break; case "blur": shapeOut(shape, areaData, e); break; case "mouseout": shapeOut(shape, areaData, e); break; } }, ); $(shape._path).on("focus", function (nativeEvent) { maybeDisplayPopupOnFocus(shape, areaData, nativeEvent); maybeDisplayTitleOnFocusForLayout(shape, areaData, nativeEvent); }); }; var a11yFixes = function (img, map) { let svg = img .siblings(".leaflet-container") .find(".leaflet-overlay-pane svg"); let id = img.data("id"); // Add title and description to SVG svg.prepend( '' + img.data("image-description") + "", ); svg.prepend( '' + img.data("image-title") + "", ); // Use title and desc to describe the svg svg.attr("aria-labelledby", "img-title-" + id); svg.attr("aria-describedby", "img-desc-" + id); // Make svg screen reader traversable svg.attr("role", "group"); // Create a traversable list var group = svg.find("g").attr("role", "list"); group.children().attr("role", "listitem"); // Handle tooltips for the map map.on("popupopen", function (popup) { // shift focus to the popup when it opens $(popup.popup._container) .find(".leaflet-rrose-content") .attr("tabindex", "-1") .focus(); // move the close button to the end of the popup content so screen readers reach it // after the main popup content, not before var close = $(popup.popup._container) .find(".leaflet-rrose-close-button") .detach(); close.attr("aria-label", "Close item"); $(popup.popup._container).append(close); $(document).on("keydown", function (e) { if (e.which == 27) { map.closePopup(); } }); }); // return focus to the icon we started from before opening the pop up map.on("popupclose", function (popup) { $(document).off("keydown"); $(popup.popup._source._path).focus(); }); }; hotspots.linkToArea = function () { // Called after the shapes are drawn var hash = window.location.hash; if (!hash) return; var spotName = hash.replace("#", ""); if (!hotspots.infoSpots.hasOwnProperty(spotName)) return; Object.keys(hotspots.infoSpots).forEach(function (key) { hotspots.infoSpots[key].closeTooltip(); }); const spot = hotspots.infoSpots[spotName]; if (!spot._path.classList.contains("hotspot-active")) { spot.fire("click"); } scrollIntoViewIfNeeded(spot._map?.getContainer()); }; hotspots.setup = function () { mapSetup(); }; hotspots.resizeTimer = null; hotspots.resizing = false; hotspots.init = function () { // For backward compatibility - resets the size of the leaflet on demand leaflets.forEach(function (item) { var isLoaded = item.img.data("status") === "loaded"; if (!isLoaded) { return; } item.img.next(".hotspots-map-container").css({ width: item.img.width() + "px", height: item.img.height() + "px", }); item.map.invalidateSize(true); item.map.fitBounds([ [0, 0], [item.img.data("natH"), item.img.data("natW")], ]); }); }; hotspots.compatibilityFixes = function () { if (window.Foundation) { /* Fix for Foundation firing tag change event indiscriminately when some items are clicked on the page */ $(window).on("change.zf.tabs", function (e) { if (e.target.tagName !== "INPUT") { hotspots.init(); } }); } $(window).on("pageloaded load", function () { /* Listen for pageloaded and load events on the window */ hotspots.init(); }); $(window).on("et_hashchange", function () { /* Listen for Divi hashchange */ setTimeout(function () { hotspots.init(); }, 1000); }); $(".ult_tabs").on("click", ".ult_tab a", function () { /* Ultimate tabs */ setTimeout(function () { hotspots.init(); }, 2000); }); $( "a[data-vc-accordion], .et_pb_tabs .et_pb_tabs_controls li, .et_pb_toggle_title", ).on("click", function () { /* Divi tabs, accordion, toggle */ setTimeout(function () { hotspots.init(); }, 1000); }); $(".vc_tta-tabs-container").on("click", ".vc_tta-tab", function () { /* Visual composer tabs */ setTimeout(function () { hotspots.init(); }, 1000); }); $(".ui-tabs-anchor, .nav-tabs > li").on("click", function () { /* UI Tabs */ setTimeout(function () { hotspots.init(); }, 750); }); $(".fl-accordion-button").on("click", function () { /* Beaver Builder accordion */ setTimeout(function () { hotspots.init(); }, 500); }); $(".responsive-tabs").on( "click", ".responsive-tabs__list__item", function () { /* Responsive tabs */ hotspots.init(); }, ); $(".elementor-tabs").on("click", ".elementor-tab-title", function () { /* Elementor tabs */ hotspots.init(); }); $(".fl-tabs").on("click", "a.fl-tabs-label", function () { /* Beaver Builder tabs */ hotspots.init(); }); $(".uabb-adv-accordion-button .uabb-tabs").on("click", function () { /* Ultimate Beaver Builder addons accordion and tabs */ setTimeout(function () { hotspots.init(); }, 250); }); $(".w-tabs-item").on("click", function () { /* Custom Woocommerce tabs */ setTimeout(function () { hotspots.init(); }, 1000); }); }; })(jQuery, (window.hotspots = window.hotspots || {})); jQuery(function () { hotspots.setup(); hotspots.compatibilityFixes(); }); jQuery(document).on("elementor/popup/show", function () { hotspots.setup(); hotspots.compatibilityFixes(); }); jQuery(window).on("resize orientationchange", function (e) { var $window = jQuery(this); if (!hotspots.resizing) { $window.trigger("resizeStart.responsilight"); hotspots.resizing = true; } clearTimeout(hotspots.resizeTimer); hotspots.resizeTimer = setTimeout(function () { hotspots.init(); $window.trigger("resizeComplete.responsilight"); hotspots.resizing = false; }, 250); }); jQuery(window).on("hashchange", function () { hotspots.linkToArea(); }); window.onerror = function (errorMsg, url, lineNumber) { // This should be a fun little experiement! var errorBox = jQuery(".da-error").show(); if (errorBox.length) { var contents = errorBox.html(); errorBox.html( contents + "

Error: " + errorMsg + "
Line " + lineNumber + ": " + url, ); } return false; }; /* Fix for Elementor bug - duplicating DA images when popup opens */ jQuery(document).on("elementor/popup/show", () => { setTimeout(function () { var imageContainers = jQuery(".hotspots-image-container"); imageContainers.each(function () { var extraMapContainers = jQuery(this) .find(".hotspots-map-container:not(:first)") .remove(); // find all but the first one and remove them }); }, 250); }); function scrollIntoViewIfNeeded(el, options = {}) { if (!el) return; const rect = el.getBoundingClientRect(); const fullyVisible = rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth); if (!fullyVisible) { el.scrollIntoView(options); } }