PageSourceSearch

https://www.now-planning.co.jp/design/themes/pc/js/slider.js

js now-planning.co.jp collected 2026-10-05 09:53:50 UTC 15,911 bytes, 451 lines download raw bytes

1/**
2 * slider
3 *
4 * multirole slider plug-in
5 *
6 * @category	jQuery plugin
7 * @license		http://www.opensource.org/licenses/mit-license.html	 MIT License
8 * @copyright	2010 RaNa design associates, inc.
9 * @author		keisuke YAMAMOTO <[email protected]>
10 * @link		http://www.ranadesign.com/
11 * @version		4.0
12 * @since		Aug 30, 2010
13 * @update		Feb 13, 2014
14 */
15
16;(function($) {
17
18	// for mobile =============================
19	var mobile = "createTouch" in document;
20
21	// slider ====================================
22	$.fn.slider = function(param) {
23		// 初期設定 ------------------------- //
24
25		// 初期値
26		var def = {
27			loop: true,			// ループさせるかどうか
28			time: 10,			// 1px動かすのにかける時間
29			speed: 1,			// 早送りや遅送りの比率指定
30			direction: "left",	// 送り方向
31			reverse: true,		// コントロール方向を逆向きにするかどうか
32			auto: true,			// trueで「自動実行」falseで「手動(コントロール)実行」
33			easing: "linear",	// イージングの初期値
34			guideSelector: ".slideGuide",	// ガイド用クラス名
35			cellSelector: ".slideCell", // セル用クラス名
36			ctrlSelector: ".slideCtrl", // コントローラー用クラス名
37			ctrlClick: false,	// コントローラ操作用イベントハンドラ(click)
38			ctrlHover: true,	// コントローラ操作用イベントハンドラ(hover)
39			draggable: false,	// スライドをドラッグで操作するかどうか
40			dragCursorOpen: "open.cur", // ドラッグ可能時のカーソルアイコン
41			dragCursorClose: "close.cur", // ドラッグ中のカーソルアイコン
42			shuttle: false,		// 往復スライドにするかどうか
43			once: false,		// 動きを1コマずつ止めるかどうか
44			restart: true,		// リスタートするかどうか(clickイベント用)
45			restartTime: 3000,	// リスタートまでの待ち時間
46			pause: true,		// マウスオーバー時に一時停止するかどうか
47			build: true,		// 暗黙のオプション(幅の初期設定)falseで幅設定をしない
48			sp: 1				// 基本速度
49		};
50
51		return this.each(function() {
52
53			// プライベート用のプロパティの上書き禁止
54			if (param) {
55				delete param.guide;
56				delete param.sp;
57			}
58			
59			// パラメータ受け渡し
60			$.extend(def, param);
61			def.guide = $(this).find(def.guideSelector);
62
63			// draggableかshuttleがtrueの時は関係するオプションをオフにする
64			if (def.draggable || def.shuttle) def.loop = def.auto = def.pause = false;
65
66			// 内部処理用プロパティ設定
67			def.d = def.direction; // 方向の初期設定を記憶
68			def.cell = def.cellSelector;
69			def.ctrl = def.ctrlSelector;
70			def.curOpen = "url(" + def.dragCursorOpen + "), default";
71			def.curClose = "url(" + def.dragCursorClose + "), default";
72			def.mousedownX = 0;
73			
74			// パラメータやセレクターが不正または無効な場合は次へ
75			if (!def.guide || def.loop && !def.guide.children(def.cell).length || !def.loop && def.guide.hasClass(def.guideSelector)) return true;
76			
77			// frame枠の取得
78			def.frameBorder = def.guide.offset().left - def.guide.parent().offset().left;
79			// cellマージンの取得
80			def.horizontalMargin = def.guide.find(def.cell).eq(0).outerWidth(true) - def.guide.find(def.cell).eq(0).outerWidth();
81			def.verticalMargin = def.guide.find(def.cell).eq(0).outerHeight(true) - def.guide.find(def.cell).eq(0).outerHeight();
82
83			// for mobile
84			def.handlerMousedown = mobile ? "touchstart" : "mousedown";
85			def.handlerMousemove = mobile ? "touchmove" : "mousemove";
86			def.handlerMouseup = mobile ? "touchend" : "mouseup";
87
88			// init 定義 =============================
89			// スライド枠の幅設定
90			var init = function(def) {
91				var cell = def.guide.find(def.cell);
92				// slideCellの数調整。足りない時にコピーして増やす。
93				var max = 0;
94				var size = 0;
95				switch (def.direction) {
96					case "up":
97					case "down":
98						// セルの合計幅と最大幅を取得する。
99						cell.each(function() {
100							max = max > $(this).outerHeight() ? max : $(this).outerHeight();
101							size += $(this).outerHeight(true);
102						});
103						// ループしない時はセルを増やさない。ガイド幅をセルの合計幅に合わせて終了。
104						if (!def.loop) {
105							def.guide.height(size);
106							return false;
107						}
108						// フレーム枠を超えるまでセルを増やす。
109						while (size < def.guide.parent().height() + max) {
110							cell.clone(true).appendTo(def.guide);
111							size += cell.outerHeight();
112						}
113						// slideGuideのサイズを合計幅+最大幅にする。
114						def.guide.height(size + max);
115						break;
116					case "left":
117					case "right":
118					default:
119						// セルの合計幅と最大幅を取得する。
120						cell.each(function() {
121							max = max > $(this).outerWidth() ? max : $(this).outerWidth();
122							size += $(this).outerWidth(true);
123						});
124						// ループしない時はセルを増やさない。ガイド幅をセルの合計幅に合わせて終了。
125						if (!def.loop) {
126							def.guide.width(size);
127							return false;
128						}
129						// フレーム枠を超えるまでセルを増やす。
130						while (size < def.guide.parent().width() + max) {
131							cell.clone(true).appendTo(def.guide);
132							size += cell.outerWidth();
133						}
134						// slideGuideのサイズを合計幅+最大幅にする。
135						def.guide.width(size + max);
136				}
137			}
138			var initTimerId = 0;
139
140			// slider 定義 ==========================
141			// ループする場合は「先頭セルを左に移動させたあと、最終セルの後ろに移動させる」を繰り返す。
142			var slider = function(par) {
143				var cell = par.guide.find(par.cell);
144				
145				if (par.loop) {
146					cell.first = cell.eq(0);
147					cell.last = cell.eq(cell.length - 1);
148
149					switch (par.direction.toLowerCase()) {
150						case "up":
151							if (cell.first.height() === 0) {
152								setTimeout(function() {
153									slider(par);
154								}, 200);
155								return false;
156							}
157							cell.first.animate({
158								marginTop: -1 * cell.first.innerHeight() - def.verticalMargin
159							}, {
160								// 途中で止まっていた場合は残りを調整してanimateし、次以降は再ループさせる。
161								duration: ~~Math.abs(par.time / par.sp * cell.first.height() * 
162									(cell.first.offset().top - par.guide.parent().offset().top < 0 ? 
163										(cell.first.height() + cell.first.offset().top - par.guide.parent().offset().top) / cell.first.height() : 1
164									)
165								),
166								easing: par.easing,
167								complete: function() {
168									if (par.loop) {
169										cell.first.appendTo(par.guide).css("marginTop", 0);
170										if (!par.once) slider(par);
171									}
172								}
173							});
174							break;
175						case "down":
176							if (cell.first.height() === 0) {
177								setTimeout(function() {
178									slider(par);
179								}, 200);
180								return false;
181							}
182							if (cell.first.offset().top - par.guide.parent().offset().top < 0) {
183								cell.first.animate({
184									marginTop: 0
185								},{
186									duration: ~~Math.abs(par.time / par.sp * cell.first.height() * 
187										(cell.first.offset().top - par.guide.parent().offset().top < 0 ? 
188											(par.guide.parent().offset().top - cell.first.offset().top) / cell.first.height() : 1
189										)
190									),
191									easing: par.easing,
192									complete: function() { if (!par.once) slider(par); }
193								});
194							} else {
195								cell.last.prependTo(par.guide).css("marginTop", -1 * cell.last.innerHe
195ight() - def.verticalMargin);
196								slider(par);
197							}
198							break;
199						case "left":
200							cell.first.animate({
201								marginLeft: -1 * cell.first.innerWidth() - par.horizontalMargin
202							}, {
203								// 途中で止まっていた場合は残りを調整してanimateし、次以降は再ループさせる。
204								duration: ~~Math.abs(par.time / par.sp * cell.first.width() * 
205									(cell.first.offset().left - par.guide.offset().left < 0 ? 
206										(cell.first.width() + cell.first.offset().left - par.guide.offset().left) / cell.first.width() : 1
207									)
208								),
209								easing: par.easing,
210								complete: function() {
211									if (par.loop) {
212										cell.first.appendTo(par.guide).css("marginLeft", 0);
213										if (!par.once) slider(par);
214									}
215								}
216							});
217							break;
218						case "right":
219							if (cell.first.offset().left - par.guide.offset().left < 0) {
220								cell.first.animate({
221									marginLeft: 0
222								},{
223									duration: ~~Math.abs(par.time / par.sp * cell.first.width() * 
224										(cell.first.offset().left - par.guide.offset().left < 0 ? 
225											(par.guide.offset().left - cell.first.offset().left) / cell.first.width() : 1
226										)
227									),
228									easing: par.easing,
229									complete: function() { if (!par.once) slider(par); }
230								});
231							} else {
232								cell.last.prependTo(par.guide).css("marginLeft", -1 * cell.last.innerWidth() - par.horizontalMargin);
233								slider(par);
234							}
235							break;
236						default:
237							return false;
238					}
239				
240				} else { // ループしない時
241					// コントローラの表示
242					var ctrl = par.guide.siblings(par.ctrl);
243					ctrl.show();
244					// 方向の取得
245					var d = 0;
246					switch (par.direction.toLowerCase()) {
247						case "up":
248						case "down":
249							d = par.direction.toLowerCase() === "up" ?  -1 : 1;
250							// スライド設定
251							par.guide.animate({
252								marginTop: par.guide.height() * d
253							}, {
254								duration: par.time * par.guide.height() / par.sp,
255								easing: par.easing
256							});
257							// 停止設定
258							var gl = par.guide.offset().top;
259							var fl = par.guide.parent().offset().top;
260							var timerId = setInterval(function() {
261								if (d > 0 && par.guide.offset().top > par.guide.parent().offset().top + par.frameBorder) {
262									clearInterval(timerId);
263									par.guide.stop(true);
264									ctrl.filter(".up").hide();
265								}
266								if (d < 0 && par.guide.parent().height() + par.guide.parent().offset().top + par.frameBorder + par.verticalMargin > par.guide.height() + par.guide.offset().top) {
267									clearInterval(timerId);
268									par.guide.stop(true);
269									ctrl.filter(".down").hide();
270								}
271							}, 20);
272							break;
273						case "left":
274						case "right":
275						default:
276							d = par.direction.toLowerCase() === "left" ?  -1 : 1;
277							// スライド設定
278							par.guide.animate({
279								marginLeft: par.guide.width() * d
280							}, {
281								duration: par.time * par.guide.width() / par.sp,
282								easing: par.easing
283							});
284							// 停止設定
285							var gl = par.guide.offset().left;
286							var fl = par.guide.parent().offset().left;
287							var timerId = setInterval(function() {
288								if (d > 0 && par.guide.offset().left > par.guide.parent().offset().left + par.frameBorder) {
289									clearInterval(timerId);
290									par.guide.stop(true);
291									ctrl.filter(".left").hide();
292								}
293								if (d < 0 && par.guide.parent().width() + par.guide.parent().offset().left + par.frameBorder + par.horizontalMargin > par.guide.width() + par.guide.offset().left) {
294									clearInterval(timerId);
295									par.guide.stop(true);
296									ctrl.filter(".right").hide();
297								}
298							}, 20);
299							break;
300					}
301				}
302			}
303
304			// 実行設定 ------------------------------- //
305
306			// 幅の初期設定
307			if (def.build) {
308				$(window).resize(function() {
309					clearTimeout(initTimerId);
310					initTimerId = setTimeout(function() {
311						init(def);
312					}, 100);
313				}).triggerHandler("resize");
314			}
315
316			// 自動起動
317			if (def.auto) slider(def);
318
319			// オプション設定 ------------------------- //
320
321			// マウスオーバーで一時停止する
322			if (def.pause) {
323				def.guide.hover(
324					function() { $(this).find(def.cell).stop(true); },
325					function() { slider(def); }
326				);
327			}
328			
329			// コントローラ設定 ------------------------- //
330
331			// ホバーイベント
332			if (def.ctrlHover) {
333				// for mobile
334				if (mobile) {
335					def.guide.siblings(def.ctrl)
336						.bind(def.handlerMousedown, function(event) {
337							event.preventDefault();
338							def.guide.find(def.cell).stop(true);
339							def.sp = def.speed;
340							switch (true) {
341								case $(this).hasClass("right"):
342									def.direction = "right";
343									break;
344								case $(this).hasClass("up"):
345									def.direction = "up";
346									break;
347								case $(this).hasClass("down"):
348									def.direction = "down";
349									break;
350								case $(this).hasClass("left"):
351								default:
352								   def.direction = "left";
353							}
354							slider(def);
355						}).bind(def.handlerMouseup, function() {
356							def.guide.find(def.cell).stop(true);
357							def.sp = 1;
358							def.direction = def.d;
359							if (def.auto) slider(def);
360						});
361				} else {
362					// 早送り・巻き戻し
363					def.guide.siblings(def.ctrl).hover(
364						function() {
365							def.guide.stop(true).find(def.cell).stop(true);
366							def.sp = def.speed;
367							def.direction = $(this).hasClass("right") ? def.reverse ? "left" : "right" : def.reverse ? "right" : "left";
368							switch (true) {
369								case $(this).hasClass("right"):
370									def.direction = def.reverse ? "left" : "right";
371									break;
372								case $(this).hasClass("up"):
373									def.direction = def.reverse ? "down" : "up";
374									break;
375								case $(this).hasClass("down"):
376									def.direction = def.reverse ? "up" : "down";
377									break;
378								case $(this).hasClass("left"):
379								default:
380									def.direction = def.reverse ? "right" : "left";
381							}
382							slider(def);
383						},
384						function() {
385							def.guide.stop(true).find(def.cell).stop(true);
386							def.sp = 1;
387							def.direction = def.d;
388							if (def.auto) slider(def);
389						}
390					);
391				}
392			}
393			
394			// クリックイベント
395			if (def.ctrlClick) {
396				def.guide.siblings(def.ctrl).bind(def.handlerMousedown, function(event) {
397					// アニメーションを省略
398					def.guide.find(def.cell).stop(true, true);
399					// 初期動作の中止
400					event.preventDefault();
401					// 方向設定
402						def.direction = $(this).hasClass("right") ? def.reverse ? "left" : "right" : def.reverse ? "right" : "left";
403					// 1クリックで1コマだけ動くようにする
404					def.once = true;
405					slider(def);
406					if (def.restart) {
407						setTimeout(function() {
408							def.once = false;
409							slider(def);
410						}, def.restartTime);
411					}
412				});
413			}
414
415			// ドラッグイベント
416			// dragmove設定
417			var dragmove = function(event) {
418				var frameEnd = def.guide.parent().width() + def.guide.parent().position().left;
419				var guideEnd = def.guide.width() + def.guide.position().left;
420				var stuff = 100;
421
422				def.guide.css("position", "absolute").css("left", (mobile ? event.originalEvent.touches[0].pageX : event.pageX) - def.mousedownX);
423
424				if (frameEnd - guideEnd > stuff || def.guide.offset().left - def.guide.parent().offset().left > stuff) {
425					$(document).unbind(def.handlerMousemove, dragmove).one(def.handlerMouseup, function() {
426						def.guide.animate({
427							left: frameEnd - guideEnd > stuff ? "+=" + (frameEnd - guideEnd) : 0
428						}, {
429							duration: 500,
430							easing: "easeOutQuart"
431						});
432					});
433				}
434			}
435			if (def.draggable) {
436				def.guide.bind(def.handlerMousedown, function(event) {
437					event.preventDefault();
438					def.mousedownX = (mobile ? event.originalEvent.touches[0].pageX : event.pageX) - def.guide.position().left;
439					$(this).stop(true).css("cursor", def.curClose);
440					$(document).bind(def.handlerMousemove, dragmove);
441				});
442				$(document).bind(def.handlerMouseup, function() {
443					def.guide.css("cursor", def.curOpen);
444					$(document).unbind(def.handlerMousemove, dragmove);
445				});
446			}
447			
448		});
449	}; // slider end
450
451}(jQuery));

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.