Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 

355 wiersze
6.5 KiB

  1. const sqData = new Map();
  2. const sq = {
  3. default: function (q) {
  4. const type = typeof(q);
  5. if (type === 'string') {
  6. if (q[0] === '<')
  7. return this.build(q);
  8. return sq.find(q);
  9. } else if (type === 'object')
  10. return sq.wrap([q]);
  11. document.addEventListener('DOMContentLoaded', q, false);
  12. },
  13. build: function (tpl) {
  14. let el = document.createElement('template');
  15. el.innerHTML = tpl.trim();
  16. return sq.wrap([el.content.firstChild]);
  17. },
  18. find: function (queryString) {
  19. if (!this[0])
  20. return sq.wrap(document.querySelectorAll(queryString));
  21. let els = [];
  22. this.each(el => els.push(...el.querySelectorAll(queryString)));
  23. return sq.wrap(els);
  24. },
  25. children: function (filter) {
  26. if (!filter)
  27. return sq.wrap(this[0].children);
  28. return this.find(filter);
  29. },
  30. parent: function () {
  31. let parents = [];
  32. this.each(el => parents.push(el.parentElement));
  33. return sq.wrap(parents);
  34. },
  35. on: function (event, fn, preventDefault) {
  36. let fnHandler = function (fn, el, noDefault, e) {
  37. e.target = el;
  38. requestAnimationFrame(fn.bind(null, e));
  39. if (noDefault) {
  40. e.preventDefault();
  41. return false;
  42. }
  43. };
  44. this.each(el => el.addEventListener(event, fnHandler.bind(null, fn, el, preventDefault)));
  45. return this;
  46. },
  47. off: function () {
  48. let newNodes = [];
  49. this.each(el => {
  50. let newNode = el.cloneNode(true);
  51. el.parentNode.replaceChild(newNode, el);
  52. newNodes.push(newNode);
  53. });
  54. return this.wrap(newNodes);
  55. },
  56. clone: function () {
  57. let newNode = this[0].cloneNode(true);
  58. return this.wrap([newNode]);
  59. },
  60. each: function (fn) {
  61. const len = this.length;
  62. for (let i = 0; i < len; i++)
  63. fn(this[i]);
  64. },
  65. appendTo: function (el) {
  66. if (typeof(el) === 'string')
  67. el = sq.find(el)[0];
  68. else
  69. el = el.on ? el[0] : el;
  70. this.each(c => el.appendChild(c));
  71. return this;
  72. },
  73. prependTo: function (el) {
  74. el[0].insertBefore(this[0], el.children()[0]);
  75. return this;
  76. },
  77. remove: function () {
  78. this.each(el => el.remove());
  79. },
  80. addClass: function (classNames) {
  81. if (classNames)
  82. classNames.split(' ').forEach(c => this.each(el => el.classList.add(c)));
  83. return this;
  84. },
  85. removeClass: function (classNames) {
  86. classNames.split(' ').forEach(c => this.each(el => el.classList.remove(c)));
  87. return this;
  88. },
  89. hasClass: function (className) {
  90. return this[0].classList.contains(className);
  91. },
  92. toggleClass: function (className) {
  93. this.hasClass(className) ? this.removeClass(className) : this.addClass(className);
  94. },
  95. show: function () {
  96. this.each(el => {
  97. if ($(el).css('display') !== 'none')
  98. return;
  99. let newDisplay = el.oldDisplay || 'block';
  100. delete el.oldDisplay;
  101. el.attributeStyleMap.set('display', newDisplay);
  102. });
  103. return this;
  104. },
  105. hide: function () {
  106. this.each(el => {
  107. let oldDisplay = $(el).css('display');
  108. if (oldDisplay !== 'none')
  109. el.oldDisplay = oldDisplay;
  110. el.attributeStyleMap.set('display', 'none');
  111. });
  112. return this;
  113. },
  114. css: function (property, value) {
  115. let config = property;
  116. let aLen = arguments.length;
  117. if (aLen === 1 && typeof(property) === 'string') {
  118. let value = this[0].attributeStyleMap.get(property);
  119. if (!value) {
  120. let styles = this[0].computedStyleMap();
  121. value = (styles.get(property) || {});
  122. }
  123. return value.value;
  124. } else if (aLen === 2) {
  125. config = {
  126. [property]: value
  127. };
  128. }
  129. Object.keys(config).forEach(c => {
  130. let val = config[c];
  131. if (['left', 'top', 'width', 'height'].includes(c) && (!val.indexOf || val.indexOf('%') === -1))
  132. val += 'px';
  133. this.each(el => {
  134. if (val)
  135. el.style[c] = val;
  136. else
  137. el.attributeStyleMap.delete(c);
  138. });
  139. });
  140. return this;
  141. },
  142. empty: function () {
  143. let node = this[0];
  144. while (node.firstChild)
  145. node.removeChild(node.firstChild);
  146. return this;
  147. },
  148. is: function (state) {
  149. return (this.width() && this.height());
  150. },
  151. html: function (val) {
  152. if (!arguments.length)
  153. return this[0].innerHTML;
  154. this[0].innerHTML = val;
  155. return this;
  156. },
  157. click: function () {
  158. this[0].click();
  159. return this;
  160. },
  161. next: function () {
  162. return sq.wrap([this[0].nextSibling]);
  163. },
  164. scrollTop: function (value) {
  165. if (!arguments.length)
  166. return this[0].scrollTop;
  167. this[0].scrollTop = value;
  168. },
  169. val: function (val) {
  170. if (!arguments.length)
  171. return this[0].value;
  172. this[0].value = val;
  173. return this;
  174. },
  175. attr: function (property, value) {
  176. if (arguments.length === 1)
  177. return this[0].getAttribute(property);
  178. this[0].setAttribute(property, value);
  179. return this;
  180. },
  181. insertAfter: function (el) {
  182. el[0].parentNode.insertBefore(this[0], el[0].nextSibling);
  183. return this;
  184. },
  185. insertBefore: function (el) {
  186. el[0].parentNode.insertBefore(this[0], el[0]);
  187. return this;
  188. },
  189. index: function () {
  190. let el = this[0];
  191. return Array.prototype.indexOf.call(el.parentElement.children, el);
  192. },
  193. offset: function () {
  194. return this[0].getBoundingClientRect();
  195. },
  196. data: function (property, value) {
  197. let dataSet = sqData.get(this[0]);
  198. if (!dataSet) {
  199. dataSet = {};
  200. sqData.set(this[0], dataSet);
  201. }
  202. if (arguments.length === 1)
  203. return dataSet[property];
  204. dataSet[property] = value;
  205. return this;
  206. },
  207. removeData: function (property) {
  208. if (this.dataSet)
  209. delete this.dataSet[property];
  210. return this;
  211. },
  212. wrap: function (els) {
  213. let res = {
  214. length: els.length
  215. };
  216. Object.keys(sq)
  217. .forEach(k => res[k] = sq[k].bind(res));
  218. for (let i = 0; i < els.length; i++)
  219. res[i] = els[i];
  220. return res;
  221. },
  222. width: function (val) {
  223. if (val) {
  224. this.css('width', val);
  225. return this;
  226. }
  227. return this[0].offsetWidth;
  228. },
  229. height: function (val) {
  230. if (val) {
  231. this.css('height', val);
  232. return this;
  233. }
  234. return this[0].offsetHeight;
  235. },
  236. eq: function (index) {
  237. return sq.wrap([this[index]]);
  238. },
  239. focus: function () {
  240. this[0].focus();
  241. return this;
  242. },
  243. blur: function () {
  244. this[0].blur();
  245. return this;
  246. },
  247. cloneRecursive: function (o, newO) {
  248. if (typeof o !== 'object')
  249. return o;
  250. if (!o)
  251. return o;
  252. if (o instanceof Array) {
  253. if (!newO || !newO.push)
  254. newO = [];
  255. for (let i = 0; i < o.length; i++)
  256. newO[i] = sq.cloneRecursive(o[i], newO[i]);
  257. return newO;
  258. }
  259. if (!newO || typeof(newO) !== 'object')
  260. newO = {};
  261. for (let i in o) {
  262. if (o.hasOwnProperty(i))
  263. newO[i] = sq.cloneRecursive(o[i], newO[i]);
  264. }
  265. return newO;
  266. },
  267. extend: function (temp, o) {
  268. let aLen = arguments.length;
  269. for (let i = 2; i < aLen; i++)
  270. sq.cloneRecursive(arguments[i], o);
  271. return o;
  272. }
  273. };
  274. window.$ = sq.default.bind(sq);
  275. Object.keys(sq).forEach(k => window.$[k] = sq[k].bind(sq));