PageSourceSearch

https://myexitadvantage.com/wp-content/plugins/ht-mega-for-wpbakery/libs/magnifier/magnifier.js?ver=7.1.2

js myexitadvantage.com collected 2026-10-06 20:52:07 UTC 21,921 bytes, 662 lines download raw bytes

1/**
2* Magnifier.js is a Javascript library enabling magnifying glass effect on an images.
3*
4* Features
5*
6* Zoom in / out functionality using mouse wheel
7* Setting options via Javascript or data attributes
8* Magnified image can be displayed in the lens itself or outside of it in a wrapper
9* Attachment to multiple images with single call
10* Attachment of user defined functions for thumbnail entering, moving and leaving and image zooming events
11* Display loading text while the large image is being loaded, and switch to lens once its loaded
12*
13* Magnifier.js uses Event.js as a cross-browser event handling wrapper, which is available at
14* Github and JSClasses.org:
15*
16* Github - https://github.com/mark-rolich/Event.js
17* JS Classes - http://www.jsclasses.org/package/212-JavaScript-Handle-events-in-a-browser-independent-manner.html
18*
19* Works in Chrome, Firefox, Safari, IE 7, 8, 9 & 10.
20*
21* @author Mark Rolich <[email protected]>
22*/
23var Magnifier = function (evt, options) {
24    "use strict";
25
26    var gOptions = options || {},
27        curThumb = null,
28        curData = {
29            x: 0,
30            y: 0,
31            w: 0,
32            h: 0,
33            lensW: 0,
34            lensH: 0,
35            lensBgX: 0,
36            lensBgY: 0,
37            largeW: 0,
38            largeH: 0,
39            largeL: 0,
40            largeT: 0,
41            zoom: 2,
42            zoomMin: 1.1,
43            zoomMax: 5,
44            mode: 'outside',
45            largeWrapperId: (gOptions.largeWrapper !== undefined)
46                ? (gOptions.largeWrapper.id || null)
47                : null,
48            status: 0,
49            zoomAttached: false,
50            zoomable: (gOptions.zoomable !== undefined)
51                ? gOptions.zoomable
52                : false,
53            onthumbenter: (gOptions.onthumbenter !== undefined)
54                ? gOptions.onthumbenter
55                : null,
56            onthumbmove: (gOptions.onthumbmove !== undefined)
57                ? gOptions.onthumbmove
58                : null,
59            onthumbleave: (gOptions.onthumbleave !== undefined)
60                ? gOptions.onthumbleave
61                : null,
62            onzoom: (gOptions.onzoom !== undefined)
63                ? gOptions.onzoom
64                : null
65        },
66        pos = {
67            t: 0,
68            l: 0,
69            x: 0,
70            y: 0
71        },
72        gId = 0,
73        status = 0,
74        curIdx = '',
75        curLens = null,
76        curLarge = null,
77        gZoom = (gOptions.zoom !== undefined)
78                    ? gOptions.zoom
79                    : curData.zoom,
80        gZoomMin = (gOptions.zoomMin !== undefined)
81                    ? gOptions.zoomMin
82                    : curData.zoomMin,
83        gZoomMax = (gOptions.zoomMax !== undefined)
84                    ? gOptions.zoomMax
85                    : curData.zoomMax,
86        gMode = gOptions.mode || curData.mode,
87        data = {},
88        inBounds = false,
89        isOverThumb = 0,
90        getElementsByClass = function (className) {
91            var list = [],
92                elements = null,
93                len = 0,
94                pattern = '',
95                i = 0,
96                j = 0;
97
98            if (document.getElementsByClassName) {
99                list = document.getElementsByClassName(className);
100            } else {
101                elements = document.getElementsByTagName('*');
102                len = elements.length;
103                pattern = new RegExp("(^|\\s)" + className + "(\\s|$)");
104
105                for (i, j; i < len; i += 1) {
106                    if (pattern.test(elements[i].className)) {
107                        list[j] = elements[i];
108                        j += 1;
109                    }
110                }
111            }
112
113            return list;
114        },
115        $ = function (selector) {
116            var idx = '',
117                type = selector.charAt(0),
118                result = null;
119
120            if (type === '#' || type === '.') {
121                idx = selector.substr(1, selector.length);
122            }
123
124            if (idx !== '') {
125                switch (type) {
126                case '#':
127                    result = document.getElementById(idx);
128                    break;
129                case '.':
130                    result = getElementsByClass(idx);
131                    break;
132                }
133            }
134
135            return result;
136        },
137        createLens = function (thumb, idx) {
138            var lens = document.createElement('div');
139
140            lens.id = idx + '-lens';
141            lens.className = 'magnifier-loader';
142
143            thumb.parentNode.appendChild(lens);
144        },
145        updateLensOnZoom = function () {
146            curLens.style.left = pos.l + 'px';
147            curLens.style.top = pos.t + 'px';
148            curLens.style.width = curData.lensW + 'px';
149            curLens.style.height = curData.lensH + 'px';
150            curLens.style.backgroundPosition = '-' + curData.lensBgX + 'px -' +
151                                                curData.lensBgY + 'px';
152
153            curLarge.style.left = '-' + curData.largeL + 'px';
154            curLarge.style.top = '-' + curData.largeT + 'px';
155            curLarge.style.width = curData.largeW + 'px';
156            curLarge.style.height = curData.largeH + 'px';
157        },
158        updateLensOnLoad = function (idx, thumb, large, largeWrapper) {
159            var lens = $('#' + idx + '-lens'),
160                textWrapper = null;
161
162            if (data[idx].status === 1) {
163                textWrapper = document.createElement('div');
164                textWrapper.className = 'magnifier-loader-text';
165                lens.className = 'magnifier-loader hidden';
166
167                textWrapper.appendChild(document.createTextNode('Loading...'));
168                lens.appendChild(textWrapper);
169            } else if (data[idx].status === 2) {
170                lens.className = 'magnifier-lens hidden';
171                lens.removeChild(lens.childNodes[0]);
172                lens.style.background = 'url(' + thumb.src + ') no-repeat 0 0 scroll';
173
174                large.id = idx + '-large';
175                large.style.width = data[idx].largeW + 'px';
176                large.style.height = data[idx].largeH + 'px';
177                large.className = 'magnifier-large hidden';
178
179                if (data[idx].mode === 'inside') {
180                    lens.appendChild(large);
181                } else {
182                    largeWrapper.appendChild(large);
183                }
184            }
185
186            lens.style.width = data[idx].lensW + 'px';
187            lens.style.height = data[idx].lensH + 'px';
188        },
189        getMousePos = function () {
190            var xPos = pos.x - curData.x,
191                yPos = pos.y - curData.y,
192                t    = 0,
193                l    = 0;
194
195            inBounds = (
196                xPos < 0 ||
197                yPos < 0 ||
198                xPos > curData.w ||
199                yPos > curData.h
200            )
201                ? false
202                : true;
203
204            l = xPos - (curData.lensW / 2);
205            t = yPos - (curData.lensH / 2);
206
207            if (curData.mode !== 'inside') {
208                if (xPos < curData.lensW / 2) {
209                    l = 0;
210                }
211
212                if (yPos < curData.lensH / 2) {
213                    t = 0;
214                }
215
216                if (xPos - curData.w + (curData.lensW / 2) > 0) {
217                    l = curData.w - (curData.lensW + 2);
218                }
219
220                if (yPos - curData.h + (curData.lensH / 2) > 0) {
221                    t = curData.h - (curData.lensH + 2);
222                }
223            }
224
225            pos.l = Math.round(l);
226            pos.t = Math.round(t);
227
228            curData.lensBgX = pos.l + 1;
229            curData.lensBgY = pos.t + 1;
230
231            if (curData.mode === 'inside') {
232                curData.largeL = Math.round(xPos * (curData.zoom - (curData.lensW / curData.w)));
233                curData.largeT = Math.round(yPos * (curData.zoom - (curData.lensH / curData.h)));
234            } else {
235                curData.largeL = Math.round(curData.lensBgX * curData.zoom * (curData.largeWrapperW / curData.w));
236                curData.largeT = Math.round(curData.lensBgY * curData.zoom * (curData.largeWrapperH / curData.h));
237            }
238        },
239        zoomInOut = function (e) {
240            var delta = (e.wheelDelta > 0 || e.detail < 0) ? 0.1 : -0.1,
241                handler = curData.onzoom,
242                multiplier = 1,
243                w = 0,
244                h = 0;
245
246            if (e.preventDefault) {
247                e.preventDefault();
248            }
249
250            e.returnValue = false;
251
252            curData.zoom = Math.round((curData.zoom + delta) * 10) / 10;
253
254            if (curData.zoom >= curData.zoomMax) {
255                curData.zoom = curData.zoomMax;
256            } else if (curData.zoom >= curData.zoomMin) {
257                curData.lensW = Math.round(curData.w / curData.zoom);
258                curData.lensH = Math.round(curData.h / curData.zoom);
259
260                if (curData.mode === 'inside') {
261                    w = curData.w;
262                    h = curData.h;
263                } else {
264                    w = curData.largeWrapperW;
265                    h = curData.largeWrapperH;
266                    multiplier = curData.largeWrapperW / curData.w;
267                }
268
269                curData.largeW = Math.round(curData.zoom * w);
270                curData.largeH = Math.round(curData.zoom * h);
271
272                getMousePos();
273                updateLensOnZoom();
274
275                if (handler !== null) {
276                    handler({
277                        thumb: curThumb,
278                        lens: curLens,
279                        large: curLarge,
280                        x: pos.x,
281                        y: pos.y,
282                        zoom: Math.round(curData.zoom * multiplier * 10) / 10,
283                        w: curData.lensW,
284                        h: curData.lensH
285                    });
286                }
287            } else {
288                curData.zoom = curData.zoomMin;
289            }
290        },
291        onThumbEnter = function () {
292            curData = data[curIdx];
293            curLens = $('#' + curIdx + '-lens');
294
295            if (curData.status === 2) {
296                curLens.className = 'magnifier-lens';
297
298                if (curData.zoomAttached === false) {
299                    if (curData.zoomable !== undefined && curData.zoomable === true) {
300                        evt.attach('mousewheel', curLens, zoomInOut);
301
302                        if (window.addEventListener) {
303                            curLens.addEventListener('DOMMouseScroll', function (e) {
304                                zoomInOut(e);
305                            });
306                        }
307                    }
308
309                    curData.zoomAttached = true;
310                }
311
312                curLarge = $('#' + curIdx + '-large');
313                curLarge.className = 'magnifier-large';
314            } else if (curData.status === 1) {
315                curLens.className = 'magnifier-loader';
316            }
317        },
318        onThumbLeave = function () {
319            if (curData.status > 0) {
320                var handler = curData.onthumbleave;
321
322                if (handler !== null) {
323                    handler({
324                        thumb: curThumb,
325                        lens: curLens,
326                        large: curLarge,
327                        x: pos.x,
328                        y: pos.y
329                    });
330                }
331
332                if (curLens.className.indexOf('hidden') === -1) {
333                    curLens.className += ' hidden';
334                    curThumb.className = curData.thumbCssClass;
335
336                    if (curLarge !== null) {
337                        curLarge.className += ' hidden';
338                    }
339                }
340            }
341        },
342        move = function () {
343            if (status !== curData.status) {
344                onThumbEnter();
345            }
346
347            if (curData.status > 0) {
348                curThumb.className = curData.thumbCssClass + ' opaque';
349
350                if (curData.status === 1) {
351                    curLens.className = 'magnifier-loader';
352                } else if (curData.status === 2) {
353                    curLens.className = 'magnifier-lens';
354                    curLarge.className = 'magnifier-large';
355                    curLarge.style.left = '-' + curData.largeL + 'px';
356                    curLarge.style.top = '-' + curData.largeT + 'px';
357                }
358
359                curLens.style.left = pos.l + 'px';
360                curLens.style.top = pos.t + 'px';
361                curLens.style.backgroundPosition = '-' +
362                                                curData.lensBgX + 'px -' +
363                                                curData.lensBgY + 'px';
364
365                var handler = curData.onthumbmove;
366
367                if (handler !== null) {
368                    handler({
369                        thumb: curThumb,
370                        lens: curLens,
371                        large: curLarge,
372                        x: pos.x,
373                        y: pos.y
374                    });
375                }
376            }
377
378            status = curData.status;
379        },
380        setThumbData = function (thumb, thumbData) {
381            var thumbBounds = thumb.getBoundingClientRect(),
382                w = 0,
383                h = 0;
384
385            thumbData.x = thumbBounds.left;
386            thumbData.y = thumbBounds.top;
387            thumbData.w = Math.round(thumbBounds.right - thumbData.x);
388            thumbData.h = Math.round(thumbBounds.bottom - thumbData.y);
389
390            thumbData.lensW = Math.round(thumbData.w / thumbData.zoom);
391            thumbData.lensH = Math.round(thumbData.h / thumbData.zoom);
392
393            if (thumbData.mode === 'inside') {
394                w = thumbData.w;
395                h = thumbData.h;
396            } else {
397                w = thumbData.largeWrapperW;
398                h = thumbData.largeWrapperH;
399            }
400
401            thumbData.largeW = Math.round(thumbData.zoom * w);
402            thumbData.largeH = Math.round(thumbData.zoom * h);
403        };
404
405    this.attach = function (options) {
406        if (options.thumb === undefined) {
407            throw {
408                name: 'Magnifier error',
409                message: 'Please set thumbnail',
410                toString: function () {return this.name + ": " + this.message; }
411            };
412        }
413
414        var thumb = $(options.thumb),
415            i = 0;
416
417        if (thumb.length !== undefined) {
418            for (i; i < thumb.length; i += 1) {
419                options.thumb = thumb[i];
420                this.set(options);
421            }
422        } else {
423            options.thumb = thumb;
424            this.set(options);
425        }
426    };
427
428    this.setThumb = function (thumb) {
429        curThumb = thumb;
430    };
431
432    this.set = function (options) {
433        if (data[options.thumb.id] !== undefined) {
434            curThumb = options.thumb;
435            return false;
436        }
437
438        var thumbObj    = new Image(),
439            largeObj    = new Image(),
440            thumb       = options.thumb,
441            idx         = thumb.id,
442            zoomable    = null,
443            largeUrl    = null,
444            largeWrapper = (
445                $('#' + options.largeWrapper) ||
446                $('#' + thumb.getAttribute('data-large-img-wrapper')) ||
447                $('#' + curData.largeWrapperId)
448            ),
449            zoom = options.zoom || thumb.getAttribute('data-zoom') || gZoom,
450            zoomMin = options.zoomMin || thumb.getAttribute('data-zoom-min') || gZoomMin,
451            zoomMax = options.zoomMax || thumb.getAttribute('data-zoom-max') || gZoomMax,
452            mode = options.mode || thumb.getAttribute('data-mode') || gMode,
453            onthumbenter = (options.onthumbenter !== undefined)
454                        ? options.onthumbenter
455                        : curData.onthumbenter,
456            onthumbleave = (options.onthumbleave !== undefined)
457                        ? options.onthumbleave
458                        : curData.onthumbleave,
459            onthumbmove = (options.onthumbmove !== undefined)
460                        ? options.onthumbmove
461                        : curData.onthumbmove,
462            onzoom = (options.onzoom !== undefined)
463                        ? options.onzoom
464                        : curData.onzoom;
465
466        if (options.large === undefined) {
467            largeUrl = (options.thumb.getAttribute('data-large-img-url') !== null)
468                            ? options.thumb.getAttribute('data-large-img-url')
469                            : options.thumb.src;
470        } else {
471            largeUrl = options.large;
472        }
473
474        if (largeWrapper === null && mode !== 'inside') {
475            throw {
476                name: 'Magnifier error',
477                message: 'Please specify large image wrapper DOM element',
478                toString: function () {return this.name + ": " + this.message; }
479            };
480        }
481
482        if (options.zoomable !== undefined) {
483            zoomable = options.zoomable;
484        } else if (thumb.getAttribute('data-zoomable') !== null) {
485            zoomable = (thumb.getAttribute('data-zoomable') === 'true');
486        } else if (curData.zoomable !== undefined) {
487            zoomable = curData.zoomable;
488        }
489
490        if (thumb.id === '') {
491            idx = thumb.id = 'magnifier-item-' + gId;
492            gId += 1;
493        }
494
495        createLens(thumb, idx);
496
497        data[idx] = {
498            zoom: zoom,
499            zoomMin: zoomMin,
500            zoomMax: zoomMax,
501            mode: mode,
502            zoomable: zoomable,
503            thumbCssClass: thumb.className,
504            zoomAttached: false,
505            status: 0,
506            largeUrl: largeUrl,
507            largeWrapperId: mode === 'outside' ? largeWrapper.id : null,
508            largeWrapperW: mode === 'outside' ? largeWrapper.offsetWidth : null,
509            largeWrapperH: mode === 'outside' ? largeWrapper.offsetHeight : null,
510            onzoom: onzoom,
511            onthumbenter: onthumbenter,
512            onthumbleave: onthumbleave,
513            onthumbmove: onthumbmove
514        };
515
516        evt.attach('mouseover', thumb, function (e, src) {
517            if (curData.status !== 0) {
518                onThumbLeave();
519            }
520
521            curIdx = src.id;
522            curThumb = src;
523
524            onThumbEnter(src);
525
526            setThumbData(curThumb, curData);
527
528            pos.x = e.clientX;
529            pos.y = e.clientY;
530
531            getMousePos();
532            move();
533
534            var handler = curData.onthumbenter;
535
536            if (handler !== null) {
537                handler({
538                    thumb: curThumb,
539                    lens: curLens,
540                    large: curLarge,
541                    x: pos.x,
542                    y: pos.y
543                });
544            }
545        }, false);
546
547        evt.attach('mousemove', thumb, function (e, src) {
548            isOverThumb = 1;
549        });
550
551        evt.attach('load', thumbObj, function () {
552            data[idx].status = 1;
553
554            setThumbData(thumb, data[idx]);
555            updateLensOnLoad(idx);
556
557            evt.attach('load', largeObj, function () {
558                data[idx].status = 2;
559                updateLensOnLoad(idx, thumb, largeObj, largeWrapper);
560            });
561
562            largeObj.src = data[idx].largeUrl;
563        });
564
565        thumbObj.src = thumb.src;
566    };
567
568    evt.attach('mousemove', document, function (e) {
569        pos.x = e.clientX;
570        pos.y = e.clientY;
571
572        getMousePos();
573
574        if (inBounds === true) {
575            move();
576        } else {
577            if (isOverThumb !== 0) {
578                onThumbLeave();
579            }
580
581            isOverThumb = 0;
582        }
583    }, false);
584
585    evt.attach('scroll', window, function () {
586        if (curThumb !== null) {
587            setThumbData(curThumb, curData);
588        }
589    });
590};
591
592
593/**
594* Unifies event handling across browsers
595*
596* - Allows registering and unregistering of event handlers
597* - Injects event object and involved DOM element to listener
598*
599* @author Mark Rolich <[email protected]>
600*/
601var Event = function () {
602    "use strict";
603    this.attach = function (evtName, element, listener, capture) {
604        var evt         = '',
605            useCapture  = (capture === undefined) ? true : capture,
606            handler     = null;
607
608        if (window.addEventListener === undefined) {
609            evt = 'on' + evtName;
610            handler = function (evt, listener) {
611                element.attachEvent(evt, listener);
612                return listener;
613            };
614        } else {
615            evt = evtName;
616            handler = function (evt, listener, useCapture) {
617                element.addEventListener(evt, listener, useCapture);
618                return listener;
619            };
620        }
621
622        return handler.apply(element, [evt, function (ev) {
623            var e   = ev || event,
624                src = e.srcElement || e.target;
625
626            listener(e, src);
627        }, useCapture]);
628    };
629
630    this.detach = function (evtName, element, listener, capture) {
631        var evt         = '',
632            useCapture  = (capture === undefined) ? true : capture;
633
634        if (window.removeEventListener === undefined) {
635            evt = 'on' + evtName;
636            element.detachEvent(evt, listener);
637        } else {
638            evt = evtName;
639            element.removeEventListener(evt, listener, useCapture);
640        }
641    };
642
643    this.stop = function (evt) {
644        evt.cancelBubble = true;
645
646        if (evt.stopPropagation) {
647            evt.stopPropagation();
648        }
649    };
650
651    this.prevent = function (evt) {
652        if (evt.preventDefault) {
653            evt.preventDefault();
654        } else {
655            evt.returnValue = false;
656        }
657    };
658};
659
660// Create object
661var evt = new Event(),
662m = new Magnifier(evt);

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.