summaryrefslogtreecommitdiff
path: root/src/client/directives/size.ts
blob: a72a97abcc12c054293cb489218dcf0e38a8593b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import { Directive } from 'vue';

//const observers = new Map<Element, ResizeObserver>();

export default {
	mounted(src, binding, vn) {
		const query = binding.value;

		const addClass = (el: Element, cls: string) => {
			el.classList.add(cls);
		};

		const removeClass = (el: Element, cls: string) => {
			el.classList.remove(cls);
		};

		const calc = () => {
			const width = src.clientWidth;

			// 要素が(一時的に)DOMに存在しないときは計算スキップ
			if (width === 0) return;

			if (query.max) {
				for (const v of query.max) {
					if (width <= v) {
						addClass(src, 'max-width_' + v + 'px');
					} else {
						removeClass(src, 'max-width_' + v + 'px');
					}
				}
			}
			if (query.min) {
				for (const v of query.min) {
					if (width >= v) {
						addClass(src, 'min-width_' + v + 'px');
					} else {
						removeClass(src, 'min-width_' + v + 'px');
					}
				}
			}
		};

		calc();

		window.addEventListener('resize', calc);

		// Vue3では使えなくなった
		// 無くても大丈夫か...?
		// TODO: ↑大丈夫じゃなかったので解決策を探す
		//vn.context.$on('hook:activated', calc);

		//const ro = new ResizeObserver((entries, observer) => {
		//	calc();
		//});

		//ro.observe(el);

		// TODO: 新たにプロパティを作るのをやめMapを使う
		// ただメモリ的には↓の方が省メモリかもしれないので検討中
		//el._ro_ = ro;
		src._calc_ = calc;
	},

	unmounted(src, binding, vn) {
		//el._ro_.unobserve(el);
		window.removeEventListener('resize', src._calc_);
	}
} as Directive;