Underdollar jQuery replacement

Replaces jQuery, which causes lots of conflicts, with a framework that is largely cross-compatible

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/37273/246089/Underdollar%20jQuery%20replacement.js

  1. // ==UserScript==
  2. // @name Underdollar jQuery replacement
  3. // @namespace https://greasyfork.org
  4. // @include https://sellers.shopgoodwill.com/*
  5. // @version 1.1
  6. // @description Replaces jQuery, which causes lots of conflicts, with a framework that is largely cross-compatible
  7. // @grant none
  8. // ==/UserScript==
  9.  
  10. console.log('ostrich');
  11.  
  12. class underdollar {
  13. constructor(selector) {
  14. this.is_$ = true;
  15. var singleNode = (function () {
  16. // make an empty node list to inherit from
  17. var nodelist = document.createDocumentFragment().childNodes;
  18. // return a function to create object formed as desired
  19. return function (node) {
  20. return Object.create(nodelist, {
  21. '0': {value: node, enumerable: true},
  22. 'length': {value: 1},
  23. 'item': {
  24. "value": function (i) {
  25. return this[+i || 0];
  26. },
  27. enumerable: true
  28. }
  29. }); // return an object pretending to be a NodeList
  30. };
  31. }());
  32.  
  33. if (arguments.length < 1 || typeof selector == 'undefined') {
  34. this.nodeList = 'empty';
  35. } else {
  36. if (selector instanceof Element) {
  37. this.nodeList = singleNode(selector);
  38. } else if (selector instanceof NodeList || selector instanceof HTMLCollection) {
  39. this.nodeList = selector;
  40. } else if (selector instanceof Array) {
  41. selector.forEach(function(el) {
  42. if (el instanceof Element) {
  43. el.classList.add('udTempClassSelector');
  44. }
  45. });
  46. this.nodeList = _$('.udTempClassSelector').nodeList;
  47. Array.prototype.forEach.call(_$('.udTempClassSelector').nodeList, function(el) {
  48. el.classList.remove('udTempClassSelector');
  49. });
  50. } else {
  51. this.nodeList = document.querySelectorAll(selector);
  52. }
  53. this.selector = selector;
  54. }
  55. Array.prototype.forEach.call(document.querySelectorAll('.udTempClassSelector'), function(el) {
  56. el.classList.remove('.udTempClassSelector');
  57. });
  58.  
  59. this.length = this.nodeList.length;
  60. var nodeArray = [];
  61. for (var i=0; i<this.length; i++) {
  62. this[i] = this.nodeList[i];
  63. }
  64. }
  65.  
  66. // selection functions
  67.  
  68. parent() {
  69. if (this.nodeList instanceof NodeList) {
  70. var myParent = this.nodeList[0].parentNode;
  71. return _$(myParent);
  72. }
  73. }
  74.  
  75. children() {
  76. return _$(this.nodeList[0].children);
  77. }
  78.  
  79. first() {
  80. if (this.nodeList instanceof NodeList) {
  81. return _$(this.nodeList[0]);
  82. } else {
  83. return _$(this.selector);
  84. }
  85. }
  86.  
  87. last() {
  88. if (this.nodeList instanceof NodeList) {
  89. var length = this.nodeList.length;
  90. this.nodeList[length-1].classList.add('udLastTempClass');
  91. var returnThis = _$('.udLastTempClass');
  92. _$('.udLastTempClass').removeClass('.udLastTempClass');
  93. return returnThis;
  94. } else {
  95. return _$(this.selector);
  96. }
  97. }
  98.  
  99. nth(pos) { // Takes 1-indexed values
  100. pos -= 1;
  101. return _$(this[pos]);
  102. }
  103. index(pos) { // Takes 0-indexed values
  104. return _$(this[pos]);
  105. }
  106. next() {
  107. return _$(this[this.length-1].nextElementSibling);
  108. }
  109. contents() {
  110. // var frame = document.getElementById('myframe');
  111. // var c = frame.contentDocument || frame.contentWindow.document;
  112. return this.nodeList[0].contentDocument || this.nodeList[0].contentWindow.document;
  113. }
  114.  
  115.  
  116.  
  117. // display functions
  118.  
  119. css(arg1, arg2){
  120. var me = this;
  121. if (typeof arg1 == 'string' && typeof arg2 == 'string') {
  122. Array.prototype.forEach.call(this.nodeList, function(el){
  123. el.style[arg1] = arg2;
  124. });
  125. } else if (arg1 instanceof Object) {
  126. Array.prototype.forEach.call(this.nodeList, function(el) {
  127. _$().each(arg1, function(styleName, styleValue) {
  128. el.style[styleName] = styleValue;
  129. });
  130. });
  131. }
  132.  
  133. return _$(this.selector);
  134. }
  135.  
  136. hide() {
  137. this.css('display', 'none');
  138. return _$(this.selector);
  139. }
  140.  
  141. show() {
  142. this.css('display', '');
  143. return _$(this.selector);
  144. }
  145.  
  146. toggle() {
  147. if (this.nodeList instanceof NodeList) {
  148. this.each(function(el){
  149. if (el.style.display == 'none') {
  150. el.style.display = '';
  151. } else {
  152. el.style.display = 'none';
  153. }
  154. });
  155. }
  156. return _$(this.selector);
  157. }
  158.  
  159. // DOM functions
  160.  
  161. before(htmlString) {
  162. this.each(function(el){
  163. el.insertAdjacentHTML('beforebegin', htmlString);
  164. });
  165. return _$(this.selector);
  166. }
  167.  
  168. after(htmlString) {
  169. this.each(function(el){
  170. el.insertAdjacentHTML('afterend', htmlString);
  171. });
  172. return _$(this.selector);
  173. }
  174.  
  175. append(something) {
  176. if (something instanceof Element) {
  177. this.each(function(el) {
  178. // how to function with appending one existing thing when there are multiple things to append to??
  179. el.appendChild(something);
  180.  
  181. });
  182. } else if (something instanceof NodeList) {
  183. Array.prototype.forEach.call(something, function(el) {
  184. this.append(something);
  185. });
  186. } else if (typeof something == 'string') {
  187. this.each(function(el) {
  188. var newEl = document.createElement('text');
  189. newEl.innerHTML = something;
  190. el.appendChild(newEl)
  191. });
  192. } else if (something.hasOwnProperty('is_$')) {
  193. if (something.nodeList.length == 1) {
  194. this.each(function(el) {
  195. // how to function with appending one existing thing when there are multiple things to append to??
  196. el.appendChild(something.nodeList[0]);
  197. });
  198. } else if (something.nodeList.length > 1) {
  199. this.each(function(el) {
  200. // how to function with appending one existing thing when there are multiple things to append to??
  201. //el.appendChild(something.nodeList[0]);
  202. Array.prototype.forEach.call(something.nodeList, function(myNode, nodeIndex) {
  203. el.appendChild(myNode);
  204. });
  205. });
  206. }
  207. }
  208. return _$(this.selector);
  209. }
  210.  
  211. prepend(something) {
  212. if (something instanceof Element) {
  213. this.each(function(el) {
  214. // how to function with appending one existing thing when there are multiple things to append to??
  215. el.insertBefore(something, el.firstChild);
  216.  
  217. });
  218. } else if (something instanceof NodeList) {
  219. Array.prototype.forEach.call(something, function(el) {
  220. this.append(something, el.firstChild);
  221. });
  222. } else if (typeof something == 'string') {
  223. this.each(function(el) {
  224. var newEl = document.createElement('text');
  225. newEl.innerHTML = something;
  226. el.insertBefore(newEl, el.firstChild)
  227. });
  228. } else if (something.hasOwnProperty('is_$')) {
  229. if (something.nodeList.length == 1) {
  230. this.each(function(el) {
  231. // how to function with appending one existing thing when there are multiple things to append to??
  232. el.insertBefore(something.nodeList[0], el.firstChild);
  233. });
  234. } else if (something.nodeList.length > 1) {
  235. this.each(function(el) {
  236. // how to function with appending one existing thing when there are multiple things to append to??
  237. Array.prototype.forEach.call(something.nodeList, function(myNode, nodeIndex) {
  238. el.insertBefore(myNode, el.firstChild);
  239. });
  240. });
  241. }
  242. }
  243. return _$(this.selector);
  244. }
  245.  
  246. remove() {
  247. this.each(function(el) {
  248. el.parentNode.removeChild(el);
  249. });
  250. }
  251.  
  252. wrap(htmlString) {
  253. this.after(htmlString);
  254. var newEl = this.next();
  255. newEl.prepend(this);
  256. }
  257. wrapInner(htmlString) {
  258. this.after(htmlString);
  259. var newEl = this.next();
  260. console.dir(this.children());
  261. Array.prototype.forEach.call(this.children(), function(el) {
  262. newEl.prepend(el);
  263. });
  264. this.prepend(newEl);
  265. //this.children().wrap(htmlString);
  266. }
  267. // other element property/content functions
  268.  
  269. attr(arg1, arg2) {
  270. if (arguments.length < 2) {
  271. return this.nodeList[0].getAttribute(arg1);
  272. } else {
  273. this.each(function(el) {
  274. el.setAttribute(arg1, arg2);
  275. });
  276. return _$(this.selector);
  277. }
  278. }
  279.  
  280. text(textString) {
  281. if (arguments.length < 1) {
  282. var myVal = '';
  283. this.each(function(el){
  284. myVal += el.textContent;
  285. });
  286. return myVal;
  287. } else {
  288. this.each(function(el){
  289. el.textContent = textString;
  290. });
  291. return _$(this.selector);
  292. }
  293. }
  294.  
  295. html(arg1) {
  296. if (arguments.length < 1) {
  297. var myVal = '';
  298. this.each(function(el){
  299. myVal += el.innerHTML;
  300. });
  301. return myVal;
  302. } else {
  303. this.each(function(el){
  304. el.innerHTML = arg1;
  305. });
  306. return _$(this.selector);
  307. }
  308. }
  309.  
  310. val(arg1) {
  311. if (arguments.length < 1) {
  312. if (this.length > 1) {
  313. var myVals = [];
  314. this.each(function(el){
  315. myVals.push(el.value)
  316. });
  317. return myVals;
  318. } else if (this.length == 1) {
  319. return this.nodeList[0].value;
  320. }
  321. } else {
  322. this.each(function(el){
  323. el.value = arg1;
  324. });
  325. return _$(this.selector);
  326. }
  327. }
  328.  
  329. isVisible() {
  330. if (this.length == 1) {
  331. return this.nodeList[0].offsetWidth !== 0 && this.nodeList[0].offsetHeight !== 0;
  332. } else if (this.length == 1) {
  333. var numVisible = 0;
  334. this.each(function(el){
  335. if (!(el.offsetWidth !== 0) || !(el.offsetHeight !== 0)) {
  336. numVisible++;
  337. }
  338. });
  339. return numVisible;
  340. }
  341. }
  342.  
  343. // class functions
  344.  
  345. addClass(classNames) {
  346. var classNameList = classNames.split(/[ ,]/gim);
  347. this.each(function(el) {
  348. _$().each(classNameList, function(index, val) {
  349. if (val.length > 0) {
  350. el.classList.add(val);
  351. }
  352. });
  353. });
  354. }
  355. removeClass(classNames) {
  356. var classNameList = classNames.split(/[ ,]/gim);
  357. this.each(function(el) {
  358. _$().each(classNameList, function(index, val) {
  359. if (val.length > 0) {
  360. el.classList.remove(val);
  361. }
  362. });
  363. });
  364. }
  365. toggleClass(classNames) {
  366. var classNameList = classNames.split(/[ ,]/gim);
  367. this.each(function(el) {
  368. _$().each(classNameList, function(index, val) {
  369. if (val.length > 0) {
  370. el.classList.toggle(val);
  371. }
  372. });
  373. });
  374. }
  375. replaceClass(oldClass, newClass) {
  376. this.each(function(el) {
  377. el.classList.replace(oldClass, newClass);
  378. });
  379. }
  380.  
  381. // event functions
  382.  
  383. bind(eventName, fn) {
  384. Array.prototype.forEach.call(this.nodeList, function(el) {
  385. el.addEventListener(eventName, fn);
  386. });
  387.  
  388. }
  389. trigger(eventName) {
  390. var event = document.createEvent('HTMLEvents');
  391. event.initEvent(eventName, true, false);
  392. this.each(function(el){
  393. el.dispatchEvent(event);
  394. });
  395. }
  396.  
  397. // json functions
  398.  
  399. getJSON(url, placeholder, fn) {
  400. var Httpreq = new XMLHttpRequest(); // a new request
  401. Httpreq.open("GET",url,false);
  402. Httpreq.send(null);
  403. var data = JSON.parse(Httpreq.responseText);
  404. if (arguments.length > 2) {
  405. fn(data);
  406. }
  407. return data;
  408. }
  409. // utility functions
  410.  
  411. filter(fn) {
  412. this.each(function(el){
  413. if (fn(el)) {
  414. el.classList.add('udFilterTempClass');
  415. }
  416. });
  417. var returnThis = _$('.udFilterTempClass');
  418. _$('.udFilterTempClass').each(function(el) {
  419. el.classList.remove('udFilterTempClass');
  420. });
  421. // var returnThis = Array.prototype.filter.call(this.nodeList, fn);
  422. // console.dir(returnThis);
  423. return returnThis;
  424. }
  425.  
  426. each(arg1, arg2){
  427. if (arg1 instanceof Object && arg2 instanceof Function) {
  428. for (var p in arg1) {
  429. if (arg1.hasOwnProperty(p)) {
  430. arg2(p, arg1[p]);
  431. }
  432. }
  433. } else if (arg1 instanceof Array && arg2 instanceof Function) {
  434. Array.prototype.forEach.call(arg1, arg2);
  435. } else if (this.nodeList instanceof Array || this.nodeList instanceof NodeList) {
  436. Array.prototype.forEach.call(this.nodeList, arg1);
  437. }
  438.  
  439. return _$(this.selector);
  440. }
  441.  
  442. iterateOverObject(obj, fn) {
  443. if (obj instanceof Object) {
  444. for (var p in obj) {
  445. if (obj.hasOwnProperty(p)) {
  446. fn(p, obj[p]);
  447. }
  448. }
  449. }
  450.  
  451. return _$(this.selector);
  452. }
  453.  
  454. }
  455.  
  456. function _$(selector) {
  457. return new underdollar(selector);
  458. }