create-fesd-app 1.0.15 → 1.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/assets/css/layouts/article4/_article4_setting.sass +10 -13
- package/src/assets/js/commons/cookies/cookieData.js +126 -124
- package/src/assets/js/commons/cookies/cookieElement.js +157 -0
- package/src/assets/js/commons/cookies/cookiePolicy.js +315 -276
- package/src/assets/js/commons/inits.js +1 -1
- package/src/layouts/components/_cookiePolicy.pug +3 -3
- package/src/pages/index.pug +1 -1
package/package.json
CHANGED
|
@@ -77,10 +77,6 @@ $typeFull-padding_rwd: 30px 20px
|
|
|
77
77
|
$typeFull-content-padding: 85px 75px 100px
|
|
78
78
|
$typeFull-content-padding_rwd: 20px
|
|
79
79
|
|
|
80
|
-
// swiper pagination
|
|
81
|
-
$pagination-TB-gap: 20px
|
|
82
|
-
$pagination-TB-gap_rwd: 10px
|
|
83
|
-
|
|
84
80
|
// 表格與其他物件上下間的距離
|
|
85
81
|
$table-TB-gap: 20px
|
|
86
82
|
$table-TB-gap_rwd: 20px
|
|
@@ -341,28 +337,31 @@ $quote-TB-gap: 20px
|
|
|
341
337
|
// @extend %table_border_rows
|
|
342
338
|
// @extend %table_border_full
|
|
343
339
|
@extend %table_solidSingle_borderColumn
|
|
340
|
+
|
|
341
|
+
&[data-table-markdown="on"]
|
|
342
|
+
table p
|
|
343
|
+
white-space: pre-wrap
|
|
344
|
+
|
|
344
345
|
table
|
|
345
346
|
th, td
|
|
346
347
|
text-align: left
|
|
347
348
|
background: #fff
|
|
349
|
+
span
|
|
350
|
+
display: block
|
|
351
|
+
ol,ul
|
|
352
|
+
&:not(:first-child)
|
|
353
|
+
margin-top: 10px
|
|
348
354
|
thead
|
|
349
355
|
th
|
|
350
356
|
// 以下可修改
|
|
351
357
|
font-size: 16px
|
|
352
358
|
line-height: 1.2
|
|
353
359
|
font-weight: 600
|
|
354
|
-
span
|
|
355
|
-
display: block
|
|
356
360
|
tbody
|
|
357
361
|
td
|
|
358
362
|
// 以下可修改
|
|
359
363
|
font-size: 16px
|
|
360
364
|
line-height: 1.2
|
|
361
|
-
span
|
|
362
|
-
display: block
|
|
363
|
-
ol,ul
|
|
364
|
-
&:not(:first-child)
|
|
365
|
-
margin-top: 10px
|
|
366
365
|
|
|
367
366
|
%table_tipText
|
|
368
367
|
// 以下可修改
|
|
@@ -581,8 +580,6 @@ $quote-TB-gap: 20px
|
|
|
581
580
|
line-height: 1.2
|
|
582
581
|
&:not(:first-child)
|
|
583
582
|
margin-top: 10px
|
|
584
|
-
p
|
|
585
|
-
white-space: pre-wrap
|
|
586
583
|
em
|
|
587
584
|
font-style: italic
|
|
588
585
|
a
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
1
|
+
// 此處為 demo 資料, 後端會用相同資料結構洗資料在 #_wcookie 上
|
|
2
|
+
// 給後端 :
|
|
3
|
+
// 基本上進階版細項開關不開, 有需求才開; 若開啟進階版細項, 大分類的 close 開關預設會無效, 會以判斷細項是否有開啟 or 全關為主
|
|
4
|
+
// close: 0 -> 開啟; close: 1 -> 關閉
|
|
3
5
|
export const cookieData = [
|
|
4
6
|
{
|
|
7
|
+
multiType: true, // 是否開啟個別選項設定
|
|
5
8
|
title: "您的 Cookie 偏好設定",
|
|
6
9
|
text: "我們使用不同類型的 Cookies 來優化您在我們的網站上的體驗,點擊下面類別以了解其目的與更多訊息。<br>您可以選擇允許的 Cookies 類型,也可以隨時更改您的偏好設定。<br>提醒您,停用 Cookies 可能會影響您在網站上的體驗,您可以瀏覽我們的隱私權政策,進一步了解我們如何使用 Cookie。",
|
|
7
10
|
options: [
|
|
8
11
|
{
|
|
9
12
|
key: "required",
|
|
10
|
-
|
|
13
|
+
close: 0,
|
|
11
14
|
disabled: true,
|
|
12
15
|
title: "必要",
|
|
13
16
|
text: "這些 Cookies 對於支持核心網站功能(例如提供安全登錄)至關重要。",
|
|
@@ -18,26 +21,26 @@ export const cookieData = [
|
|
|
18
21
|
text: "第一方 cookies 由用戶訪問的網站(即主機域名)設置。網站通常使用第一方 cookies 用於跟踪訪客在網站上的行為並個性化他們在網站上的瀏覽體驗以及個性化他們的瀏覽體驗。",
|
|
19
22
|
list: [
|
|
20
23
|
{
|
|
21
|
-
key: "",
|
|
22
|
-
|
|
24
|
+
key: "PHPSESSID",
|
|
25
|
+
close: 0,
|
|
23
26
|
title: "PHPSESSID",
|
|
24
27
|
text: "php用來辨識用戶的session id",
|
|
25
28
|
},
|
|
26
29
|
{
|
|
27
|
-
key: "",
|
|
28
|
-
|
|
30
|
+
key: "XSRF",
|
|
31
|
+
close: 0,
|
|
29
32
|
title: "XSRF-TOKEN",
|
|
30
33
|
text: "網站防止 CSRF(Cross-Site Request Forgery,跨站請求偽造)攻擊 的 token",
|
|
31
34
|
},
|
|
32
35
|
{
|
|
33
|
-
key: "",
|
|
34
|
-
|
|
36
|
+
key: "web_session",
|
|
37
|
+
close: 0,
|
|
35
38
|
title: "web_session",
|
|
36
39
|
text: "網站用來辨識用戶的session id",
|
|
37
40
|
},
|
|
38
41
|
{
|
|
39
|
-
key: "",
|
|
40
|
-
|
|
42
|
+
key: "hubspot",
|
|
43
|
+
close: 0,
|
|
41
44
|
title: "hubspot",
|
|
42
45
|
text: "hubspot 使用了Cloudflare服務,區分真人訪客與惡意機器人",
|
|
43
46
|
},
|
|
@@ -48,77 +51,57 @@ export const cookieData = [
|
|
|
48
51
|
},
|
|
49
52
|
{
|
|
50
53
|
key: "analytics",
|
|
51
|
-
|
|
54
|
+
close: 1,
|
|
52
55
|
disabled: false,
|
|
53
56
|
title: "分析與自訂",
|
|
54
57
|
text: "這些 Cookies 分析網站優化的使用情況。",
|
|
55
58
|
notice: "我們將無法分析您的網站使用情況,以提供自定義內容",
|
|
56
59
|
data: {
|
|
57
60
|
items: [
|
|
58
|
-
// {
|
|
59
|
-
// main: "第一方 Cookie 提供商",
|
|
60
|
-
// text: "第一方 cookies 由用戶訪問的網站(即主機域名)設置。網站通常使用第一方 cookies 用於跟踪訪客在網站上的行為並個性化他們在網站上的瀏覽體驗以及個性化他們的瀏覽體驗。",
|
|
61
|
-
// list: [
|
|
62
|
-
// {
|
|
63
|
-
// title: "gtm",
|
|
64
|
-
// key: "gtm",
|
|
65
|
-
// state: "",
|
|
66
|
-
// },
|
|
67
|
-
// {
|
|
68
|
-
// title: "ga",
|
|
69
|
-
// key: "ga",
|
|
70
|
-
// state: "",
|
|
71
|
-
// detail: [
|
|
72
|
-
// {
|
|
73
|
-
// title: "_ga",
|
|
74
|
-
// text: "用來區分不同使用者。每個使用者會被指派唯一的 ID",
|
|
75
|
-
// typeTitle: "時間 / 類型",
|
|
76
|
-
// typeDesc: "13 個月",
|
|
77
|
-
// },
|
|
78
|
-
// {
|
|
79
|
-
// title: "_ga_<container-id>",
|
|
80
|
-
// text: "追蹤單一屬性 (Property) 的資料。",
|
|
81
|
-
// typeTitle: "時間 / 類型",
|
|
82
|
-
// typeDesc: "13 個月",
|
|
83
|
-
// },
|
|
84
|
-
// ],
|
|
85
|
-
// },
|
|
86
|
-
// ],
|
|
87
|
-
// },
|
|
88
61
|
{
|
|
89
|
-
main: "
|
|
90
|
-
text: "
|
|
62
|
+
main: "第一方 Cookie 提供商",
|
|
63
|
+
text: "第一方 cookies 由用戶訪問的網站(即主機域名)設置。網站通常使用第一方 cookies 用於跟踪訪客在網站上的行為並個性化他們在網站上的瀏覽體驗以及個性化他們的瀏覽體驗。",
|
|
91
64
|
list: [
|
|
92
|
-
// {
|
|
93
|
-
// title: "googlefont",
|
|
94
|
-
// key: "",
|
|
95
|
-
// state: "",
|
|
96
|
-
// },
|
|
97
65
|
{
|
|
98
|
-
title: "
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
66
|
+
title: "gtm",
|
|
67
|
+
key: "gtm",
|
|
68
|
+
close: 1,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
title: "ga",
|
|
72
|
+
key: "ga",
|
|
73
|
+
close: 1,
|
|
102
74
|
detail: [
|
|
103
75
|
{
|
|
104
|
-
title: "
|
|
105
|
-
text: "
|
|
76
|
+
title: "_ga",
|
|
77
|
+
text: "用來區分不同使用者。每個使用者會被指派唯一的 ID",
|
|
106
78
|
typeTitle: "時間 / 類型",
|
|
107
|
-
typeDesc: "
|
|
79
|
+
typeDesc: "13 個月",
|
|
108
80
|
},
|
|
109
81
|
{
|
|
110
|
-
title: "
|
|
111
|
-
text: "
|
|
82
|
+
title: "_ga_<container-id>",
|
|
83
|
+
text: "追蹤單一屬性 (Property) 的資料。",
|
|
112
84
|
typeTitle: "時間 / 類型",
|
|
113
|
-
typeDesc: "
|
|
85
|
+
typeDesc: "13 個月",
|
|
114
86
|
},
|
|
115
87
|
],
|
|
116
88
|
},
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
main: "第三方 Cookie 提供商",
|
|
93
|
+
text: "第三方 cookies 是由其他第三方實體放置在網站上,而不是網站本身,即使用者在地址欄中看到的網域以外的域名。第三方 cookies 通常跟踪訪客在網站之間的行為,通常用於針對性廣告目的。",
|
|
94
|
+
list: [
|
|
95
|
+
{
|
|
96
|
+
title: "googlefont",
|
|
97
|
+
key: "googlefont",
|
|
98
|
+
close: 1,
|
|
99
|
+
},
|
|
117
100
|
{
|
|
118
101
|
title: "Youtube",
|
|
119
102
|
text: "https://www.youtube.com/",
|
|
120
|
-
key: "",
|
|
121
|
-
|
|
103
|
+
key: "Youtube",
|
|
104
|
+
close: 1,
|
|
122
105
|
detail: [
|
|
123
106
|
{
|
|
124
107
|
title: "YSC",
|
|
@@ -157,67 +140,86 @@ export const cookieData = [
|
|
|
157
140
|
},
|
|
158
141
|
],
|
|
159
142
|
},
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
143
|
+
{
|
|
144
|
+
title: "Vimeo",
|
|
145
|
+
text: "https://vimeo.com/",
|
|
146
|
+
key: "Vimeo",
|
|
147
|
+
close: 1,
|
|
148
|
+
detail: [
|
|
149
|
+
{
|
|
150
|
+
title: "_cf_bm",
|
|
151
|
+
text: "Cloudflare bot manager manages incoming traffic that matches the criteria associated with bots.",
|
|
152
|
+
typeTitle: "時間 / 類型",
|
|
153
|
+
typeDesc: "30 分",
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
title: "_cfuvid",
|
|
157
|
+
text: "Cloudflare cookie used to enforce rate-limiting rules.",
|
|
158
|
+
typeTitle: "時間 / 類型",
|
|
159
|
+
typeDesc: "session",
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
title: "Tiktok",
|
|
165
|
+
text: "https://www.tiktok.com/zh-Hant-TW/",
|
|
166
|
+
key: "Tiktok",
|
|
167
|
+
close: 1,
|
|
168
|
+
detail: [
|
|
169
|
+
{
|
|
170
|
+
title: "_ttp",
|
|
171
|
+
text: "To measure and improve the performance of advertising campaigns and to personalize the customer experience (including ads) on TikTok.",
|
|
172
|
+
typeTitle: "時間 / 類型",
|
|
173
|
+
typeDesc: "13 個月",
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
title: "msToken",
|
|
177
|
+
text: "用於存儲用戶的會話令牌,確保用戶在瀏覽器會話期間保持登錄狀態。",
|
|
178
|
+
typeTitle: "時間 / 類型",
|
|
179
|
+
typeDesc: "10 天",
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
title: "passport_csrf_token",
|
|
183
|
+
text: "用於防止跨站請求偽造(CSRF)攻擊,確保請求的合法性。",
|
|
184
|
+
typeTitle: "時間 / 類型",
|
|
185
|
+
typeDesc: "60 天",
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
title: "ttwid",
|
|
189
|
+
text: "用於識別用戶的唯一 ID,協助 TikTok 進行用戶識別與防止機器人行為。",
|
|
190
|
+
typeTitle: "時間 / 類型",
|
|
191
|
+
typeDesc: "10 天",
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
title: "instagram",
|
|
197
|
+
text: "https://www.instagram.com/",
|
|
198
|
+
key: "instagram",
|
|
199
|
+
close: 1,
|
|
200
|
+
detail: [
|
|
201
|
+
{
|
|
202
|
+
title: "mid",
|
|
203
|
+
text: "用於區分不同的用戶,協助 Instagram 提供個性化的內容推薦、廣告展示以及其他社交媒體功能。",
|
|
204
|
+
typeTitle: "時間 / 類型",
|
|
205
|
+
typeDesc: "13 個月",
|
|
206
|
+
},
|
|
207
|
+
],
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
title: "meta",
|
|
211
|
+
text: "https://www.facebook.com/privacy/policy",
|
|
212
|
+
key: "meta",
|
|
213
|
+
close: 1,
|
|
214
|
+
detail: [
|
|
215
|
+
{
|
|
216
|
+
title: "_fbp",
|
|
217
|
+
text: "用於辨識網站訪客,讓 Meta 可以顯示相關廣告(再行銷用途)。",
|
|
218
|
+
typeTitle: "時間 / 類型",
|
|
219
|
+
typeDesc: "90 天",
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
},
|
|
221
223
|
],
|
|
222
224
|
},
|
|
223
225
|
]
|
|
@@ -225,14 +227,14 @@ export const cookieData = [
|
|
|
225
227
|
},
|
|
226
228
|
{
|
|
227
229
|
key: "functionality",
|
|
228
|
-
|
|
230
|
+
close: 1,
|
|
229
231
|
disabled: false,
|
|
230
232
|
title: "性能與功能",
|
|
231
233
|
text: "這些 Cookies 有助於測量和分析,以改善瀏覽體驗",
|
|
232
234
|
},
|
|
233
235
|
{
|
|
234
236
|
key: "advertising",
|
|
235
|
-
|
|
237
|
+
close: 1,
|
|
236
238
|
disabled: false,
|
|
237
239
|
title: "廣告",
|
|
238
240
|
text: "這些 Cookies 有助於提供與您相關的廣告內容",
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// js 產 cookie 結構方法
|
|
2
|
+
/**
|
|
3
|
+
* @param {Array} target
|
|
4
|
+
* @param {(opt: cookieData[0], index: number) => string} fn
|
|
5
|
+
*/
|
|
6
|
+
const generateHtmlString = (target, fn) => {
|
|
7
|
+
return target.map((data, index) => fn(data, index)).join("")
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const cookieStep1El = (opt, index, isDisabled, isChecked) => {
|
|
11
|
+
return `
|
|
12
|
+
<div class="item" data-index="${index}">
|
|
13
|
+
<div class="left">
|
|
14
|
+
<div class="checkbox ${isDisabled}">
|
|
15
|
+
<div class="input-wrap">
|
|
16
|
+
<input type="checkbox"
|
|
17
|
+
id="s1-check-${index}"
|
|
18
|
+
${isChecked()}
|
|
19
|
+
data-name="${opt.key}"
|
|
20
|
+
>
|
|
21
|
+
<div class="fake-checkbox">
|
|
22
|
+
<i class="icon-check"></i>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
<label for="s1-check-${index}">
|
|
26
|
+
<span>${opt.title}</span>
|
|
27
|
+
</label>
|
|
28
|
+
</div>
|
|
29
|
+
<div class="desc">
|
|
30
|
+
<div class="text">${opt.text}</div>
|
|
31
|
+
${opt.notice ? `
|
|
32
|
+
<div class="notice">
|
|
33
|
+
<div class="icon">
|
|
34
|
+
<i class="icon-notice"></i>
|
|
35
|
+
</div>
|
|
36
|
+
<span>${opt.notice}</span>
|
|
37
|
+
</div>` : ""}
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
<div class="right">
|
|
41
|
+
<div class="switch-box ${isDisabled}">
|
|
42
|
+
<input type="checkbox" hidden
|
|
43
|
+
id="s1-switch-${index}"
|
|
44
|
+
${isChecked()}
|
|
45
|
+
data-name="${opt.key}"
|
|
46
|
+
>
|
|
47
|
+
<label class="switch" for="s1-switch-${index}"></label>
|
|
48
|
+
</div>
|
|
49
|
+
<div class="icon" data-open>
|
|
50
|
+
<i class="icon-arrow"></i>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
`
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const cookieStep2TittleEl = (opt, index, isDisabled, isChecked) => {
|
|
58
|
+
return `
|
|
59
|
+
<div class="box">
|
|
60
|
+
<div class="left">
|
|
61
|
+
<div class="checkbox ${isDisabled}">
|
|
62
|
+
<div class="input-wrap">
|
|
63
|
+
<input type="checkbox"
|
|
64
|
+
id="s2-check-${index}"
|
|
65
|
+
${isChecked()}
|
|
66
|
+
data-name="${opt.key}"
|
|
67
|
+
>
|
|
68
|
+
<div class="fake-checkbox">
|
|
69
|
+
<i class="icon-check"></i>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
<label for="s2-check-${index}">
|
|
73
|
+
<span>${opt.title}</span>
|
|
74
|
+
</label>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
<div class="right">
|
|
78
|
+
<div class="switch-box ${isDisabled}">
|
|
79
|
+
<input type="checkbox" hidden
|
|
80
|
+
id="s2-switch-${index}"
|
|
81
|
+
${isChecked()}
|
|
82
|
+
data-name="${opt.key}"
|
|
83
|
+
>
|
|
84
|
+
<label class="switch" for="s2-switch-${index}"></label>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
<div class="desc">
|
|
89
|
+
<div class="text">${opt.text || ""}</div>
|
|
90
|
+
${opt.notice ?
|
|
91
|
+
`<div class="notice">
|
|
92
|
+
<div class="icon">
|
|
93
|
+
<i class="icon-notice"></i>
|
|
94
|
+
</div>
|
|
95
|
+
<span>${opt.notice}</span>
|
|
96
|
+
</div> ` : ""}
|
|
97
|
+
</div>
|
|
98
|
+
`
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export const cookieStep2DetailEl = (data, li, index, parentKey, num, isDisabled, isListChecked) => {
|
|
102
|
+
return `
|
|
103
|
+
<div class="list collapseItem" data-collapse>
|
|
104
|
+
<div class="title collapseTitle" data-collapse-click>
|
|
105
|
+
<div class="icon">
|
|
106
|
+
<i class="icon-arrow"></i>
|
|
107
|
+
</div>
|
|
108
|
+
<span>${li.title || ""}</span>
|
|
109
|
+
${data.multiType ?
|
|
110
|
+
`<div class="switch-box ${isDisabled}">
|
|
111
|
+
<input
|
|
112
|
+
type="checkbox"
|
|
113
|
+
hidden
|
|
114
|
+
id="s2-content-${num}-${index}"
|
|
115
|
+
${isListChecked}
|
|
116
|
+
data-name="${li.key}"
|
|
117
|
+
data-parent="${parentKey || ""}"
|
|
118
|
+
>
|
|
119
|
+
<label
|
|
120
|
+
class="switch"
|
|
121
|
+
for="s2-content-${num}-${index}">
|
|
122
|
+
</label>
|
|
123
|
+
</div>`
|
|
124
|
+
: ""
|
|
125
|
+
}
|
|
126
|
+
</div>
|
|
127
|
+
${li.text ?
|
|
128
|
+
`<div class="text">${li.text}</div>`
|
|
129
|
+
: ""
|
|
130
|
+
}
|
|
131
|
+
<div class="list-detail collapseBox" data-collapse-content>
|
|
132
|
+
<div class="innerBox">
|
|
133
|
+
<div class="content">
|
|
134
|
+
${li.detail?.length > 0 ?
|
|
135
|
+
generateHtmlString(li.detail, (i) => {
|
|
136
|
+
return `
|
|
137
|
+
<div class="li">
|
|
138
|
+
<div class="title">${i.title || ""}</div>
|
|
139
|
+
${i.text ?
|
|
140
|
+
`<div class="text">${i.text}</div>`
|
|
141
|
+
: ""
|
|
142
|
+
}
|
|
143
|
+
<div class="flex">
|
|
144
|
+
<div class="text bold">${i.typeTitle || ""}</div>
|
|
145
|
+
<div class="text">${i.typeDesc || ""}</div>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
`
|
|
149
|
+
})
|
|
150
|
+
: ""
|
|
151
|
+
}
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
`
|
|
157
|
+
}
|
|
@@ -5,15 +5,24 @@ import {
|
|
|
5
5
|
scrollLock,
|
|
6
6
|
scrollUnlock
|
|
7
7
|
} from '@xwadex/fesd/tools';
|
|
8
|
-
import Cookies from "js-cookie"
|
|
9
|
-
import { OverlayScrollbars } from 'overlayscrollbars'
|
|
10
|
-
import { cookieData } from "./cookieData"
|
|
11
|
-
|
|
8
|
+
import Cookies from "js-cookie";
|
|
9
|
+
import { OverlayScrollbars } from 'overlayscrollbars';
|
|
10
|
+
import { cookieData } from "./cookieData";
|
|
11
|
+
import { cookieStep1El, cookieStep2TittleEl, cookieStep2DetailEl } from "./cookieElement"
|
|
12
|
+
|
|
13
|
+
// 基礎版 cookie
|
|
14
|
+
const cookieBasic = {}
|
|
15
|
+
// 進階版 cookie
|
|
16
|
+
const cookieAdvanced = {}
|
|
17
|
+
// 存方法工具
|
|
12
18
|
const cookieSetting = {}
|
|
19
|
+
// 存結構
|
|
13
20
|
const cookieElements = {}
|
|
21
|
+
// 存一個空物件
|
|
22
|
+
let cookieNewObj = {};
|
|
14
23
|
|
|
15
24
|
// 簡易版 cookie 設定
|
|
16
|
-
|
|
25
|
+
cookieBasic.basicCookiePolicy = () => {
|
|
17
26
|
const $cookiePolicy = $(".cookie-check");
|
|
18
27
|
if (!$cookiePolicy.length) return;
|
|
19
28
|
|
|
@@ -47,7 +56,21 @@ cookieSetting.basicCookiePolicy = () => {
|
|
|
47
56
|
$closeBtn.on("click", () => {
|
|
48
57
|
$cookiePolicy.addClass("hidden");
|
|
49
58
|
sessionStorage.setItem("frameworkCookie-agree", "false");
|
|
59
|
+
if (typeof window._wdSetting === 'function') {
|
|
60
|
+
window._wdSetting()
|
|
61
|
+
}
|
|
50
62
|
});
|
|
63
|
+
|
|
64
|
+
// ⚠️ 以下可斟酌移除
|
|
65
|
+
// 開啟 cookie 視窗按鈕
|
|
66
|
+
$("[data-cookie-open]").on("click", function() {
|
|
67
|
+
$cookiePolicy.addClass("first-enter");
|
|
68
|
+
$cookiePolicy.removeClass("agree");
|
|
69
|
+
$cookiePolicy.removeClass("hidden");
|
|
70
|
+
setTimeout(() => {
|
|
71
|
+
$cookiePolicy.addClass("show");
|
|
72
|
+
}, 800);
|
|
73
|
+
})
|
|
51
74
|
};
|
|
52
75
|
|
|
53
76
|
// 執行事件
|
|
@@ -55,33 +78,90 @@ cookieSetting.basicCookiePolicy = () => {
|
|
|
55
78
|
clickEvent();
|
|
56
79
|
};
|
|
57
80
|
|
|
58
|
-
//
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
81
|
+
// ⚠️ ** --- 結構這邊修改 --- ** ⚠️
|
|
82
|
+
// step 1 結構
|
|
83
|
+
cookieElements.getStep1Element = (opt, index) => {
|
|
84
|
+
const isDisabled = opt.disabled ? "disabled" : ""
|
|
85
|
+
const isChecked = () => {
|
|
86
|
+
if (opt.key == "required") {
|
|
87
|
+
return "checked"
|
|
88
|
+
} else {
|
|
89
|
+
if (cookieSetting.hasAnyListItemsOpen(opt.key)) {
|
|
90
|
+
return "checked"
|
|
91
|
+
} else {
|
|
92
|
+
return ""
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return cookieStep1El(opt, index, isDisabled, isChecked)
|
|
67
97
|
}
|
|
68
98
|
|
|
69
|
-
//
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
99
|
+
// step 2 上面結構
|
|
100
|
+
cookieElements.getStep2TopElement = (opt, index) => {
|
|
101
|
+
const isDisabled = opt.disabled ? "disabled" : ""
|
|
102
|
+
const isChecked = () => {
|
|
103
|
+
if (opt.key == "required") {
|
|
104
|
+
return "checked"
|
|
105
|
+
} else {
|
|
106
|
+
if (cookieSetting.hasAnyListItemsOpen(opt.key)) {
|
|
107
|
+
return "checked"
|
|
108
|
+
} else {
|
|
109
|
+
return ""
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return cookieStep2TittleEl(opt, index, isDisabled, isChecked)
|
|
76
114
|
}
|
|
77
115
|
|
|
78
|
-
//
|
|
79
|
-
|
|
80
|
-
const
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
116
|
+
// step 2 下面細項結構
|
|
117
|
+
cookieElements.getStep2BottomElement = (data, li, index, parentKey, num) => {
|
|
118
|
+
const isDisabled = li.disabled ? " disabled" : ""
|
|
119
|
+
const isListChecked = cookieNewObj[parentKey].list[li.key].close == 0 ? "checked" : ""
|
|
120
|
+
|
|
121
|
+
return cookieStep2DetailEl(data, li, index, parentKey, num, isDisabled, isListChecked)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// 產生新物件
|
|
125
|
+
cookieAdvanced.newObj = () => {
|
|
126
|
+
if (Cookies.get('_wd') !== undefined) {
|
|
127
|
+
const cloudDdata = JSON.parse(Cookies.get('_wd'))
|
|
128
|
+
cookieNewObj = { ...cloudDdata }
|
|
129
|
+
} else {
|
|
130
|
+
const data = $("#_wcookie").val() ? JSON.parse($("#_wcookie").val())[0] : cookieData[0]
|
|
131
|
+
const options = data?.options;
|
|
132
|
+
if (options) {
|
|
133
|
+
// 判斷是否全開 or 全關 (排除 required)
|
|
134
|
+
const nonRequiredOptions = options.filter(opt => opt.key !== 'required');
|
|
135
|
+
const allNonRequiredAreFalse = nonRequiredOptions.every(opt => opt.close === 1);
|
|
136
|
+
const globalCloseValue = allNonRequiredAreFalse == 1 ? 1 : 0;
|
|
137
|
+
|
|
138
|
+
cookieNewObj.close = globalCloseValue;
|
|
139
|
+
|
|
140
|
+
const categoriesObject = options.reduce((acc, option) => {
|
|
141
|
+
const topLevelKey = option.key;
|
|
142
|
+
const dataItems = option.data?.items;
|
|
143
|
+
|
|
144
|
+
acc[topLevelKey] = { close: option.close };
|
|
145
|
+
|
|
146
|
+
if (data.multiType && dataItems !== undefined && dataItems.length > 0) {
|
|
147
|
+
acc[topLevelKey].list = {};
|
|
148
|
+
|
|
149
|
+
dataItems.forEach(item => {
|
|
150
|
+
item.list?.forEach(listItem => {
|
|
151
|
+
if (listItem.key) {
|
|
152
|
+
acc[topLevelKey].list[listItem.key] = {
|
|
153
|
+
close: listItem.close
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
return acc;
|
|
160
|
+
}, {});
|
|
161
|
+
// 若無 cookie 紀錄可抓, 直接新建一個新的物件預存
|
|
162
|
+
Object.assign(cookieNewObj, categoriesObject);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
85
165
|
}
|
|
86
166
|
|
|
87
167
|
// js 產 cookie 結構方法
|
|
@@ -94,7 +174,7 @@ cookieElements.generateHtmlString = (target, fn) => {
|
|
|
94
174
|
}
|
|
95
175
|
|
|
96
176
|
// 產資料結構
|
|
97
|
-
|
|
177
|
+
cookieAdvanced.dataAppend = () => {
|
|
98
178
|
const $block = $(".cookie-settingBlock")
|
|
99
179
|
if (!$block.length) return
|
|
100
180
|
|
|
@@ -111,26 +191,35 @@ cookieSetting.dataAppend = () => {
|
|
|
111
191
|
const opt = data.options[index]
|
|
112
192
|
const items = opt.data?.items || []
|
|
113
193
|
|
|
194
|
+
// ⚠️ ** --- 結構這邊修改 --- ** ⚠️
|
|
114
195
|
// 產 step2 下方結構
|
|
115
196
|
const htmlStep2bottom = items.length > 0
|
|
116
|
-
? items.map(
|
|
197
|
+
? items.map((item,num) => `
|
|
117
198
|
<div class="item">
|
|
118
199
|
<div class="list">
|
|
119
|
-
<div class="main">${
|
|
120
|
-
<div class="text">${
|
|
200
|
+
<div class="main">${item.main}</div>
|
|
201
|
+
<div class="text">${item.text}</div>
|
|
121
202
|
</div>
|
|
122
203
|
${
|
|
123
|
-
(
|
|
124
|
-
(li.detail && li.detail.length > 0)
|
|
125
|
-
|
|
204
|
+
(item.list || []).map((li, index) =>
|
|
205
|
+
(li.detail && li.detail.length > 0) ?
|
|
206
|
+
cookieElements.getStep2BottomElement(data, li, index, opt.key, num)
|
|
126
207
|
: `
|
|
127
208
|
<div class="list">
|
|
128
209
|
<div class="title">
|
|
129
210
|
<span>${li.title || ""}</span>
|
|
130
|
-
${li.key.length > 0 ?
|
|
131
|
-
|
|
132
|
-
<
|
|
133
|
-
|
|
211
|
+
${data.multiType && li.key.length > 0 ?
|
|
212
|
+
`<div class="switch-box ${opt.disabled ? "disabled" : ""}">
|
|
213
|
+
<input type="checkbox" hidden
|
|
214
|
+
id="s2-content-${num}-${index}"
|
|
215
|
+
${cookieNewObj[opt.key].list[li.key].close == 0 ? "checked" : ""}
|
|
216
|
+
data-name="${li.key}"
|
|
217
|
+
data-parent="${opt.key || ""}"
|
|
218
|
+
>
|
|
219
|
+
<label class="switch" for="s2-content-${num}-${index}"></label>
|
|
220
|
+
</div>`
|
|
221
|
+
: ""
|
|
222
|
+
}
|
|
134
223
|
</div>
|
|
135
224
|
<div class="text">${li.text || ""}</div>
|
|
136
225
|
</div>
|
|
@@ -140,291 +229,241 @@ cookieSetting.dataAppend = () => {
|
|
|
140
229
|
</div>
|
|
141
230
|
`).join("")
|
|
142
231
|
: `<div class="item"><div class="text">此分類目前沒有詳細資料。</div></div>`
|
|
143
|
-
|
|
232
|
+
|
|
144
233
|
// 產 step2 上方結構
|
|
145
234
|
$step2.find(".top-block").html(cookieElements.getStep2TopElement(opt, index))
|
|
146
235
|
// 產 step2 下方結構
|
|
147
236
|
$step2.find(".content-block").html(htmlStep2bottom)
|
|
148
|
-
|
|
149
|
-
switchState(opt.key)
|
|
237
|
+
|
|
150
238
|
// 換頁
|
|
151
239
|
methods.pageChange(true)
|
|
240
|
+
// 重綁收合
|
|
152
241
|
methods.collapseEvent('[data-collapse-click]', '[data-collapse]', '[data-collapse-content]', false, true)
|
|
153
242
|
})
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// switch 的一些狀態
|
|
246
|
+
cookieAdvanced.switchState = () => {
|
|
247
|
+
const $step2contentSwitch = `[data-step="2"] .content-block input[type="checkbox"][data-parent][data-name]:not(.disabled)`
|
|
248
|
+
const $step2topSwitch = `[data-step="2"] .top-block input[type="checkbox"][data-name]:not(.disabled)`
|
|
249
|
+
|
|
250
|
+
let isSyncing = false
|
|
154
251
|
|
|
155
252
|
// 開關同步連動控制
|
|
156
|
-
// 若只有一顆控制按鈕, 可關閉
|
|
253
|
+
// ⚠️ 若只有一顆控制按鈕, 可關閉
|
|
157
254
|
$(document).on('change', 'input[type="checkbox"][data-name]:not(:disabled)', function () {
|
|
158
255
|
const key = $(this).data('name')
|
|
159
256
|
const val = $(this).prop('checked')
|
|
160
|
-
|
|
257
|
+
if (isSyncing) return
|
|
258
|
+
isSyncing = true
|
|
259
|
+
|
|
161
260
|
$(`input[type="checkbox"][data-name="${key}"]`).not(this).prop('checked', val)
|
|
261
|
+
|
|
262
|
+
isSyncing = false
|
|
162
263
|
})
|
|
163
264
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
$(
|
|
184
|
-
`[data-step="2"] .content-block input[type="checkbox"][data-name]:not(:disabled)`
|
|
185
|
-
)
|
|
186
|
-
.prop('checked', val)
|
|
187
|
-
.trigger('change')
|
|
188
|
-
}
|
|
189
|
-
)
|
|
190
|
-
|
|
191
|
-
$(document).on(
|
|
192
|
-
'change',
|
|
193
|
-
`[data-step="2"] .content-block input[type="checkbox"][data-name]:not(:disabled)`,
|
|
194
|
-
function () {
|
|
195
|
-
const $all = $(
|
|
196
|
-
`[data-step="2"] .content-block input[type="checkbox"][data-name]:not(:disabled)`
|
|
197
|
-
)
|
|
198
|
-
const total = $all.length
|
|
199
|
-
const checked = $all.filter(':checked').length
|
|
200
|
-
|
|
201
|
-
if (!total) return
|
|
202
|
-
|
|
203
|
-
if (checked === total) {
|
|
204
|
-
// 全開
|
|
205
|
-
$step2TopCheckbox.prop('checked', true)
|
|
206
|
-
} else if (checked === 0) {
|
|
207
|
-
// 全關
|
|
208
|
-
$step2TopCheckbox.prop('checked', false)
|
|
209
|
-
}
|
|
265
|
+
// step1 變動 → 更新 cookieNewObj
|
|
266
|
+
$(document)
|
|
267
|
+
.off('change.cookieStep1')
|
|
268
|
+
.on('change.cookieStep1', `[data-step="1"] input[type="checkbox"][data-name]`, function () {
|
|
269
|
+
if (isSyncing) return
|
|
270
|
+
isSyncing = true
|
|
271
|
+
|
|
272
|
+
const key = $(this).data("name")
|
|
273
|
+
const val = $(this).prop('checked') ? 0 : 1
|
|
274
|
+
if (cookieNewObj[key]) {
|
|
275
|
+
cookieNewObj[key].close = val
|
|
276
|
+
const targetList = cookieNewObj[key].list;
|
|
277
|
+
if (targetList && typeof targetList === 'object') {
|
|
278
|
+
Object.keys(targetList).forEach(childKey => {
|
|
279
|
+
if (targetList[childKey].close !== undefined) {
|
|
280
|
+
targetList[childKey].close = val;
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
}
|
|
210
284
|
}
|
|
211
|
-
)
|
|
212
285
|
|
|
213
|
-
|
|
214
|
-
}
|
|
286
|
+
isSyncing = false
|
|
287
|
+
})
|
|
215
288
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
// 紀錄每一個值存入
|
|
221
|
-
cookieSetting.save = () => {
|
|
222
|
-
let allOpen = true;
|
|
223
|
-
const mainCookies = ['required', 'analytics', 'functionality', 'advertising'];
|
|
224
|
-
const obj = {};
|
|
225
|
-
|
|
226
|
-
mainCookies.forEach((key) => {
|
|
227
|
-
// 先存大分類的 cookie
|
|
228
|
-
const isOpen = $(`input[type="checkbox"][data-name="${key}"]`)
|
|
229
|
-
.first()
|
|
230
|
-
.prop('checked');
|
|
231
|
-
const category = {
|
|
232
|
-
close: isOpen ? 0 : 1,
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
// 再存大分類底下所有細項的 cookie
|
|
236
|
-
const children = {};
|
|
237
|
-
$(`input[type="checkbox"][data-parent="${key}"][data-name]`)
|
|
238
|
-
.each(function () {
|
|
239
|
-
const childKey = $(this).data('name');
|
|
240
|
-
const childOpen = $(this).prop('checked');
|
|
241
|
-
children[childKey] = {
|
|
242
|
-
close: childOpen ? 0 : 1,
|
|
243
|
-
};
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
if (Object.keys(children).length > 0) {
|
|
247
|
-
category.list = children;
|
|
248
|
-
}
|
|
289
|
+
$(document)
|
|
290
|
+
.off("change.step2content")
|
|
291
|
+
.on("change.step2content", $step2contentSwitch, function () {
|
|
249
292
|
|
|
250
|
-
|
|
251
|
-
|
|
293
|
+
if (isSyncing) return
|
|
294
|
+
isSyncing = true
|
|
295
|
+
|
|
296
|
+
const key = $(this).data("name")
|
|
297
|
+
const parent = $(this).data("parent")
|
|
298
|
+
const val = $(this).prop('checked') ? 0 : 1
|
|
299
|
+
const $step1Switch = $(`[data-step="1"] input[type="checkbox"][data-name='${parent}']:not(.disabled)`)
|
|
300
|
+
const total = $($step2contentSwitch).length
|
|
301
|
+
const checked = $($step2contentSwitch).filter(':checked').length
|
|
252
302
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
if (
|
|
258
|
-
|
|
259
|
-
|
|
303
|
+
// 改變 cookieNewObj 的值
|
|
304
|
+
cookieNewObj[parent].list[key].close = val
|
|
305
|
+
|
|
306
|
+
// Step2 子項全部打開
|
|
307
|
+
if (checked === total || checked > 0) {
|
|
308
|
+
cookieNewObj[parent].close = 0
|
|
309
|
+
$($step2topSwitch).prop("checked", true)
|
|
310
|
+
$step1Switch.prop("checked", true)
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Step2 子項全部關閉
|
|
314
|
+
else if (checked === 0) {
|
|
315
|
+
cookieNewObj[parent].close = 1
|
|
316
|
+
$($step2topSwitch).prop("checked", false)
|
|
317
|
+
$step1Switch.prop("checked", false)
|
|
260
318
|
}
|
|
261
|
-
}
|
|
262
319
|
|
|
263
|
-
|
|
320
|
+
isSyncing = false
|
|
321
|
+
})
|
|
264
322
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
sameSite: true,
|
|
269
|
-
});
|
|
270
|
-
}
|
|
323
|
+
$(document)
|
|
324
|
+
.off("change.step2top")
|
|
325
|
+
.on("change.step2top", $step2topSwitch, function () {
|
|
271
326
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
const raw = Cookies.get('_wd');
|
|
275
|
-
if (!raw) return;
|
|
327
|
+
if (isSyncing) return
|
|
328
|
+
isSyncing = true
|
|
276
329
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
} catch {
|
|
281
|
-
return;
|
|
282
|
-
}
|
|
330
|
+
const key = $(this).data("name")
|
|
331
|
+
const isChecked = $(this).prop("checked")
|
|
332
|
+
const val = isChecked ? 0 : 1
|
|
283
333
|
|
|
284
|
-
|
|
334
|
+
// 改所有子項
|
|
335
|
+
$($step2contentSwitch)
|
|
336
|
+
.prop('checked', isChecked)
|
|
285
337
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
338
|
+
// 改 cookie main
|
|
339
|
+
if (cookieNewObj[key]) {
|
|
340
|
+
const list = cookieNewObj[key].list
|
|
341
|
+
cookieNewObj[key].close = val
|
|
342
|
+
if (list) {
|
|
343
|
+
Object.keys(list).forEach(childKey => {
|
|
344
|
+
list[childKey].close = val
|
|
345
|
+
})
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
isSyncing = false
|
|
349
|
+
})
|
|
350
|
+
}
|
|
289
351
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
352
|
+
// 存 cookie
|
|
353
|
+
cookieAdvanced.cookieSaveFn = () => {
|
|
354
|
+
const nonRequiredValues = Object.entries(cookieNewObj)
|
|
355
|
+
.filter(([key]) => key !== 'required' && key !== 'close')
|
|
356
|
+
.map(([, value]) => value);
|
|
357
|
+
|
|
358
|
+
const allNonRequiredAreClosed = nonRequiredValues.every(opt => opt.close === 1);
|
|
359
|
+
const globalCloseValue = allNonRequiredAreClosed ? 1 : 0;
|
|
360
|
+
|
|
361
|
+
// 判斷設定第一層的 close 值
|
|
362
|
+
cookieNewObj.close = globalCloseValue;
|
|
363
|
+
|
|
364
|
+
// 存入 cookie
|
|
365
|
+
Cookies.set('_wd', JSON.stringify(cookieNewObj), {
|
|
366
|
+
expires: 180,
|
|
367
|
+
path: '/',
|
|
368
|
+
sameSite: true,
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// 點擊方法
|
|
373
|
+
cookieAdvanced.clickEvent = () => {
|
|
374
|
+
const $settingBtn = $(".cookie-settingBtn")
|
|
375
|
+
const $settingBlock = $(".cookie-settingBlock")
|
|
376
|
+
|
|
377
|
+
// 打開進階版 cookie 介面
|
|
378
|
+
$settingBtn.on("click", () => {
|
|
379
|
+
cookieSetting.openEvent($settingBlock)
|
|
380
|
+
});
|
|
294
381
|
|
|
295
|
-
const children = category.list || {};
|
|
296
|
-
Object.keys(children).forEach((childKey) => {
|
|
297
|
-
const childChecked = children[childKey].close === 0;
|
|
298
|
-
$(`input[type="checkbox"][data-parent="${key}"][data-name="${childKey}"]`)
|
|
299
|
-
.prop('checked', childChecked)
|
|
300
|
-
.trigger('change');
|
|
301
|
-
});
|
|
302
|
-
});
|
|
303
|
-
};
|
|
304
382
|
// 一鍵全開
|
|
305
383
|
cookieSetting.enableAll = () => {
|
|
306
|
-
$(`input[type="checkbox"][data-name]:not(
|
|
384
|
+
$(`input[type="checkbox"][data-name]:not(.disabled)`).prop('checked', true).trigger('change')
|
|
385
|
+
cookieNewObj.close = 0
|
|
386
|
+
Object.keys(cookieNewObj).forEach(data => {
|
|
387
|
+
cookieNewObj[data].close == 0
|
|
388
|
+
})
|
|
389
|
+
}
|
|
390
|
+
// 一鍵全關
|
|
391
|
+
cookieSetting.rejectAll = () => {
|
|
392
|
+
$(`input[type="checkbox"][data-name]:not([data-name="required"])`).prop('checked', false).trigger('change')
|
|
393
|
+
cookieNewObj.close = 1
|
|
394
|
+
Object.keys(cookieNewObj).forEach(data => {
|
|
395
|
+
cookieNewObj[data].close == 1
|
|
396
|
+
})
|
|
307
397
|
}
|
|
308
|
-
|
|
309
398
|
// 綁定按鈕
|
|
310
|
-
$("[data-cookie-all]").on('click',
|
|
399
|
+
$("[data-cookie-all]").on('click', function(){
|
|
400
|
+
cookieSetting.enableAll()
|
|
401
|
+
})
|
|
311
402
|
// 儲存
|
|
312
403
|
$("[data-cookie-save]").on('click', function(){
|
|
313
|
-
|
|
404
|
+
cookieAdvanced.cookieSaveFn()
|
|
314
405
|
})
|
|
315
406
|
// 關閉視窗
|
|
316
407
|
$("[data-cookie-close]").on('click', function(){
|
|
317
|
-
cookieSetting.closeEvent($
|
|
408
|
+
cookieSetting.closeEvent($settingBlock)
|
|
409
|
+
})
|
|
410
|
+
$("[data-cookie-reject]").on('click', function() {
|
|
411
|
+
cookieSetting.rejectAll()
|
|
412
|
+
cookieAdvanced.cookieSaveFn()
|
|
318
413
|
})
|
|
319
|
-
|
|
320
|
-
// 頁面載入時先還原一次
|
|
321
|
-
$(cookieSetting.restore)
|
|
322
414
|
}
|
|
323
415
|
|
|
324
|
-
//
|
|
325
|
-
//
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
</div>
|
|
335
|
-
<label for="s1-check-${index}"><span>${opt.title}</span></label>
|
|
336
|
-
</div>
|
|
337
|
-
<div class="desc">
|
|
338
|
-
<div class="text">${opt.text}</div>
|
|
339
|
-
${opt.notice ? `
|
|
340
|
-
<div class="notice">
|
|
341
|
-
<div class="icon"><i class="icon-notice"></i></div>
|
|
342
|
-
<span>${opt.notice}</span>
|
|
343
|
-
</div>` : ""}
|
|
344
|
-
</div>
|
|
345
|
-
</div>
|
|
346
|
-
<div class="right">
|
|
347
|
-
<div class="switch-box ${opt.disabled ? " disabled" : ""}">
|
|
348
|
-
<input type="checkbox" hidden id="s1-switch-${index}" ${opt.disabled ? "checked" : ""} data-name="${opt.key}">
|
|
349
|
-
<label class="switch" for="s1-switch-${index}"></label>
|
|
350
|
-
</div>
|
|
351
|
-
<div class="icon" data-open><i class="icon-arrow"></i></div>
|
|
352
|
-
</div>
|
|
353
|
-
</div>
|
|
354
|
-
`
|
|
416
|
+
// ** --- 工具們 --- **
|
|
417
|
+
// cookie 開啟方法
|
|
418
|
+
cookieSetting.openEvent = (el) => {
|
|
419
|
+
$(el).addClass("active")
|
|
420
|
+
setTimeout(() => {
|
|
421
|
+
$(el).addClass("show")
|
|
422
|
+
scrollLock();
|
|
423
|
+
const scrollers = $(".cookie-settingBlock").find('.scroller')[0]
|
|
424
|
+
OverlayScrollbars(scrollers, {})
|
|
425
|
+
}, 500);
|
|
355
426
|
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
<div class="input-wrap">
|
|
364
|
-
<input type="checkbox" id="s2-check-${index}" ${opt.disabled ? "checked" : ""} data-name="${opt.key}">
|
|
365
|
-
<div class="fake-checkbox"><i class="icon-check"></i></div>
|
|
366
|
-
</div>
|
|
367
|
-
<label for="s2-check-${index}"><span>${opt.title}</span></label>
|
|
368
|
-
</div>
|
|
369
|
-
</div>
|
|
370
|
-
<div class="right">
|
|
371
|
-
<div class="switch-box ${opt.disabled ? " disabled" : ""}">
|
|
372
|
-
<input type="checkbox" hidden id="s2-switch-${index}" ${opt.disabled ? "checked" : ""} data-name="${opt.key}">
|
|
373
|
-
<label class="switch" for="s2-switch-${index}"></label>
|
|
374
|
-
</div>
|
|
375
|
-
</div>
|
|
376
|
-
</div>
|
|
377
|
-
<div class="desc">
|
|
378
|
-
<div class="text">${opt.text || ""}</div>
|
|
379
|
-
${opt.notice ? `<div class="notice"><div class="icon"><i class="icon-notice"></i></div><span>${opt.notice}</span></div> ` : ""}
|
|
380
|
-
</div>
|
|
381
|
-
`
|
|
427
|
+
// cookie 關閉方法
|
|
428
|
+
cookieSetting.closeEvent = (el) => {
|
|
429
|
+
$(el).removeClass("show")
|
|
430
|
+
setTimeout(() => {
|
|
431
|
+
$(el).removeClass("active")
|
|
432
|
+
scrollUnlock();
|
|
433
|
+
}, 500);
|
|
382
434
|
}
|
|
435
|
+
// 判斷該分類底下細項按鈕狀態
|
|
436
|
+
cookieSetting.hasAnyListItemsOpen = (key) => {
|
|
437
|
+
const targetList = cookieNewObj[key]?.list;
|
|
438
|
+
if (!targetList) {
|
|
439
|
+
if (cookieNewObj[key].close == 0) {
|
|
440
|
+
return true;
|
|
441
|
+
} else {
|
|
442
|
+
return false;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
const childKeys = Object.keys(targetList);
|
|
446
|
+
const isOpen = childKeys.some(childKey => {
|
|
447
|
+
return targetList[childKey]?.close === 0;
|
|
448
|
+
});
|
|
449
|
+
return isOpen;
|
|
450
|
+
};
|
|
383
451
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
${opt.key ? `<div class="switch-box ${opt.disabled ? " disabled" : ""}">
|
|
392
|
-
<input type="checkbox" hidden id="s2detail-switch-${index}" ${opt.disabled ? "checked" : ""} data-name="${opt.key}" data-parent="${parentKey || ""}">
|
|
393
|
-
<label class="switch" for="s2detail-switch-${index}"></label>
|
|
394
|
-
</div>` : ""}
|
|
395
|
-
</div>
|
|
396
|
-
${opt.text ? `<div class="text">${opt.text}</div>` : ""}
|
|
397
|
-
<div class="list-detail collapseBox" data-collapse-content>
|
|
398
|
-
<div class="innerBox">
|
|
399
|
-
<div class="content">
|
|
400
|
-
${
|
|
401
|
-
opt.detail?.length > 0 ? cookieElements.generateHtmlString(opt.detail, (i) => {
|
|
402
|
-
return `
|
|
403
|
-
<div class="li">
|
|
404
|
-
<div class="title">${i.title || ""}</div>
|
|
405
|
-
${i.text ? `<div class="text">${i.text}</div>` : ""}
|
|
406
|
-
<div class="flex">
|
|
407
|
-
<div class="text bold">${i.typeTitle || ""}</div>
|
|
408
|
-
<div class="text">${i.typeDesc || ""}</div>
|
|
409
|
-
</div>
|
|
410
|
-
</div>
|
|
411
|
-
`
|
|
412
|
-
}) : ""
|
|
413
|
-
}
|
|
414
|
-
</div>
|
|
415
|
-
</div>
|
|
416
|
-
</div>
|
|
417
|
-
</div>
|
|
418
|
-
`
|
|
452
|
+
cookieAdvanced.init = () => {
|
|
453
|
+
cookieAdvanced.newObj();
|
|
454
|
+
cookieAdvanced.dataAppend();
|
|
455
|
+
// cookieAdvanced.initialState();
|
|
456
|
+
cookieAdvanced.clickEvent();
|
|
457
|
+
cookieAdvanced.cookieSaveFn();
|
|
458
|
+
cookieAdvanced.switchState();
|
|
419
459
|
}
|
|
420
460
|
|
|
421
461
|
methods.toBackend({ getCookieValue: (el) => Cookies.get(el) });
|
|
422
462
|
|
|
423
|
-
export const init = () => {
|
|
463
|
+
export const init = (isOpenAdvanced = false) => {
|
|
424
464
|
// cookie 基本版
|
|
425
|
-
|
|
465
|
+
cookieBasic.basicCookiePolicy();
|
|
466
|
+
if (!isOpenAdvanced) return
|
|
426
467
|
// cookie 進階版
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
cookieSetting.cookieSaveFn();
|
|
430
|
-
}
|
|
468
|
+
cookieAdvanced.init();
|
|
469
|
+
}
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
p.title Cookie
|
|
7
7
|
p.text 關於本網站使用瀏覽器紀錄 Cookie 來提供您最好的使用體驗,我們使用的 Cookie 也包括了第三方 Cookie 。<br>相關資訊請訪問我們的隱私權與 Cookie 政策。如果您選擇繼續瀏覽或關閉這個提示,便表示您已接受我們的網站使用條款。
|
|
8
8
|
.button-group
|
|
9
|
-
.cookie-btn.close Reject 我拒絕
|
|
9
|
+
.cookie-btn.close(data-cookie-reject) Reject 我拒絕
|
|
10
10
|
.cookie-btn.agree(data-cookie-save) OK 我接受
|
|
11
|
-
.cookie-settingBtn
|
|
11
|
+
.cookie-settingBtn
|
|
12
12
|
span Cookie 偏好設定
|
|
13
13
|
.icon
|
|
14
14
|
i.icon-arrow
|
|
@@ -37,4 +37,4 @@
|
|
|
37
37
|
// JS append 結構
|
|
38
38
|
|
|
39
39
|
// 後端 cookie 資料放這兒
|
|
40
|
-
<input id="_wcookie" type="hidden" value="[{"title":"\u60a8\u7684 Cookie \u504f\u597d\u8a2d\u5b9a","text":"\u6211\u5011\u4f7f\u7528\u4e0d\u540c\u985e\u578b\u7684 Cookies \u4f86\u512a\u5316\u60a8\u5728\u6211\u5011\u7684\u7db2\u7ad9\u4e0a\u7684\u9ad4\u9a57\uff0c\u9ede\u64ca\u4e0b\u9762\u985e\u5225\u4ee5\u4e86\u89e3\u5176\u76ee\u7684\u8207\u66f4\u591a\u8a0a\u606f\u3002\u003Cbr\u003E\u60a8\u53ef\u4ee5\u9078\u64c7\u5141\u8a31\u7684 Cookies \u985e\u578b\uff0c\u4e5f\u53ef\u4ee5\u96a8\u6642\u66f4\u6539\u60a8\u7684\u504f\u597d\u8a2d\u5b9a\u3002\u003Cbr\u003E\u63d0\u9192\u60a8\uff0c\u505c\u7528 Cookies \u53ef\u80fd\u6703\u5f71\u97ff\u60a8\u5728\u7db2\u7ad9\u4e0a\u7684\u9ad4\u9a57\uff0c\u60a8\u53ef\u4ee5\u700f\u89bd\u6211\u5011\u7684\u96b1\u79c1\u6b0a\u653f\u7b56\uff0c\u9032\u4e00\u6b65\u4e86\u89e3\u6211\u5011\u5982\u4f55\u4f7f\u7528 Cookie\u3002","options":[{"key":"required","state":true,"disabled":true,"title":"\u56b4\u683c\u5fc5\u8981","text":"\u9019\u4e9b Cookies \u5c0d\u65bc\u652f\u6301\u6838\u5fc3\u7db2\u7ad9\u529f\u80fd\uff08\u4f8b\u5982\u63d0\u4f9b\u5b89\u5168\u767b\u9304\uff09\u81f3\u95dc\u91cd\u8981\u3002","data":{"items":[{"main":"\u7b2c\u4e00\u65b9 Cookie \u63d0\u4f9b\u5546","text":"\u7b2c\u4e00\u65b9 cookies \u7531\u7528\u6236\u8a2a\u554f\u7684\u7db2\u7ad9\uff08\u5373\u4e3b\u6a5f\u57df\u540d\uff09\u8a2d\u7f6e\u3002\u7db2\u7ad9\u901a\u5e38\u4f7f\u7528\u7b2c\u4e00\u65b9 cookies \u7528\u65bc\u8ddf\u8e2a\u8a2a\u5ba2\u5728\u7db2\u7ad9\u4e0a\u7684\u884c\u70ba\u4e26\u500b\u6027\u5316\u4ed6\u5011\u5728\u7db2\u7ad9\u4e0a\u7684\u700f\u89bd\u9ad4\u9a57\u4ee5\u53ca\u500b\u6027\u5316\u4ed6\u5011\u7684\u700f\u89bd\u9ad4\u9a57\u3002","list":[{"key":"","state":"","title":"PHPSESSID","text":"\u7db2\u7ad9\u7528\u65bc\u8fa8\u8b58\u7528\u6236\u7684session id"},{"key":"","state":"","title":"XSRF-TOKEN","text":"\u7db2\u7ad9\u7528\u65bc\u9632\u6b62 CSRF\uff08Cross-Site Request Forgery\uff0c\u8de8\u7ad9\u8acb\u6c42\u507d\u9020\uff09\u653b\u64caTOKEN"},{"key":"","state":"","title":"web_session","text":"\u7db2\u7ad9\u7528\u65bc\u8fa8\u8b58\u7528\u6236\u7684session id"},{"key":"","state":"","title":"_cfuvid","text":"hubspot\u8868\u55ae\u670d\u52d9\u4f7f\u7528\u4e86Cloudflare\u670d\u52d9\uff0c\u7528\u65bc\u5340\u5206\u771f\u4eba\u8a2a\u5ba2\u6216\u6a5f\u5668\u4eba"}]}]}},{"key":"analytics","state":false,"disabled":false,"title":"\u7d71\u8a08\u5206\u6790","text":"\u9019\u4e9b Cookies \u7d71\u8a08\/\u5206\u6790\u7db2\u7ad9\u4f7f\u7528\u60c5\u6cc1\uff0c\u4ee5\u63d0\u4f9b\u66f4\u597d\u7684\u7db2\u7ad9\u9ad4\u9a57\u3002","data":{"items":[{"main":"\u7b2c\u4e00\u65b9 Cookie \u63d0\u4f9b\u5546","text":"\u7b2c\u4e00\u65b9 cookies \u7531\u7528\u6236\u8a2a\u554f\u7684\u7db2\u7ad9\uff08\u5373\u4e3b\u6a5f\u57df\u540d\uff09\u8a2d\u7f6e\u3002\u7db2\u7ad9\u901a\u5e38\u4f7f\u7528\u7b2c\u4e00\u65b9 cookies \u7528\u65bc\u8ddf\u8e2a\u8a2a\u5ba2\u5728\u7db2\u7ad9\u4e0a\u7684\u884c\u70ba\u4e26\u500b\u6027\u5316\u4ed6\u5011\u5728\u7db2\u7ad9\u4e0a\u7684\u700f\u89bd\u9ad4\u9a57\u4ee5\u53ca\u500b\u6027\u5316\u4ed6\u5011\u7684\u700f\u89bd\u9ad4\u9a57\u3002","list":[{"title":"gtm","key":"","state":""},{"title":"ga","key":"","state":"","detail":[{"title":"_ga","text":"\u7528\u4f86\u5340\u5206\u4e0d\u540c\u4f7f\u7528\u8005\u3002\u6bcf\u500b\u4f7f\u7528\u8005\u6703\u88ab\u6307\u6d3e\u552f\u4e00\u7684 ID","typeTitle":"\u6642\u9593 \/ \u985e\u578b","typeDesc":"13 \u500b\u6708"},{"title":"_ga_\u003Ccontainer-id\u003E","text":"\u8ffd\u8e64\u55ae\u4e00\u5c6c\u6027 (Property) \u7684\u8cc7\u6599\u3002","typeTitle":"\u6642\u9593 \/ \u985e\u578b","typeDesc":"13 \u500b\u6708"}]}]}]}},{"key":"functionality","state":false,"disabled":false,"title":"\u529f\u80fd\/\u504f\u597d","text":"\u9019\u4e9b Cookies \u7d00\u9304\u60a8\u7684\u504f\u597d\u6216\u63d0\u4f9b\u66f4\u597d\u7684\u9ad4\u9a57","data":{"items":[{"main":"\u7b2c\u4e09\u65b9 Cookie \u63d0\u4f9b\u5546","text":"\u7b2c\u4e09\u65b9 cookies \u662f\u7531\u5176\u4ed6\u7b2c\u4e09\u65b9\u5be6\u9ad4\u653e\u7f6e\u5728\u7db2\u7ad9\u4e0a\uff0c\u800c\u4e0d\u662f\u7db2\u7ad9\u672c\u8eab\uff0c\u5373\u4f7f\u7528\u8005\u5728\u5730\u5740\u6b04\u4e2d\u770b\u5230\u7684\u7db2\u57df\u4ee5\u5916\u7684\u57df\u540d\u3002\u7b2c\u4e09\u65b9 cookies \u901a\u5e38\u8ddf\u8e2a\u8a2a\u5ba2\u5728\u7db2\u7ad9\u4e4b\u9593\u7684\u884c\u70ba\uff0c\u901a\u5e38\u7528\u65bc\u91dd\u5c0d\u6027\u5ee3\u544a\u76ee\u7684\u3002","list":[{"title":"googlefont","key":"","state":""},{"title":"Vimeo","text":"https:\/\/vimeo.com\/","key":"","state":"","detail":[{"title":"_cf_bm","text":"Cloudflare bot manager manages incoming traffic that matches the criteria associated with bots.","typeTitle":"\u6642\u9593 \/ \u985e\u578b","typeDesc":"30 \u5206"},{"title":"_cfuvid","text":"Cloudflare cookie used to enforce rate-limiting rules.","typeTitle":"\u6642\u9593 \/ \u985e\u578b","typeDesc":"session"}]},{"title":"Tiktok","text":"https:\/\/www.tiktok.com\/zh-Hant-TW\/","key":"","state":"","detail":[{"title":"_ttp","text":"To measure and improve the performance of advertising campaigns and to personalize the customer experience (including ads) on TikTok.","typeTitle":"\u6642\u9593 \/ \u985e\u578b","typeDesc":"13 \u500b\u6708"},{"title":"msToken","text":"\u7528\u65bc\u5b58\u5132\u7528\u6236\u7684\u6703\u8a71\u4ee4\u724c\uff0c\u78ba\u4fdd\u7528\u6236\u5728\u700f\u89bd\u5668\u6703\u8a71\u671f\u9593\u4fdd\u6301\u767b\u9304\u72c0\u614b\u3002","typeTitle":"\u6642\u9593 \/ \u985e\u578b","typeDesc":"10 \u5929"},{"title":"passport_csrf_token","text":"\u7528\u65bc\u9632\u6b62\u8de8\u7ad9\u8acb\u6c42\u507d\u9020\uff08CSRF\uff09\u653b\u64ca\uff0c\u78ba\u4fdd\u8acb\u6c42\u7684\u5408\u6cd5\u6027\u3002","typeTitle":"\u6642\u9593 \/ \u985e\u578b","typeDesc":"60 \u5929"},{"title":"ttwid","text":"\u7528\u65bc\u8b58\u5225\u7528\u6236\u7684\u552f\u4e00 ID\uff0c\u5354\u52a9 TikTok \u9032\u884c\u7528\u6236\u8b58\u5225\u8207\u9632\u6b62\u6a5f\u5668\u4eba\u884c\u70ba\u3002","typeTitle":"\u6642\u9593 \/ \u985e\u578b","typeDesc":"10 \u5929"}]}]}]}},{"key":"advertising","state":false,"disabled":false,"title":"\u5ee3\u544a\u8207\u884c\u92b7","text":"\u9019\u4e9b Cookies \u70ba\u8de8\u7db2\u7ad9\u8ffd\u8e64\u3001\u5ee3\u544a\u518d\u884c\u92b7","data":{"items":[{"main":"\u7b2c\u4e09\u65b9 Cookie \u63d0\u4f9b\u5546","text":"\u7b2c\u4e09\u65b9 cookies \u662f\u7531\u5176\u4ed6\u7b2c\u4e09\u65b9\u5be6\u9ad4\u653e\u7f6e\u5728\u7db2\u7ad9\u4e0a\uff0c\u800c\u4e0d\u662f\u7db2\u7ad9\u672c\u8eab\uff0c\u5373\u4f7f\u7528\u8005\u5728\u5730\u5740\u6b04\u4e2d\u770b\u5230\u7684\u7db2\u57df\u4ee5\u5916\u7684\u57df\u540d\u3002\u7b2c\u4e09\u65b9 cookies \u901a\u5e38\u8ddf\u8e2a\u8a2a\u5ba2\u5728\u7db2\u7ad9\u4e4b\u9593\u7684\u884c\u70ba\uff0c\u901a\u5e38\u7528\u65bc\u91dd\u5c0d\u6027\u5ee3\u544a\u76ee\u7684\u3002","list":[{"title":"Youtube","text":"https:\/\/www.youtube.com\/","key":"","state":"","detail":[{"title":"YSC","text":"\u7528\u65bc\u8ffd\u8e64\u5f71\u7247\u64ad\u653e\u6703\u8a71\uff08Session cookie\uff09\uff0c\u4e0d\u542b\u500b\u8cc7\u4f46\u53ef\u8b58\u5225\u55ae\u6b21\u89c0\u770b\u3002","typeTitle":"\u6642\u9593 \/ \u985e\u578b","typeDesc":"session"},{"title":"__Secure-YNID","typeTitle":"\u6642\u9593 \/ \u985e\u578b","typeDesc":"6 \u500b\u6708"},{"title":"__Secure-ROLLOUT_TOKEN","text":"\u7528\u65bc YouTube \/ Google \u529f\u80fd\u7684\u300c\u7248\u672c\u6efe\u52d5 \/ \u6e2c\u8a66\u529f\u80fd\u63a7\u5236\u300d\uff08feature rollout \/ A\/B \u6e2c\u8a66\u63a7\u5236\uff09","typeTitle":"\u6642\u9593 \/ \u985e\u578b","typeDesc":"6 \u500b\u6708"},{"title":"VISITOR_INFO1_LIVE","text":"\u7528\u65bc\u8861\u91cf\u4f7f\u7528\u8005\u7684\u7db2\u8def\u983b\u5bec \/ \u5224\u65b7\u662f\u5426\u4f7f\u7528\u65b0\u7248\u6216\u820a\u7248 YouTube \u64ad\u653e\u5668\u4ecb\u9762\uff0c\u4ee5\u53ca\u67d0\u4e9b YouTube \u670d\u52d9\u4e2d\u7528\u65bc\u89c0\u5bdf\u4f7f\u7528\u8005\u8a2d\u5099 \/ \u6d41\u91cf\u80fd\u529b","typeTitle":"\u6642\u9593 \/ \u985e\u578b","typeDesc":"6 \u500b\u6708"},{"title":"VISITOR_PRIVACY_METADATA","text":"\u7528\u4f86\u5132\u5b58\u4f7f\u7528\u8005\u5728\u7576\u524d\u7db2\u57df\uff08domain\uff09\u4e0a\u5c0d cookie \u540c\u610f \/ \u96b1\u79c1\u8a2d\u5b9a\u72c0\u614b\u7684\u5143\u8cc7\u6599\uff08metadata\uff09","typeTitle":"\u6642\u9593 \/ \u985e\u578b","typeDesc":"6 \u500b\u6708"},{"title":"__Secure-YEC","text":"\u7528\u65bc\u6aa2\u6e2c\u6feb\u7528\u3001\u5ee3\u544a\u6b3a\u8a50\u3001Bot \u5075\u6e2c\uff0c\u4ee5\u53ca\u6539\u5584 YouTube \u670d\u52d9\uff08\u5982\u8207\u5f71\u7247\u64ad\u653e\uff0f\u5d4c\u5165\u6709\u95dc\u7684\u5206\u6790\u6216\u554f\u984c\u5075\u6e2c\uff09","typeTitle":"\u6642\u9593 \/ \u985e\u578b","typeDesc":"13 \u500b\u6708"}]},{"title":"meta","text":"https:\/\/www.facebook.com\/privacy\/policy","key":"","state":"","detail":[{"title":"_fbp","text":"\u7528\u65bc\u8fa8\u8b58\u7db2\u7ad9\u8a2a\u5ba2\uff0c\u8b93 Meta \u53ef\u4ee5\u986f\u793a\u76f8\u95dc\u5ee3\u544a\uff08\u518d\u884c\u92b7\u7528\u9014\uff09\u3002","typeTitle":"\u6642\u9593 \/ \u985e\u578b","typeDesc":"90 \u5929"}]},{"title":"instagram","text":"https:\/\/www.instagram.com\/","key":"","state":"","detail":[{"title":"mid","text":"\u7528\u65bc\u5340\u5206\u4e0d\u540c\u7684\u7528\u6236\uff0c\u5354\u52a9 Instagram \u63d0\u4f9b\u500b\u6027\u5316\u7684\u5167\u5bb9\u63a8\u85a6\u3001\u5ee3\u544a\u5c55\u793a\u4ee5\u53ca\u5176\u4ed6\u793e\u4ea4\u5a92\u9ad4\u529f\u80fd\u3002","typeTitle":"\u6642\u9593 \/ \u985e\u578b","typeDesc":"13 \u500b\u6708"}]}]}]}}]}]">
|
|
40
|
+
input(input type="hidden" id="_wcookie" value='')
|
package/src/pages/index.pug
CHANGED
|
@@ -79,7 +79,7 @@ block content
|
|
|
79
79
|
h3 Video4 👇
|
|
80
80
|
.row
|
|
81
81
|
.grid
|
|
82
|
-
.photo-box(video-target video-id="
|
|
82
|
+
.photo-box(video-target video-id="" video-type="youtube")
|
|
83
83
|
picture
|
|
84
84
|
source(srcset="https://cdn.wdd.idv.tw/image/video-cover01.webp" type="image/webp")
|
|
85
85
|
source(srcset="https://cdn.wdd.idv.tw/image/video-cover01.jpg" type="image/jpeg")
|