PageSourceSearch

http://www.thetileapp.com.tw/assets/js/main.js?r=210219

js thetileapp.com.tw collected 2026-10-07 04:05:40 UTC 17,450 bytes, 500 lines download raw bytes

1(function () {
2    if (typeof NodeList.prototype.forEach === "function")
3        return false;
4    else
5        NodeList.prototype.forEach = Array.prototype.forEach;
6})();
7$(function () {
8    $().UItoTop({
9        easingType: 'easeOutQuart'
10    });
11    $('img[usemap]').rwdImageMaps();
12    $('ul.dropdown-menu [data-toggle=dropdown]').on('click', function (event) {
13        // Avoid following the href location when clicking
14        event.preventDefault();
15        // Avoid having the menu to close when clicking
16        event.stopPropagation();
17        // If a menu is already open we close it
18        $('ul.dropdown-menu [data-toggle=dropdown]').parent().removeClass('open');
19        // opening the one you clicked on
20        $(this).parent().addClass('open');
21    });
22    var swiper = new Swiper('.swiper-container', {
23        slidesPerView: 1,
24        spaceBetween: 0,
25        preloadImages: false,
26        lazy: {
27            loadPrevNext: true
28        },
29        loop: true,
30        pagination: {
31            el: '.swiper-pagination',
32            clickable: true,
33        },
34        navigation: {
35            nextEl: '.swiper-button-next',
36            prevEl: '.swiper-button-prev',
37        },
38        autoplay: {
39            delay: 5000,
40        },
41    });
42    $('.js-lazyYT').lazyYT();
43    /* $('img.lazy').lazyload({
44        threshold: 30,
45        effect: "fadeIn"
46    }); */
47    /*商品搜尋*/
48    $('.my_search').click(function () {
49        $('#menu_bar').hide();
50        $('#search_bar').show();
51    });
52    $('.icon-line-circle-cross').click(function () {
53        $('#search_bar').hide();
54        $('#menu_bar').show();
55    });
56    $('.search_popup').click(function () {
57        link = $(this).attr("data-href");
58        $.magnificPopup.open({
59            items: {
60                src: $(link)
61            },
62            type: 'inline',
63            removalDelay: 300,
64            mainClass: 'mfp-fade',
65            closeOnContentClick: false,
66            fixedContentPos: true
67        });
68    });
69    /*商品搜尋 END*/
70    /*form validate*/
71    (function(){
72        var error_msg = "";
73        var tw = {
74            errorTitle: '表單提示訊息',
75            requiredFields: "請填寫必填欄位",
76            badEmail: "email格式有誤"
77        };
78        $.formUtils.addValidator({
79            name : 'namelimit',
80            validatorFunction : function(value, $el, config, language, $form) {
81                var isValid = !!(String(value).match(/^[a-zA-Z-\u0020]+$|^[\u4e00-\u9fa5]{2,}$/g));
82                return isValid;
83            },
84            errorMessage : "姓名須輸入中文 (至少兩個字) 或英文(可包含半形空白及-),請勿中文與英文相參",
85            errorMessageKey: 'namelimit'
86        });
87        $.validate({
88            language: tw,
89            errorMessagePosition: 'top',
90            errorMessageClass: 'form_error',
91            validateOnBlur: false,
92            validationRuleAttribute: 'datavalidation',
93            scrollToTopOnError: false,
94            onError: function ($form) {
95                alert(error_msg);
96                error_msg = "";
97            },
98            onSuccess: function ($form) {
99                if ($form.data('send-confirm')) {
100                    if (!confirm($form.data('send-confirm'))) {
101                        return false;
102                    }
103                    var cb = $form.data('callback');
104                    if ($.isFunction(window[cb])) {
105                        window[cb].call($form);
106                    }
107                }
108            },
109            inlineErrorMessageCallback: function ($input, errorMessage, config) {
110                return false;
111            },
112            submitErrorMessageCallback: function ($input, errorMessage, config) {
113                if (errorMessage.length > 0) {
114                    error_msg = (errorMessage.map(function (txt){
115                        return "*" + txt;
116                    })).join("\n");
117                }
118                return false;
119            }
120        });
121    })();
122    /*form validate END*/
123});
124/*overlay*/
125var overlay = function () {
126    if (!(this instanceof overlay)) {
127        return new overlay();
128    }
129    return this;
130};
131overlay.prototype.show = function (params) {
132    var visited = false;
133    if (params.chk_cookie) {
134        visited = $.cookie(params.cookie.name) == null ? false : true;
135    }
136    if (!visited) {
137        if (this.date_range_check(params.pre_date_range, params.post_date_range)) {
138            params.ele.popup({
139                autoopen: true,
140                opacity: 0.6,
141                transition: 'all 0.5s'
142            });
143            $.cookie(params.cookie.name, "1", {
144                path: '/',
145                expires: params.cookie.expires,
146                domain: params.cookie.domain
147            });
148        }
149    }
150};
151overlay.prototype.date_range_check = function (pre_date_range, post_date_range) {
152    var nowDate = Date.parse((new Date()).toDateString());
153    var pre_con = ((nowDate >= Date.parse(pre_date_range.startDate)) && (nowDate <= Date.parse(pre_date_range.endDate)));
154    var post_con = ((nowDate >= Date.parse(post_date_range.startDate)) && (nowDate <= Date.parse(post_date_range.endDate)));
155    return (pre_con || post_con);
156};
157/*overlay END*/
158/*snack bar*/
159var snackbar = function (txt) {
160    if (!(this instanceof snackbar)) {
161        return new snackbar(txt);
162    }
163    this.ele = $('#snackbar');
164    this.show_txt = txt;
165    return this;
166};
167snackbar.prototype.show = function (class_name) {
168    var close_this = this;
169    this.ele.html(this.show_txt).toggleClass("show " + class_name);
170    setTimeout(function () {
171        close_this.ele.toggleClass("show " + class_name);
172    }, 3000);
173};
174/*snack bar END*/
175/*cart*/
176var cart = function (ele) {
177    if (!(this instanceof cart)) {
178        return new cart(ele);
179    }
180    this.ele = ele;
181    return this;
182};
183cart.prototype.add = function (ele, rest_url, callback) {
184    $.post(rest_url, {
185        id: ele.attr('data-cart-add')
186    }, function (response) {
187        var json = $.parseJSON(response);
188        snackbar(json.title).show();
189        if ($.isFunction(callback)) {
190            callback.apply(json);
191        }
192    });
193};
194cart.prototype.delete = function (ele, rest_url, callback) {
195    if (confirm('確定移除該商品嗎?')) {
196        $.post(rest_url, {
197            id: ele.attr('data-cart-del')
198        }, function (response) {
199            var json = $.parseJSON(response);
200            snackbar(json.title).show();
201            if ($.isFunction(callback)) {
202                callback.apply(json);
203            }
204        });
205    }
206};
207cart.prototype.update_total = function (rest_url, callback) {
208    $.post(rest_url, function (response) {
209        var json = $.parseJSON(response);
210        $('[data-cart-total]').html(Object.keys(json).length);
211        window.cart_data$ = json;
212        if ($.isFunction(callback)) {
213            callback.apply(json);
214        }
215    });
216};
217cart.prototype.update_quantity = function (ele, rest_url, callback) {
218    $.post(rest_url, {
219        id: ele.attr('data-cart-quantity-chg'),
220        val: ele.val()
221    }, function (response) {
222        var json = $.parseJSON(response);
223        if ($.isFunction(callback)) {
224            callback.apply(json);
225        }
226    });
227};
228cart.prototype.order_price = function (rest_url) {
229    $.post(rest_url, function (response) {
230        var json = $.parseJSON(response);
231        $('[data-cart-order-price]').html($.number(json.order_price));
232        $('[data-cart-shipment]').html($.number(json.shipment));
233        $('[data-cart-total-price]').html($.number(json.total_price));
234        if ($.trim(json.offer_des) != '') {
235            $('[data-offer-now]').html('<i class="icon-bolt"></i>符合活動條件:<br>&emsp;' + json.offer_des + '<br>');
236        } else {
237            $('[data-offer-now]').html('');
238        }
239        /* (function () {
240            var $gifts_num = Object.keys(json.gifts).length, $offer_gift_container = $('[data-offer-gifts]');
241            if ($gifts_num > 0 && $offer_gift_container != undefined) {
242                var des$ = [];
243                des$.push(div('<i class="icon-bolt"></i>贈品:'));
244                $.each(json.gifts, function (title, gift) {
245                    des$.push(div('&emsp;【' + title + '】 ' + Object.keys(gift)[0] + ' x ' + Object.values(gift)[0]));
246                });
247                $offer_gift_container.html(fragmentAppend(des$));
248            } else {
249                $offer_gift_container.html('');
250            }
251        })(); */
252        (function () {
253            var $offer_discount_container = $('[data-offer-discount]'), $offer_discount_add = $('[data-cart-offer-discount-code-add]'), $offer_discount_del = $('[data-cart-offer-discount-code-del]');
254            if (!!json.offer_discount.code) {
255                $offer_discount_del.show();
256                $offer_discount_add.hide();
257            } else {
258                $offer_discount_del.hide();
259                $offer_discount_add.show();
260            }
261            var el$ = $('#offer_discount_code');
262            if (!!json.offer_discount.code && !!$offer_discount_container) {
263                var des$ = [];
264                el$.attr('readonly', true).val(json.offer_discount.code);
265                des$.push(div('<i class="icon-bolt"></i>代碼折扣:【' + json.offer_discount.offer_name + '】'));
266                if (json.offer_discount.list.length > 0) {
267                    $.each(json.offer_discount.list, function (idx$, data$) {
268                        des$.push(div('&emsp;【' + data$.name + ' / ' + data$.color + '】 ' + ' 原售價:$' + $.number(data$.price) + ' x ' + data$.quantity + ',共折扺 $' + $.number(data$.total_discount) + ',小計 $' + $.number(data$.after_discount)));
269                    });
270                } else {
271                    des$.push(div('&emsp;購物車中未有符合此優惠商品'));
272                }
273                $offer_discount_container.html(fragmentAppend(des$));
274            } else {
275                el$.val('').attr('readonly', false);
276                $offer_discount_container.html('');
277            }
278        })();
279        (function () {
280            var $container = $('[data-full-code-container]'), $full_code_add = $('[data-cart-full-code-add]'), $full_code_del = $('[data-cart-full-code-del]');
281            if (json.full_code.activity.length > 0) {
282                $full_code_del.show();
283                $full_code_add.hide();
284            } else {
285                $full_code_del.hide();
286                $full_code_add.show();
287            }
288            var el$ = $('#full_code');
289            if (json.full_code.activity.length > 0 && !!$container) {
290                var $activity = json.full_code.activity[0];
291                var des$ = [];
292                el$.attr('readonly', true).val($activity.code);
293                des$.push(div('<i class="icon-bolt"></i>代碼折扣:【' + $activity.title + '】&nbsp;滿&nbsp;$' + $.number($activity.full_amount) + '&nbsp;折&nbsp;$' + $.number($activity.discount) + (!!!json.full_code.fulfill ? '&emsp;<span class="bg-danger text-danger" style="padding:5px;"><i class="fa fa-info-circle"></i>&nbsp;尚未達到滿額門檻</span>' : '&emsp;<span class="bg-success text-success" style="padding:5px;"><i class="fa fa-check-circle"></i>&nbsp;已符合</span>')));
294                $container.html(fragmentAppend(des$));
295            } else {
296                el$.val('').attr('readonly', false);
297                $container.html('');
298            }
299        })();
300    });
301};
302cart.prototype.reset = function (rest_url, callback) {
303    if (confirm('確定清空購物車嗎?')) {
304        $.post(rest_url, function (response) {
305            if ($.isFunction(callback)) {
306                callback.apply();
307            }
308        });
309    }
310};
311cart.prototype.offer_discount_code_add = function (ele, rest_url, callback) {
312    var code$ = ele.val().trim();
313    if (code$ == '') {
314        return;
315    }
316    $.post(rest_url, {
317        act: 'add',
318        code: code$
319    }, function (response) {
320        if (response.status == 'success') {
321            snackbar('成功使用代碼').show();
322        } else {
323            snackbar('代碼無效').show();
324        }
325        if ($.isFunction(callback)) {
326            callback.apply();
327        }
328    });
329};
330cart.prototype.offer_discount_code_del = function (ele, rest_url, callback) {
331    $.post(rest_url, {
332        act: 'del'
333    }, function (response) {
334        snackbar('已取消代碼').show();
335        if ($.isFunction(callback)) {
336            callback.apply();
337        }
338    });
339};
340cart.prototype.full_code_add = function (ele, rest_url, callback) {
341    var code$ = ele.val().trim();
342    if (code$ == '') {
343        return;
344    }
345    $.post(rest_url, {
346        act: 'add',
347        code: code$
348    }, function (response) {
349        if (response.msg.trim() != '') {
350            snackbar(response.msg).show();
351        }
352        if ($.isFunction(callback)) {
353            callback.apply();
354        }
355    });
356};
357cart.prototype.full_code_del = function (ele, rest_url, callback) {
358    $.post(rest_url, {
359        act: 'del'
360    }, function (response) {
361        snackbar('已取消代碼').show();
362        if ($.isFunction(callback)) {
363            callback.apply();
364        }
365    });
366};
367$('._popup').click(function () {
368    link = $(this).attr("data-href");
369    $.magnificPopup.open({
370        items: {
371            src: $(link)
372        },
373        type: 'inline',
374        removalDelay: 300,
375        mainClass: 'mfp-fade',
376        closeOnContentClick: false,
377        fixedContentPos: true
378    });
379});
380
381/*cart END*/
382function fragmentAppend(nodes$) {
383    var nodes$ = nodes$ || [], frag = document.createDocumentFragment();
384    nodes$.forEach(function (node$) {
385        frag.appendChild(node$);
386    });
387    return frag;
388}
389function div(content$) {
390    var wrap = document.createElement('div');
391    //wrap.append(content$);
392    wrap.innerHTML = content$;
393    return wrap;
394}
395function dropdown_close() {
396    $('.navbar-collapse').toggleClass('in');
397}
398CSSPlugin.defaultForce3D = true;
399var _controller = new ScrollMagic.Controller();
400function splitText(phrase, container) {
401    var prevLetter, offsetLeft = 0, sentence,
402        sentence = phrase.split(""), fragment = document.createDocumentFragment();
403    sentence.forEach(function (_w, _id) {
404        if (_w === " ") _w = "&nbsp;";
405        var n = document.createElement('span');
406        n.className = "txt";
407        n.innerHTML = _w;
408        fragment.appendChild(n);
409        /* if (prevLetter) {
410            offsetLeft += prevLetter.offsetWidth;
411            n.style.left = offsetLeft + 'px';
412        }
413        prevLetter = n; */
414        n.style.display = "inline-block";
415    });
416    container.appendChild(fragment);
417}
418function getTweenTxt(_wrapId) {
419    var _eles = document.querySelectorAll("#" + _wrapId + " noscript[data-for]");
420    if (!_eles) return;
421    _eles.forEach(function (_ele) {
422        var _for = _ele.dataset.for;
423        splitText(_ele.innerText, document.getElementById(_for));
424    });
425    return document.querySelectorAll("#" + _wrapId + " .txt");
426}
427function flyTxt(_s) {
428    return function (_wrapId) {
429        var _timeline = new TimelineMax({ yoyo: true }),
430            _txt = getTweenTxt(_wrapId);
431        _timeline.staggerFrom(_txt, _s, { autoAlpha: 0 }, 0.05, _wrapId)
432            .staggerFrom(_txt, _s + 0.3, { rotationY: "-270deg", top: 50, transformOrigin: "50% 50% -50", ease: Back.easeOut }, 0.05, _wrapId);
433        return _timeline;
434    };
435}
436function typeTxt(_s) {
437    return function (_wrapId) {
438        var _timeline = new TimelineMax(),
439            _txt = getTweenTxt(_wrapId);
440        _timeline.staggerFrom(_txt, _s, { autoAlpha: 0 }, 0.06, _wrapId);
441        return _timeline;
442    };
443}
444function alpha(_s) {
445    return function (_wrapId) {
446        return TweenMax.from(document.getElementById(_wrapId), _s, { autoAlpha: 0 });
447    };
448}
449function fromTo(_s, _from, _to) {
450    return function (_wrapId) {
451        return TweenMax.fromTo(document.getElementById(_wrapId), _s, _from, _to);
452    };
453}
454function tweenObserve(_ids, _tweenF) {
455    if (typeof _tweenF != 'function') return;
456    _ids.forEach(function (_id) {
457        new ScrollMagic.Scene({
458            triggerElement: document.getElementById(_id),
459            triggerHook: 'onEnter'
460        }).setTween(_tweenF(_id)).addTo(_controller);
461    });
462}
463document.addEventListener("DOMContentLoaded", function (event) {
464    _wHeight = window.innerHeight,
465        _wWidth = window.innerWidth;
466    window.addEventListener("resize", debounce(function (e) {
467        _wHeight = window.innerHeight;
468        _wWidth = window.innerWidth;
469    }, 200));
470});
471function debounce(fn, delay) {
472    var timer = null;
473    return function () {
474        var t = this, args = arguments;
475        clearTimeout(timer);
476        timer = setTimeout(function () {
477            fn.apply(t, args);
478        }, delay);
479    }
480}
481Function.prototype._before = function (func) {
482    var self$ = this;
483    return function () {
484        if (func.apply(self$, arguments) === false) {
485            return false;
486        }
487        return self$.apply(self$, arguments);
488    }
489}
490Function.prototype._after = function (func) {
491    var self$ = this;
492    return function () {
493        var ret = self$.apply(self$, arguments);
494        if (ret === false) {
495            return false;
496        }
497        func.apply(self$, arguments);
498        return ret;
499    }
500}

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.