PageSourceSearch

https://plavakamenica.hr/wp-content/plugins/breakdance/subplugins/…/breakdance-back-to-top.js?bd_ver=2.8.1

js plavakamenica.hr collected 2026-10-02 11:22:49 UTC 4,506 bytes, 140 lines download raw bytes

1(function () {
2  const { mergeObjects } = BreakdanceFrontend.utils;
3
4  const isSelectorValid = (selector) => {
5    const queryCheck = (s) =>
6      document.createDocumentFragment().querySelector(s);
7
8    try {
9      queryCheck(selector);
10    } catch {
11      return false;
12    }
13    return true;
14  };
15
16  class BreakdanceBackToTop {
17    defaultOptions = {
18      type: "progress",
19      show: "always",
20      advanced: {
21        scroll_offset: 0,
22        scroll_to_selector: null,
23      },
24    };
25
26    constructor(selector, options) {
27      this.selector = selector;
28      this.element = document.querySelector(`${this.selector}`);
29      this.button = document.querySelector(
30        `${this.selector} .js-ee-back-to-top`
31      );
32      this.rootElement = document.documentElement;
33      this.options = mergeObjects(this.defaultOptions, options);
34      this.init();
35    }
36
37    destroy() {
38      this.button.removeEventListener("click", this.handleClick);
39      document.removeEventListener("scroll", this.handleScroll);
40      if (this.options.type === "progress") {
41        document.removeEventListener("scroll", this.handlePercentageScroll);
42      }
43    }
44
45    init() {
46      // handle button events
47      this.handleClick = this.clickHandler.bind(this);
48      this.button.addEventListener("click", this.handleClick);
49      // handle scroll animations
50      this.handleScroll = this.scrollHandler.bind(this);
51      document.addEventListener("scroll", this.handleScroll);
52      this.handleScroll();
53      // handle scroll indicator
54      if (this.options.type === "progress") {
55        this.initIndicator();
56        this.handlePercentageScroll = this.updateScrollPercent.bind(this);
57        document.addEventListener("scroll", this.handlePercentageScroll);
58      }
59    }
60
61    update() {
62      this.destroy();
63      this.init();
64    }
65
66    updateScrollPercent() {
67      const heightOfWindow = window.innerHeight;
68      const contentScrolled = window.pageYOffset;
69      const bodyHeight = document.body.offsetHeight;
70      let percentageVal = 0;
71
72      if (bodyHeight - contentScrolled <= heightOfWindow) {
73        percentageVal = 100;
74      } else {
75        const total = bodyHeight - heightOfWindow;
76        const got = contentScrolled;
77        percentageVal = parseInt((got / total) * 100);
78      }
79      const pathLength = this.progressPath.getTotalLength();
80      const progress = pathLength - (percentageVal / 100) * pathLength;
81      this.progressPath.style.strokeDashoffset = progress;
82    }
83
84    calculateOffset() {
85      const offset = this.options.advanced.scroll_offset;
86      const customSelector = this.options.advanced.scroll_to_selector;
87
88      if (customSelector !== null && isSelectorValid(customSelector)) {
89        const element = document.querySelector(customSelector);
90        if (!element) return offset;
91        const bodyRect = document.body.getBoundingClientRect().top;
92        const elementRect = element.getBoundingClientRect().top;
93        const elementPosition = elementRect - bodyRect;
94        return elementPosition - offset;
95      } else {
96        return offset;
97      }
98    }
99
100    initIndicator() {
101      this.progressPath = this.element.querySelector(
102        ".js-progress-svg path.tracker"
103      );
104
105      const pathLength = this.progressPath.getTotalLength();
106      this.progressPath.style.transition =
107        this.progressPath.style.WebkitTransition = "none";
108      this.progressPath.style.strokeDasharray = pathLength + " " + pathLength;
109      this.progressPath.style.strokeDashoffset = pathLength;
110      this.progressPath.getBoundingClientRect();
111      this.progressPath.style.transition =
112        this.progressPath.style.WebkitTransition =
113          "stroke-dashoffset 10ms linear";
114    }
115
116    clickHandler() {
117      const offsetPosition = this.calculateOffset();
118
119      this.rootElement.scrollTo({
120        top: offsetPosition,
121        behavior: "smooth",
122      });
123    }
124
125    scrollHandler() {
126      const offsetBottom = this.options.show === "half" ? 0.5 : 0.8;
127      const scrollTotal =
128        this.rootElement.scrollHeight - this.rootElement.clientHeight;
129      if (this.rootElement.scrollTop / scrollTotal > offsetBottom) {
130        this.button.classList.add("is-visible");
131      } else if (this.rootElement.scrollTop === 0) {
132        this.button.classList.add("is-top");
133      } else {
134        this.button.classList.remove("is-visible");
135        this.button.classList.remove("is-top");
136      }
137    }
138  }
139  window.BreakdanceBackToTop = BreakdanceBackToTop;
140})();

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.