12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424 |
- // Generated by CoffeeScript 2.0.0-beta4
- (function() {
- // 主要的選擇器函式。
- var ts;
- ts = function(selector, context) {
- var nodes, ref, tag;
- nodes = [];
- // 如果選擇器是文字,但是是標籤(如:`<div>`)就建立新的元素
- if (typeof selector === 'string' && selector[0] === '<') {
- tag = selector.match(/<(.*)\/>|<(.*)>/);
- nodes = [document.createElement((ref = tag[1]) != null ? ref : tag[2])];
- // 如果選擇器是一般的文字,就選取元素。
- } else if (typeof selector === 'string' && context === void 0) {
- document.querySelectorAll(selector).forEach(function(element) {
- return nodes.push(element);
- });
- // 如果選擇器有上下文選擇器,就透過選擇器找出上下文元素。
- } else if (typeof context === 'string') {
- nodes = ts(selector).find(context).toArray();
- // 如果選擇器是 NodeList 就轉換成元素陣列然後取出來接著繼續。
- } else if (selector instanceof NodeList) {
- selector.forEach(function(element) {
- return nodes.push(element);
- });
- // 如果選擇器是陣列,就當作是元素陣列,取出來然後繼續。
- // 或傳入的是一個選擇器,就取出裡面的元素然後繼續。
- } else if (Array.isArray(selector) || (selector != null ? selector.isSelector : void 0) === true) {
- nodes = nodes.concat(selector);
- selector = selector.selector;
- context = selector != null ? selector.context : void 0;
- // 如果是單個 DOM 元素,就放入選擇器然後繼續。
- } else if (selector instanceof HTMLElement || selector instanceof HTMLDocument || selector instanceof HTMLBodyElement || selector === window) {
- nodes = [selector];
- }
- // 保存目前的選擇器文字與上下文選擇器文字。
- nodes.selector = typeof selector === 'string' ? selector : null;
- nodes.context = typeof context === 'string' ? context : null;
- // 將自訂的選擇器方法插入到節點陣列中,這樣才能夠串連使用。
- Object.defineProperties(nodes, ts.fn);
- // 將節點陣列標註為是選擇器,這樣才能判斷傳入的是不是我們自己的選擇器。
- Object.defineProperty(nodes, 'isSelector', {
- value: true
- });
- return nodes;
- };
- // 註冊到視窗上。
- window.ts = ts;
- // 函式鏈。
- ts.fn = {};
- // 輔助函式。
- ts.helper = {};
- // 事件輔助函式。
- ts.helper.eventAlias = function(event) {
- var alias, pair;
- pair = event.split('.');
- alias = pair[1] !== void 0 ? `.${pair[1]}` : '';
- switch (false) {
- case pair.indexOf('animationend') === -1:
- return `webkitAnimationEnd${alias} mozAnimationEnd${alias} MSAnimationEnd${alias} oanimationend${alias} animationend${alias}`;
- case pair.indexOf('transitionend') === -1:
- return `webkitTransitionEnd${alias} mozTransitionEnd${alias} oTransitionEnd${alias} msTransitionEnd${alias} transitionend${alias}`;
- default:
- return event;
- }
- };
- // 是否為物件。
- ts.isPlainObject = function(object) {
- return Object.prototype.toString.call(object) === '[object Object]';
- };
- // 是否為可觸控裝置。
- ts.isTouchDevice = function() {
- return 'ontouchstart' in window || navigator.maxTouchPoints;
- };
- // 延展物件的函式,與 ES 的 `...` 不同之處在於 extend 並不會替換掉整個子物件,而會以補插的方式執行。
- // https://gomakethings.com/vanilla-javascript-version-of-jquery-extend/
- ts.extend = function() {
- var deep, extended, i, length, merge, obj;
- extended = {};
- deep = true;
- i = 0;
- length = arguments.length;
- if (Object.prototype.toString.call(arguments[0]) === '[object Boolean]') {
- deep = arguments[0];
- i++;
- }
- merge = function(obj) {
- var prop;
- for (prop in obj) {
- if (Object.prototype.hasOwnProperty.call(obj, prop)) {
- if (deep && Object.prototype.toString.call(obj[prop]) === '[object Object]') {
- extended[prop] = ts.extend(true, extended[prop], obj[prop]);
- } else {
- extended[prop] = obj[prop];
- }
- }
- }
- };
- while (i < length) {
- obj = arguments[i];
- merge(obj);
- i++;
- }
- return extended;
- };
- // 建立元素
- ts.createElement = (html) => {
- var div;
- div = document.createElement('div');
- div.innerHTML = html.trim();
- return div.firstChild;
- };
- // 註冊 Tocas 模塊
- ts.register = ({NAME, MODULE_NAMESPACE, Settings}, starter) => {
- return ts.fn[NAME] = {
- value: function(parameters) {
- var $allModules, consoleText, errorHeaderCSS, headerCSS, messageCSS, methodInvoked, query, queryArguments, returnedValue;
- $allModules = ts(this);
- query = arguments[0];
- queryArguments = [].slice.call(arguments, 1);
- methodInvoked = typeof query === 'string';
- returnedValue = void 0;
- consoleText = (args) => {
- //currentdate = new Date();
- //datetime = "#{currentdate.getFullYear()}/#{(currentdate.getMonth()+1)}/#{currentdate.getDate()}/@#{currentdate.getHours()}:#{currentdate.getMinutes()}:#{currentdate.getSeconds()}"
- return `%c${NAME}%c ${args[0]}`;
- };
- headerCSS = "background : #EEE;\ncolor : #5A5A5A;\nfont-size : 1em;\npadding : 8px 8px;\nline-height : 5px;\nmargin : 5px 0 5px 0;\nborder-radius: 1000em;";
- errorHeaderCSS = `${headerCSS}\nbackground: #CE5F58;\ncolor: #FFF;`;
- messageCSS = "font-weight: bold;";
- $allModules.each(function(_, index) {
- var $this, debug, element, error, initialize, instance, instantiate, invoke, module, observeChanges, settings;
- $this = ts(this);
- element = this;
- instance = $this.data(MODULE_NAMESPACE);
- settings = ts.isPlainObject(parameters) ? ts.extend(Settings, parameters) : ts.extend(Settings);
- debug = function() {
- if (!settings.debug || settings.silent) {
- return;
- }
- return console.info.call(console, consoleText(arguments), headerCSS, messageCSS, "\n", ...Array.prototype.slice.call(arguments).slice(1));
- };
- error = function() {
- if (settings.silent) {
- return;
- }
- error = Function.prototype.bind.call(console.error, console, consoleText(arguments), errorHeaderCSS, messageCSS);
- return error.apply(console, Array.prototype.slice.call(arguments, 1));
- };
- instantiate = () => {
- module.instantiate();
- instance = module;
- return $this.data(MODULE_NAMESPACE, instance);
- };
- initialize = () => {
- module.initialize();
- if (settings.observeChanges) {
- observeChanges();
- }
- return instantiate();
- };
- observeChanges = () => {
- var observer;
- if (!'MutationObserver' in window) {
- debug('找不到樹狀結構變更觀測者,略過結構監聽動作', element);
- return;
- }
- observer = new MutationObserver((mutations) => {
- //debug 'DOM 樹狀結構已變更,更新快取資料'
- return module.refresh();
- });
- return observer.observe(element, {
- childList: true,
- subtree: true
- });
- };
- //debug '已設置 DOM 樹狀結構異動觀察者', observer
- invoke = (query, passedArguments, context) => {
- var camelCaseValue, depth, found, j, len, maxDepth, object, response, value;
- object = instance;
- maxDepth = void 0;
- found = void 0;
- response = void 0;
- passedArguments = passedArguments || queryArguments;
- context = element || context;
- if (typeof query === 'string' && object !== void 0) {
- query = query.split(/[\. ]/);
- maxDepth = query.length - 1;
- for (depth = j = 0, len = query.length; j < len; depth = ++j) {
- value = query[depth];
- camelCaseValue = query;
- if (depth !== maxDepth) {
- camelCaseValue = value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1);
- }
- switch (false) {
- case !(ts.isPlainObject(object[camelCaseValue]) && depth !== maxDepth):
- object = object[camelCaseValue];
- break;
- case object[camelCaseValue] === void 0:
- found = object[camelCaseValue];
- break;
- case !(ts.isPlainObject(object[value]) && depth !== maxDepth):
- object = object[value];
- break;
- case object[value] === void 0:
- found = object[value];
- break;
- default:
- error('欲呼叫的方法並不存在', query);
- break;
- }
- }
- }
- switch (false) {
- case typeof found !== 'function':
- response = found.apply(context, passedArguments);
- break;
- case found === void 0:
- response = found;
- }
- switch (false) {
- case response !== $allModules:
- returnedValue = $allModules;
- break;
- default:
- returnedValue = response;
- }
- return found;
- };
- module = starter({$allModules, $this, element, debug, settings, instance, index});
- if (methodInvoked) {
- if (instance === void 0) {
- initialize();
- }
- return invoke(query);
- } else {
- if (instance !== void 0) {
- invoke('destroy');
- }
- return initialize();
- }
- });
- if (returnedValue !== void 0) {
- return returnedValue;
- } else {
- return $allModules;
- }
- }
- };
- };
- // Get
- // 取得選擇器內的指定元素,並且回傳一個 DOM 元素而非選擇器。
- ts.fn.get = {
- value: function(index = 0) {
- return this[index];
- }
- };
- // ToArray
- // 將選擇器轉換成帶有節點的一般陣列。
- ts.fn.toArray = {
- value: function() {
- var array;
- array = [];
- this.forEach(function(element) {
- return array.push(element);
- });
- return array;
- }
- };
- // Each
- // 遍歷整個選擇器陣列。
- ts.fn.each = {
- value: function(callback) {
- this.forEach(function(element, index) {
- return callback.call(element, element, index);
- });
- return this;
- }
- };
- // CollectSwap
- // 將收集到的元素替換掉目前選擇器內的所有元素。
- ts.fn.collectSwap = {
- value: function(callback) {
- var collection, newSelector;
- collection = [];
- this.each(function(element, index) {
- var result;
- result = callback.call(element, element, index);
- if (result === void 0 || result === null) {
- return;
- }
- if (result instanceof NodeList) {
- return result.forEach(function(el) {
- return collection.push(el);
- });
- } else if (Array.isArray(result)) {
- return collection = collection.concat(result);
- } else {
- if (collection.indexOf(result) === -1) {
- return collection.push(result);
- }
- }
- });
- // 透過 Set 型態移除重複的節點。
- collection = new Set(collection);
- // 然後將 Set 轉換成陣列,建立新的選擇器。
- newSelector = ts([...collection]);
- // 保存選擇器之前的所有節點。
- Object.defineProperty(newSelector, 'prevObject', {
- value: this
- });
- // 回傳這個新的選擇器。
- return newSelector;
- }
- };
- // Eq
- // 取得選擇器的指定元素,然後繼續回傳僅帶有該元素的選擇器。
- ts.fn.eq = {
- value: function(index) {
- return ts(this.get(index));
- }
- };
- // Parent
- // 回傳元素的父元素選擇器。
- ts.fn.parent = {
- value: function() {
- return this.collectSwap(function() {
- return this.parentNode;
- });
- }
- };
- // Closest
- // 回傳最接近指定的父元素選擇器。
- ts.fn.closest = {
- value: function(selector) {
- return this.collectSwap(function() {
- return this.closest(selector);
- });
- }
- };
- // Find
- // 在目前元素中搜尋指定元素並回傳其選擇器。
- ts.fn.find = {
- value: function(selector) {
- return this.collectSwap(function() {
- return this.querySelectorAll(selector);
- });
- }
- };
- // Insert Before
- // 將選擇器元素安插在指定元素前。
- ts.fn.insertBefore = {
- value: function(target) {
- return this.each(function() {
- return ts(target).each((element) => {
- return element.parentNode.insertBefore(this, element);
- });
- });
- }
- };
- // Insert After
- // 將選擇器元素安插在指定元素後。
- ts.fn.insertAfter = {
- value: function(target) {
- return this.each(function() {
- return ts(target).each((element) => {
- return element.parentNode.insertBefore(this, element.nextSibling);
- });
- });
- }
- };
- // Wrap
- // 將元素用指定元素包覆起來。
- ts.fn.wrap = {
- value: function(element) {
- return this.each(function() {
- if (this.nextSibling) {
- this.parentNode.insertBefore(element, this.nextSibling);
- } else {
- this.parentNode.appendChild(element);
- }
- return element.appendChild(this);
- });
- }
- };
- // Clone
- // 複製元素。
- ts.fn.clone = {
- value: function() {
- return this.collectSwap(function() {
- return this.cloneNode(true);
- });
- }
- };
- // Append
- // 將元素插入在目前選擇器元素的內部最後面。
- ts.fn.append = {
- value: function(element) {
- var shouldClone;
- shouldClone = this.length !== 1;
- if (element.isSelector !== void 0) {
- return this.each(function() {
- return element.each((e) => {
- return this.appendChild(shouldClone ? e.cloneNode(true) : e);
- });
- });
- } else if (typeof element === 'string') {
- return this.each(function() {
- return this.insertAdjacentHTML('beforeend', element);
- });
- } else {
- return this.each(function() {
- return this.appendChild(shouldClone ? element.cloneNode(true) : element);
- });
- }
- }
- };
- // AppendTo
- // 將目前選擇器元素插入到指定元素的內部最後面。
- ts.fn.appendTo = {
- value: function(selector) {
- return this.each(function() {
- return ts(selector).append(this);
- });
- }
- };
- // Prepend
- // 將元素插入在目前選擇器元素的內部最前面。
- ts.fn.prepend = {
- value: function(element) {
- var shouldClone;
- shouldClone = this.length !== 1;
- if (element.isSelector !== void 0) {
- return this.each(function() {
- return element.each((e) => {
- return this.prepend(shouldClone ? e.cloneNode(true) : e);
- });
- });
- } else if (typeof element === 'string') {
- return this.each(function() {
- return this.insertAdjacentHTML('afterbegin', element);
- });
- } else {
- return this.each(function() {
- return this.prepend(shouldClone ? element.cloneNode(true) : element);
- });
- }
- }
- };
- // PrependTo
- // 將目前選擇器元素插入到指定元素的內部最前面。
- ts.fn.prependTo = {
- value: function(selector) {
- return this.each(function() {
- return ts(selector).prepend(this);
- });
- }
- };
- // Remove
- // 將選擇器元素從頁面上中移除。
- ts.fn.remove = {
- value: function() {
- return this.each(function() {
- var ref;
- return (ref = this.parentNode) != null ? ref.removeChild(this) : void 0;
- });
- }
- };
- // Is
- // 選擇一些元素,然後用來比對目前的選擇器元素是否在這群當中。
- ts.fn.is = {
- value: function(selector) {
- var compareElements, isInElements;
- compareElements = document.querySelectorAll(selector);
- isInElements = false;
- this.each(function() {
- return compareElements.forEach(function(compareElement) {
- if (this === compareElement) {
- return isInElements = true;
- }
- }, this);
- });
- return isInElements;
- }
- };
- // Contains
- // 是否擁有指定子元素。
- ts.fn.contains = {
- value: function(selector) {
- var ref;
- return (ref = this.get(0)) != null ? ref.contains(ts(selector).get()) : void 0;
- }
- };
- // Not
- // 將指定元素從選擇器中剔除。
- ts.fn.not = {
- value: function(selector) {
- return ts(this.toArray().filter((element) => {
- return ts(selector).indexOf(element) === -1;
- }));
- }
- };
- // Slice
- // 替元素陣列進行切分。
- ts.fn.slice = {
- value: function(from, to) {
- return ts(this.toArray().slice(from, to));
- }
- };
- // Children
- // 取得容器裡的第一層子節點。
- ts.fn.children = {
- value: function(selector) {
- return this.collectSwap(function() {
- return this.querySelectorAll(selector != null ? `:scope > ${selector}` : ':scope > *');
- });
- }
- };
- // Replace With
- // 將元素替換為指定選擇器元素。
- ts.fn.replaceWith = {
- value: function(selector) {
- var element;
- element = ts(selector).get();
- return this.each(function() {
- return this.replaceWith(element);
- });
- }
- };
- // Last
- // 選擇器中的最後一個元素。
- ts.fn.last = {
- value: function() {
- return this.eq(this.length - 1);
- }
- };
- // Next
- // 下一個元素。
- ts.fn.next = {
- value: function() {
- return this.collectSwap(function() {
- return this.nextElementSibling;
- });
- }
- };
- // Prev
- // 上一個元素。
- ts.fn.prev = {
- value: function() {
- return this.collectSwap(function() {
- return this.previousElementSibling;
- });
- }
- };
- // NextAll
- // 這個元素之後的所有同階層元素。
- ts.fn.nextAll = {
- value: function(selector) {
- return this.collectSwap(function() {
- var $children, $parent, $self, index;
- $self = ts(this);
- $parent = $self.parent();
- $children = selector != null ? $parent.find(`:scope > ${selector}`) : $parent.find(':scope > *');
- index = $self.index();
- return $children.slice(index + 1);
- });
- }
- };
- // PrevAll
- // 這個元素之前的所有同階層元素。
- ts.fn.prevAll = {
- value: function(selector) {
- return this.collectSwap(function() {
- var $children, $parent, $self, index;
- $self = ts(this);
- $parent = $self.parent();
- $children = selector != null ? $parent.find(`:scope > ${selector}`) : $parent.find(':scope > *');
- index = $self.index();
- return $children.slice(0, index);
- });
- }
- };
- // AddBack
- // 在目前的選擇器節點陣列中加上先前選擇的所有節點。
- ts.fn.addBack = {
- value: function() {
- if (this.prevObject) {
- this.prevObject.toArray().forEach((element) => {
- return this.push(element);
- });
- }
- return this;
- }
- };
- // Index
- // 該元素在容器內的索引。
- ts.fn.index = {
- value: function() {
- var index, node;
- node = this.get(0);
- index = 0;
- if (node == null) {
- return -1;
- }
- while ((node = node.previousElementSibling)) {
- index++;
- }
- return index;
- }
- };
- // Attr
- // 取得或是建立新的標籤到目前的選擇器元素。
- ts.fn.attr = {
- value: function(name, value) {
- var ref;
- // 如果有 value 就設置簡單鍵值資料。
- if (value !== void 0) {
- return this.each(function() {
- return this.setAttribute(name, value);
- });
- // 如果傳入的是物件就設置多重資料。
- } else if (typeof name === 'object') {
- return this.each(function() {
- var key, results;
- results = [];
- for (key in name) {
- results.push(this.setAttribute(key, name[key]));
- }
- return results;
- });
- } else {
- return (ref = this.get()) != null ? ref.getAttribute(name) : void 0;
- }
- }
- };
- // RemoveAttr
- // 移除目前選擇器元素的指定標籤。
- ts.fn.removeAttr = {
- value: function(name) {
- return this.each(function() {
- return this.removeAttribute(name);
- });
- }
- };
- // AddClass
- // 在目前選擇器元素插入新的樣式類別名稱。
- ts.fn.addClass = {
- value: function(names) {
- var name, newNames;
- if (typeof names === 'object') {
- newNames = '';
- for (name in names) {
- if (names[name] === true) {
- newNames += ` ${name}`;
- }
- }
- names = newNames;
- } else {
- names = Array.prototype.slice.call(arguments).join(' ');
- }
- return this.each(function() {
- return DOMTokenList.prototype.add.apply(this.classList, names.split(' ').filter(Boolean));
- });
- }
- };
- // RemoveClass
- // 移除目前選擇器元素的指定樣式類別。
- ts.fn.removeClass = {
- value: function(names) {
- var name, newNames;
- if (typeof names === 'object') {
- newNames = '';
- for (name in names) {
- if (names[name] === true) {
- newNames += ` ${name}`;
- }
- }
- names = newNames;
- } else {
- names = Array.prototype.slice.call(arguments).join(' ');
- }
- //console.log @
- return this.each(function() {
- return DOMTokenList.prototype.remove.apply(this.classList, names.split(' ').filter(Boolean));
- });
- }
- };
- // ToggleClass
- // 切換目前選擇器元素的樣式。
- ts.fn.toggleClass = {
- value: function(names) {
- return this.each(function() {
- return names.split(' ').forEach(function(name) {
- return this.classList.toggle(name);
- }, this);
- });
- }
- };
- // HasClass
- // 回傳選擇器元素是否帶有指定樣式類別,是布林值。
- ts.fn.hasClass = {
- value: function(name) {
- var ref;
- return (ref = this.get(0)) != null ? ref.classList.contains(name) : void 0;
- }
- };
- // CSS
- // 將選擇器元素套用指定的 CSS 樣式。
- ts.fn.css = {
- value: function(name, value) {
- var key;
- // 有 name 也有 value 就設置樣式。
- if (typeof name === 'string' && value !== void 0) {
- return this.each(function() {
- return this.style[name] = value;
- });
- // 有 name 但沒有 value 就取得樣式。
- } else if (typeof name === 'string' && value === void 0) {
- if (this.get() != null) {
- return document.defaultView.getComputedStyle(this.get(), null).getPropertyValue(name);
- } else {
- return null;
- }
- // 有 name 但他是 object,就設置多重樣式。
- } else if (typeof name === 'object') {
- for (key in name) {
- this.each(function() {
- return this.style[key] = name[key];
- });
- }
- return this;
- }
- }
- };
- // Rect
- // 回傳選擇器元素的渲染形狀。
- ts.fn.rect = {
- value: function() {
- var ref;
- return (ref = this.get(0)) != null ? ref.getBoundingClientRect() : void 0;
- }
- };
- // On
- // 綁定並註冊一個事件監聽器。
- ts.fn.on = {
- value: function() {
- var data, events, handler, options, selector;
- switch (arguments.length) {
- // Event 與 Handler。
- case 2:
- events = arguments[0];
- handler = arguments[1];
- break;
- // Event 與 Selector 與 Handler。
- // Event 與 Data 與 Handler。
- // Event 與 Handler 與 Options。
- case 3:
- events = arguments[0];
- handler = arguments[2];
- switch (typeof arguments[1]) {
- case "string":
- selector = arguments[1];
- break;
- case "function":
- handler = arguments[1];
- options = arguments[2];
- break;
- default:
- data = arguments[1];
- }
- break;
- // Event 與 Selector 與 Data 與 Handler。
- // Event 與 Selector 與 Handler 與 Options。
- case 4:
- events = arguments[0];
- selector = arguments[1];
- handler = arguments[3];
- switch (typeof arguments[2]) {
- case "function":
- handler = arguments[2];
- options = arguments[3];
- break;
- default:
- data = arguments[2];
- }
- break;
- // Event 與 Selector 與 Data 與 Handler 與 Options。
- case 5:
- events = arguments[0];
- selector = arguments[1];
- data = arguments[2];
- handler = arguments[3];
- options = arguments[4];
- }
- events = ts.helper.eventAlias(events);
- // $events.click =
- // {
- // anonymous: [
- // {
- // once : true,
- // selector: ".button",
- // data : {},
- // func : func()
- // }
- // ]
- // alias1: [
- // {
- // once : true,
- // selector: ".button",
- // data : {},
- // func : func()
- // }
- // ]
- // }
- return this.each(function() {
- if (this.addEventListener === void 0) {
- return;
- }
- if (this.$events === void 0) {
- this.$events = {};
- }
- return events.split(' ').forEach(function(eventName) {
- var event, eventAlias, hasAlias;
- event = eventName.split('.');
- // 透過事件的「event.alias」取得「點」後面的別名。
- hasAlias = event.length > 1;
- eventName = event[0];
- eventAlias = hasAlias ? event[1] : null;
- // 如果事件還沒在這個物件內產生過,就初始化一個事件結構。
- if (this.$events[eventName] === void 0) {
- this.$events[eventName] = {
- anonymous: []
- };
- // 然後建立一個管理多個事件的事件管理處理程式。
- this.addEventListener(eventName, function(event) {
- var alias, calledAlias, closest, context, hasArgs, index, ref, ref1, ref2, results, single;
- // 是否有自訂參數。
- hasArgs = ((ref = event.detail) != null ? (ref1 = ref.args) != null ? ref1.length : void 0 : void 0) > 0;
- // 是否有呼叫事件別名。
- calledAlias = (ref2 = event.detail) != null ? ref2.alias : void 0;
- // 如果該事件已經被移除則停止後續的反應。
- if (this.$events[eventName] === void 0) {
- return;
- }
- results = [];
- // 將被觸發的事件裡面的所有處理程式全部呼叫一次。
- for (alias in this.$events[eventName]) {
- if (calledAlias && calledAlias !== alias) {
- continue;
- }
- index = this.$events[eventName][alias].length;
- results.push((function() {
- var results1;
- results1 = [];
- while (index--) {
- if (this.$events[eventName] === void 0) {
- continue;
- }
- if (this.$events[eventName][alias] === void 0) {
- continue;
- }
- single = this.$events[eventName][alias][index];
- // 設置事件的上下文。
- context = this;
- // 如果這個事件有選擇器的話,則使用該選擇器為主。
- if (single.selector !== void 0) {
- selector = single.selector;
- closest = ts(event.target).closest(selector);
- // 如果找不到指定選擇棄的元素,就不要觸發此事件。
- if (closest.length === 0) {
- continue;
- } else {
- // 替換上下文為選擇器元素。
- context = closest.get();
- }
- }
- // 將事件預資料放入事件中供處理函式取得。
- event.data = single.data;
- if (hasArgs) {
- single.func.call(context, event, ...event.detail.args);
- } else {
- single.func.call(context, event);
- }
- // 如果這個程式只能被呼叫一次就在處理程式呼叫後移除。
- if (single.once === true) {
- results1.push(this.$events[eventName][alias].splice(index, 1));
- } else {
- results1.push(void 0);
- }
- }
- return results1;
- }).call(this));
- }
- return results;
- });
- }
- // 將新的事件處理程式註冊到事件清單中。
- // 如果有別名,就不要推送到匿名陣列中,我們替這個別名另開物件。
- if (hasAlias) {
- if (this.$events[eventName][eventAlias] === void 0) {
- this.$events[eventName][eventAlias] = [];
- }
- return this.$events[eventName][eventAlias].push({
- func: handler,
- selector: selector,
- data: data,
- once: options != null ? options.once : void 0
- });
- } else {
- // 如果沒有,就照常推進匿名陣列中。
- return this.$events[eventName].anonymous.push({
- func: handler,
- selector: selector,
- data: data,
- once: options != null ? options.once : void 0
- });
- }
- }, this);
- });
- }
- };
- // One
- // 綁定一次性的事件監聽器,當被觸發之後就會被移除。
- ts.fn.one = {
- value: function(events, handler) {
- events = ts.helper.eventAlias(events);
- return this.each(function() {
- return ts(this).on(events, handler, {
- once: true
- });
- });
- }
- };
- // Off
- // 註銷事件監聽器。
- ts.fn.off = {
- value: function(events, handler) {
- events = ts.helper.eventAlias(events);
- return this.each(function() {
- if (this.$events === void 0) {
- return;
- }
- return events.split(' ').forEach((eventName) => {
- var alias, aliasName, event, hasAlias, isAlias, results;
- // 將事件名稱由中間的「.」切成兩半。
- event = eventName.split('.');
- // 如果事件開頭是「.」符號,表示這是個別名,不是事件名稱。
- isAlias = eventName[0] === '.';
- // 如果事件分切後有兩個項目,表示這個事件有別名。
- hasAlias = event.length === 2 && event[0] !== '';
- if (hasAlias || isAlias) {
- // 如果有別名的話,取得別名。
- aliasName = event[1];
- }
- // 如果此事件不是只有別名的話,取得事件名稱。
- eventName = !isAlias ? event[0] : void 0;
- switch (false) {
- // 當有指定監聽函式時。
- case !(handler !== void 0 && this.$events[eventName] !== void 0):
- return this.$events[eventName].anonymous.forEach((item, index) => {
- if (handler === item.func) {
- return this.$events[eventName].anonymous.splice(index, 1);
- }
- });
- // 當本事件名稱不僅是別名時。
- case !(!isAlias && hasAlias && this.$events[eventName] !== void 0):
- // 移除指定事件的別名監聽函式。
- return delete this.$events[eventName][aliasName];
- // 當僅有指定別名時。
- case !(isAlias && !hasAlias):
- results = [];
- // 移除所有與此別名有關的事件監聽器。
- for (event in this.$events) {
- results.push((function() {
- var results1;
- results1 = [];
- for (alias in this.$events[event]) {
- if (aliasName === alias) {
- results1.push(delete this.$events[event][aliasName]);
- } else {
- results1.push(void 0);
- }
- }
- return results1;
- }).call(this));
- }
- return results;
- break;
- // 當僅有指定事件名稱時。
- case this.$events[eventName] === void 0:
- // 清空該事件的所有事件監聽器。
- return delete this.$events[eventName];
- }
- }, this);
- });
- }
- };
- // Trigger
- // 觸發指定事件。
- ts.fn.trigger = {
- value: function(events) {
- var customArguments;
- events = ts.helper.eventAlias(events);
- customArguments = [].slice.call(arguments, 1);
- return this.each(function() {
- return events.split(' ').forEach((eventName) => {
- var alias, event, name;
- event = eventName.split('.');
- name = event[0];
- alias = event.length > 1 ? event[1] : null;
- event = new CustomEvent(name, {
- detail: {
- args: customArguments,
- alias: alias
- }
- });
- return this.dispatchEvent(event);
- });
- });
- }
- };
- // Emulate
- // 在指定的秒數過後觸發指定事件,若已被觸發則不再次觸發。
- // 這能用以強迫讓某個事件發生。
- ts.fn.emulate = {
- value: function(event, duration) {
- return this.each(function() {
- var called;
- called = false;
- ts(this).one(event, function() {
- return called = true;
- });
- return setTimeout(() => {
- if (!called) {
- return ts(this).trigger(event);
- }
- }, duration);
- });
- }
- };
- // Text
- // 變更或取得選擇器元素的內容文字。
- ts.fn.text = {
- value: function(text) {
- var ref;
- if (text !== void 0) {
- return this.each(function() {
- return this.innerText = text;
- });
- } else {
- return (ref = this.get()) != null ? ref.innerText : void 0;
- }
- }
- };
- // Val
- // 變更或取得選擇器元素的值。
- ts.fn.val = {
- value: function(value) {
- var ref;
- if (value !== void 0) {
- return this.each(function() {
- return this.value = value;
- });
- } else {
- return (ref = this.get()) != null ? ref.value : void 0;
- }
- }
- };
- // HTML
- // 變更或取得選擇器元素的 HTML。
- ts.fn.html = {
- value: function(html) {
- var ref;
- if (html !== void 0) {
- return this.each(function() {
- return this.innerHTML = html;
- });
- } else {
- return (ref = this.get()) != null ? ref.innerHTML : void 0;
- }
- }
- };
- // Empty
- // 將選擇器元素的內容清除,例如值或文字。
- ts.fn.empty = {
- value: function() {
- return this.each(function() {
- if (this.value !== void 0) {
- this.value = null;
- }
- if (this.innerHTML !== void 0) {
- this.innerHTML = null;
- }
- if (this.innerText !== void 0) {
- return this.innerText = null;
- }
- });
- }
- };
- // Prop
- // 變更或取得選擇器元素的屬性,例如 `.src`、`.width`。
- ts.fn.prop = {
- value: function(name, value) {
- var key, ref;
- // 有 name 也有 value 就設置屬性。
- if (typeof name === 'string' && value !== void 0) {
- return this.each(function() {
- return this[name] = value;
- });
- // 有 name 但沒有 value 就取得屬性。
- } else if (typeof name === 'string' && value === void 0) {
- return (ref = this.get()) != null ? ref[name] : void 0;
- // 有 name 但他是 object,就設置多重屬性。
- } else if (typeof name === 'object') {
- for (key in name) {
- this.each(function() {
- return this[key] = name[key];
- });
- }
- return this;
- }
- }
- };
- // Data
- // 在選擇器元素中存放資料,類似 Attr 但頁面不可見。
- ts.fn.data = {
- value: function(name, value) {
- var key, ref, ref1;
- // 有 name 也有 value 就設置資料。
- if (typeof name === 'string' && value !== void 0) {
- return this.each(function() {
- if (this.$data === void 0) {
- this.$data = {};
- }
- return this.$data[name] = value;
- });
- // 有 name 但沒有 value 就取得資料。
- } else if (typeof name === 'string' && value === void 0) {
- return (ref = this.get()) != null ? (ref1 = ref.$data) != null ? ref1[name] : void 0 : void 0;
- // 有 name 但他是 object,就設置多重樣式。
- } else if (typeof name === 'object') {
- for (key in name) {
- this.each(function() {
- if (this.$data === void 0) {
- this.$data = {};
- }
- return this.$data[key] = name[key];
- });
- }
- return this;
- }
- }
- };
- // Remove Data
- // 移除指定的資料。
- ts.fn.removeData = {
- value: function(name) {
- return this.each(function() {
- if (this.$data[name] != null) {
- return delete this.$data[name];
- }
- });
- }
- };
- // Has Timer
- // 確認是否有指定的計時器。
- ts.fn.hasTimer = {
- value: function(name) {
- var ref, ref1;
- return ((ref = this.get(0)) != null ? (ref1 = ref.$timers) != null ? ref1[name] : void 0 : void 0) != null;
- }
- };
- // Get Timer
- // 取得計時器內容。
- ts.fn.getTimer = {
- value: function(name) {
- var ref, ref1;
- return (ref = this.get(0)) != null ? (ref1 = ref.$timers) != null ? ref1[name] : void 0 : void 0;
- }
- };
- // Set Timer
- // 設置一個新的計時器。
- ts.fn.setTimer = {
- value: function(options) {
- options = Object.assign({}, {
- name: '',
- callback: function() {},
- interval: 0,
- looping: false,
- visible: false
- }, options);
- return this.each(function() {
- var timer;
- if (this.$timers === void 0) {
- this.$timers = {};
- }
- if (this.$timers[options.name] !== void 0) {
- clearInterval(this.$timers[options.name].timer);
- }
- timer = () => {
- var ref;
- // 當設置有說明,頁面不可見的時候就不要繼續計時。
- if (options.visible && document.hidden) {
- return;
- }
- // 替計時器加上 10 毫秒。
- this.$timers[options.name].passed += 10;
- // 如果計時器的經過時間還不到使用者設定的時間
- // 就返回而不要繼續執行。
- if (this.$timers[options.name].passed < options.interval) {
- return;
- }
- // 呼叫回呼函式。
- options.callback();
- // 如果要循環的話,就在計時器執行後重設時間即可。
- if (options.looping) {
- return this.$timers[options.name].passed = 0;
- } else {
- // 不然就移除計時器資訊。
- return clearInterval((ref = this.$timers[options.name]) != null ? ref.timer : void 0);
- }
- };
- // 移除在 DOM 元素內的這個計時器物件。
- //delete @$timers[options.name]
- // 在此元素內初始化計時器物件。
- return this.$timers[options.name] = {
- timer: setInterval(timer, 10),
- passed: 0,
- callback: options.callback,
- interval: options.interval,
- looping: options.looping,
- visible: options.visible,
- initializer: timer,
- paused: false
- };
- });
- }
- };
- // Pause Timer
- // 暫停一個計時器。
- ts.fn.pauseTimer = {
- value: function(name) {
- return this.each(function() {
- var ref;
- if (((ref = this.$timers) != null ? ref[name] : void 0) == null) {
- return;
- }
- // 清除計數計時器達到暫停效果。
- clearInterval(this.$timers[name].timer);
- // 表示暫停。
- return this.$timers[name].paused = true;
- });
- }
- };
- // Play Timer
- // 重啟一個計時器。
- ts.fn.playTimer = {
- value: function(name) {
- return this.each(function() {
- var ref;
- if (((ref = this.$timers) != null ? ref[name] : void 0) == null) {
- return;
- }
- if (!this.$timers[name].paused) {
- return;
- }
- // 重新初始化計數計時器來達到繼續的效果。
- this.$timers[name].timer = setInterval(this.$timers[name].initializer, 10);
- // 表示重新啟動。
- return this.$timers[name].paused = false;
- });
- }
- };
- // Remove Timer
- // 移除一個計時器。
- ts.fn.removeTimer = {
- value: function(name) {
- return this.each(function() {
- var ref;
- if (((ref = this.$timers) != null ? ref[name] : void 0) == null) {
- return;
- }
- // 清除計數計時器。
- clearInterval(this.$timers[name].timer);
- // 移除在 DOM 元素內的計時器物件。
- return delete this.$timers[name];
- });
- }
- };
- // Repaint
- // 讓瀏覽器重繪元素。
- ts.fn.repaint = {
- value: function() {
- return this.each(function() {
- return void(this.offsetHeight);
- });
- }
- };
- }).call(this);
|