PageSourceSearch

https://www.exhub.co.kr/Js/HotDealSlider.js

js exhub.co.kr collected 2026-10-02 01:04:26 UTC 3,544 bytes, 123 lines download raw bytes

1class ProductRoller {
2	constructor(selector, options = {}) {
3		this.$wrap = $(selector);
4		this.options = {
5			animationSpeed: 500,
6			autoplaySpeed: 3000,
7			...options,
8		};
9		this.$container = this.$wrap.find('.SliderContainer');
10		this.$slide = this.$wrap.find('.SliderSlide');
11		this.$items = this.$wrap.find('.SlideItem');
12		this.isAnimating = false;
13		this.autoRoll = null;
14
15		if (!this.$wrap.length || !this.$container.length || !this.$slide.length || !this.$items.length) {
16			console.error('ProductRoller: 필요한 요소를 찾을 수 없습니다.');
17			return;
18		}
19
20		this.init();
21	}
22
23	init() {
24		this.$slide.append(this.$items.clone());
25		this.bindEvents();
26		this.startAutoRoll();
27	}
28
29	calculateSlideWidth() {
30		let totalWidth = 0;
31		this.$items.each(function () {
32			totalWidth += $(this).outerWidth(true);
33		});
34		return totalWidth / 2;
35	}
36
37    nextSlide() {
38        if (this.isAnimating) return;
39        this.isAnimating = true;
40
41        // $items 를 다시 계산합니다.
42        this.$items = this.$wrap.find('.SlideItem');
43        const $firstItem = this.$items.first();
44        const itemWidth = $firstItem.outerWidth(true);
45
46        this.$slide.animate({ marginLeft: -itemWidth }, this.options.animationSpeed, () => {
47            $firstItem.appendTo(this.$slide);
48            this.$slide.css('marginLeft', 0);
49            this.isAnimating = false;
50        });
51    }
52
53    prevSlide() {
54        if (this.isAnimating) return;
55        this.isAnimating = true;
56
57        // $items 를 다시 계산합니다.
58        this.$items = this.$wrap.find('.SlideItem');
59        const $lastItem = this.$items.last();
60        const itemWidth = $lastItem.outerWidth(true);
61
62        $lastItem.prependTo(this.$slide);
63        this.$slide.css('marginLeft', -itemWidth);
64
65        this.$slide.animate({ marginLeft: 0 }, this.options.animationSpeed, () => {
66            this.isAnimating = false;
67        });
68    }
69
70	startAutoRoll() {
71		this.stopAutoRoll();
72		this.autoRoll = setInterval(() => this.nextSlide(), this.options.autoplaySpeed);
73	}
74
75	stopAutoRoll() {
76		clearInterval(this.autoRoll);
77		this.autoRoll = null;
78	}
79
80	bindEvents() {
81		this.$wrap.find('.SlideNext').on('click', () => this.nextSlide());
82		this.$wrap.find('.SlidePrev').on('click', () => this.prevSlide());
83
84		this.$wrap.on('mouseenter', () => this.stopAutoRoll());
85		this.$wrap.on('mouseleave', () => this.startAutoRoll());
86
87		let touchStartX, startMarginLeft;
88
89		this.$container.on('touchstart', (e) => {
90			if (this.isAnimating) return;
91			touchStartX = e.originalEvent.touches[0].clientX;
92			startMarginLeft = parseInt(this.$slide.css('marginLeft')) || 0;
93			this.stopAutoRoll();
94		});
95
96		this.$container.on('touchmove', (e) => {
97			if (!touchStartX || this.isAnimating) return;
98			const touchMoveX = e.originalEvent.touches[0].clientX;
99			const diff = touchStartX - touchMoveX;
100
101			if (Math.abs(diff) > 5) {
102				e.preventDefault();
103				this.$slide.css('marginLeft', startMarginLeft - diff);
104			}
105		});
106
107		this.$container.on('touchend touchcancel', (e) => {
108			if (!touchStartX || this.isAnimating) return;
109			const touchEndX = e.originalEvent.changedTouches[0].clientX;
110			const diff = touchStartX - touchEndX;
111
112			if (Math.abs(diff) > 50) {
113				if (diff > 0) this.nextSlide();
114				else this.prevSlide();
115			} else {
116				this.$slide.animate({ marginLeft: startMarginLeft }, 200);
117			}
118
119			touchStartX = null;
120			this.startAutoRoll();
121		});
122	}
123}

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.