JQuery DOM

Optimize JQuery experience of insert DOM.

当前为 2021-03-09 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/422934/908887/JQuery%20DOM.js

  1. // ==UserScript==
  2. // @name JQuery DOM
  3. // @namespace https://greasyfork.org/
  4. // @version 1.0.5
  5. // @description Optimize JQuery experience of insert DOM.
  6. // @author JMRY
  7. // @include *://*
  8. // @grant none
  9. // ==/UserScript==
  10. /*
  11. JQuery Extensions DOM
  12. (c) 2020-2021 JMRY
  13. MIT Licensed.
  14.  
  15. Version: 1.0.5 Build 20210301
  16. Version: 1.0.4 Build 20200908
  17.  
  18. Feature:
  19. Optimize JQuery experience of insert DOM.
  20. Use object to instead string to generate HTML DOM string or objects.
  21.  
  22. How to use:
  23. Get the DOM string:
  24. $.getDOMString(`div`,{id:`div`,class:`div`},`This is a DIV.`);
  25. Insert element:
  26. $(`body`).appendDOM(`div`,{id:`div`,class:`div`},`This is a DIV.`);
  27. $(`body`).prependDOM(`div`,{id:`div`,class:`div`},`This is a DIV.`);
  28. $(`body`).beforeDOM(`div`,{id:`div`,class:`div`},`This is a DIV.`);
  29. $(`body`).afterDOM(`div`,{id:`div`,class:`div`},`This is a DIV.`);
  30. $(`body`).htmlDOM(`div`,{id:`div`,class:`div`},`This is a DIV.`);
  31. Events bind:
  32. $(`body`).appendDOM(`div`,{
  33. id:`div`,class:[`div`,`div2`],
  34. bind:{
  35. click(e){
  36. console.log(`test`);
  37. }
  38. }
  39. },`This is a DIV.`);
  40.  
  41. The bind events can also push the data:
  42. $(`body`).appendDOM(`div`,{
  43. id:`div`,class:`div`,
  44. bind:{
  45. click:{
  46. data:{index:1},
  47. function(e){
  48. console.log(e.data.index);
  49. }
  50. }
  51. }
  52. },`This is a DIV.`);
  53. Styles with JQuery css object struct:
  54. $(`body`).appendDOM(`div`,{
  55. id:`div`,class:[`div`,`div2`],
  56. style:{
  57. backgrundColor:`#FFF`,
  58. opacity:0,
  59. }
  60. },`This is a DIV.`);
  61.  
  62. Children elements:
  63. You can direct insert multi-children in one element, and supports cascade.
  64. $(`body`).appendDOM(`div`,{
  65. id:`div`,class:[`div`,`div2`],
  66. children:[
  67. {
  68. tag:`div`,
  69. attr:{
  70. id:`div_child_1`,class:[`div`,`div_child`],
  71. children:{
  72. tag:`div`,
  73. attr:{
  74. id:`div_grandson`,class:[`div`,`div_child`,`div_grandson`]
  75. },
  76. html:`This is a grandson DIV.`
  77. }
  78. },
  79. html:`This is a child DIV.`
  80. },
  81. {
  82. tag:`div`,
  83. attr:{
  84. id:`div_child_2`,class:[`div`,`div_child`],
  85. },
  86. html:`This is a child DIV.`
  87. }
  88. ]
  89. },`This is a DIV.`);
  90.  
  91. HTML string in attributes without dom_html param:
  92. Notice: the priority of HTML string in attributes is higher than dom_html param.
  93. $(`body`).appendDOM(`div`,{
  94. id:`div`,class:[`div`,`div2`],
  95. html:`This is a DIV.`,
  96. children:{
  97. tag:`div`,
  98. attr:{
  99. id:`div_child_1`,class:[`div`,`div_child`],
  100. html:`This is a child DIV.`
  101. }
  102. }
  103. });
  104.  
  105. You can also insert element without attributes:
  106. $(`body`).appendDOM(`div`,`This is a DIV.`);
  107.  
  108. Use object to insert element:
  109. $(`body`).appendDOM({
  110. tag:`div`,
  111. attr:{
  112. id:`div`,class:[`div`,`div2`],
  113. html:`This is a DIV.`,
  114. children:{
  115. tag:`div`,
  116. attr:{
  117. id:`div_child_1`,class:[`div`,`div_child`],
  118. html:`This is a child DIV.`
  119. }
  120. }
  121. }
  122. })
  123.  
  124. Batch insert elements:
  125. $(`body`).appendDOM([
  126. {
  127. tag:`div`,
  128. attr:{
  129. id:`div1`,class:[`div`,`div1`],
  130. html:`This is a DIV 1.`,
  131. children:{
  132. tag:`div`,
  133. attr:{
  134. id:`div_child_1`,class:[`div`,`div_child`],
  135. html:`This is a child DIV 1.`
  136. }
  137. }
  138. }
  139. },
  140. {
  141. tag:`div`,
  142. attr:{
  143. id:`div2`,class:[`div`,`div2`],
  144. html:`This is a DIV 2.`,
  145. children:{
  146. tag:`div`,
  147. attr:{
  148. id:`div_child_1`,class:[`div`,`div_child`],
  149. html:`This is a child DIV 2.`
  150. }
  151. }
  152. }
  153. },
  154. ])
  155. */
  156.  
  157. $.getDOMString=function(dom_tag,dom_attr,dom_html){
  158. /*
  159. dom_tag:string
  160. HTML tags, like div, input, p, button, and so on.
  161. dom_attr:object
  162. HTML attributes, struct:
  163. {
  164. id:`id`,
  165. class:`class1 class2` OR [`class1`,`class2`],
  166. style:`border:none;` OR {border:`none`},
  167.  
  168. Extend attributes:
  169. bind:{
  170. click:function,
  171. },
  172. }
  173. dom_attr:string
  174. HTML inner text
  175. dom_html:string
  176. HTML inner text
  177. */
  178.  
  179. //属性黑名单指的是在遍历属性时直接忽略的key。
  180. //如果需要处理这些key但不要插入html中,则应使用allow_insert_attr,将它置为false即可。
  181. let attr_blacklist=[
  182. `bind`,`children`,
  183. ]
  184. if(dom_tag==undefined){ //html标记为空时,直接返回空值
  185. return ``;
  186. }else if(dom_tag!=undefined && dom_attr==undefined && dom_html==undefined){ //html标记不为空、属性和内容为空时,直接返回字符串
  187. return dom_tag;
  188. }else if(dom_tag!=undefined && dom_attr!=undefined && dom_html==undefined){
  189. dom_html=``;
  190. }
  191.  
  192. let dom_attr_string=``;
  193.  
  194. //dom_attr is string, it will be the inner html, without attributes.
  195. if(typeof dom_attr==`string`){
  196. dom_html=dom_attr;
  197. }else if(typeof dom_attr==`object`){
  198. let allow_insert_attr;
  199. for(let key in dom_attr){
  200. allow_insert_attr=true;
  201. let cur_dom_attr=dom_attr[key];
  202. // if(key!=`bind`){
  203. if($.inArray(key,attr_blacklist)<0){
  204. //HTML属性的特殊处理
  205. switch(key){
  206. //Class数组化处理
  207. case `class`:
  208. if(typeof cur_dom_attr==`object`){
  209. cur_dom_attr=cur_dom_attr.join(` `);
  210. }
  211. break;
  212.  
  213. //Style对象化处理(交给getDOMObject,因此将allow_insert_attr置为false,以跳过插入属性)
  214. case `style`:
  215. if(typeof cur_dom_attr==`object`){
  216. allow_insert_attr=false;
  217. }
  218. break;
  219.  
  220. //Html属性转为text。此属性会覆盖dom_html参数,因此不可混用
  221. case `html`:
  222. dom_html=cur_dom_attr;
  223. allow_insert_attr=false;
  224. break;
  225. }
  226.  
  227. //cur_dom_attr为undefined、null时,不插入此属性
  228. if(cur_dom_attr!=undefined && cur_dom_attr!=null && allow_insert_attr){
  229. dom_attr_string+=` ${key}="${cur_dom_attr}"`;
  230. }
  231. }
  232. }
  233. }
  234.  
  235. if(dom_tag==`html`){
  236. return `${dom_html}`;
  237. }
  238. return `<${dom_tag}${dom_attr_string}>${dom_html}</${dom_tag}>`;
  239. }
  240.  
  241. $.getDOMObject=function(dom_tag,dom_attr,dom_html){
  242. try{
  243. let domObject=$($.getDOMString(dom_tag, dom_attr, dom_html));
  244. if(typeof dom_attr==`object`){
  245. //DOM样式
  246. try{
  247. /*
  248. CSS Struct:
  249. style:{
  250. width:`255px`,
  251. height:`255px`,
  252. }
  253. */
  254. if(typeof dom_attr.style==`object`){
  255. domObject.css(dom_attr.style);
  256. }
  257. }catch(e){
  258. console.error(e);
  259. }
  260.  
  261. //DOM事件绑定
  262. try{
  263. /*
  264. Bind Struct:
  265. bind:{
  266. click:function,
  267. }
  268. Another Struct:
  269. bind:{
  270. click:{
  271. data:{},
  272. function:function,
  273. }
  274. }
  275. */
  276. if(typeof dom_attr.bind==`object`){
  277. for(let key in dom_attr.bind){
  278. let curBind=dom_attr.bind[key];
  279. domObject.unbind(key);
  280. if(typeof curBind==`function`){
  281. domObject.bind(key, curBind);
  282. }else if(typeof curBind==`object`){
  283. curBind={
  284. ...{
  285. data:{},
  286. function(){},
  287. },
  288. ...curBind,
  289. }
  290. domObject.bind(key, curBind.data, curBind.function);
  291. }
  292. }
  293. }
  294. }catch(e){
  295. console.error(e);
  296. }
  297.  
  298. //DOM子项
  299. try{
  300. if(typeof dom_attr.children==`object`){
  301. let default_children={
  302. tag:undefined,attr:undefined,html:undefined,type:`append`
  303. };
  304.  
  305. if(dom_attr.children.length==undefined){
  306. /*仅一个子项时,可以直接使用Object
  307. {
  308. tag:`html`,attr:{id:`id`},html:`Test`,type:`append`
  309. }
  310. */
  311. let children={
  312. ...default_children,
  313. ...dom_attr.children,
  314. }
  315. domObject.attachDOM(children.tag,children.attr,children.html,children.type);
  316. }else{
  317. /*多个子项时,采用数组形式
  318. [
  319. {
  320. tag:`html`,attr:{id:`id1`},html:`Test1`,type:`append`
  321. },
  322. {
  323. tag:`html`,attr:{id:`id2`},html:`Test2`,type:`append`
  324. },
  325. ]
  326. */
  327. for(let i=0; i<dom_attr.children.length; i++){
  328. let children={
  329. ...default_children,
  330. ...dom_attr.children[i],
  331. }
  332. domObject.attachDOM(children.tag,children.attr,children.html,children.type);
  333. }
  334. }
  335. }
  336. }catch(e){
  337. console.error(e);
  338. }
  339. }
  340. return domObject;
  341. }catch(e){
  342. //对不规范写法的容错,如:只传dom_tag的情况下,直接返回字符串,而不是JQuery对象。
  343. return $.getDOMString(dom_tag, dom_attr, dom_html);
  344. }
  345. }
  346.  
  347. $.fn.attachDOM=function(dom_tag, dom_attr, dom_html, attach_type){
  348. //dom_tag为数组时,批量为母元素添加元素
  349. if(typeof dom_tag==`object` && dom_tag.length!=undefined){
  350. let default_children={
  351. tag:undefined,attr:undefined,html:undefined,type:`append`
  352. };
  353. for(let cur of dom_tag){
  354. cur={
  355. ...default_children,
  356. ...cur,
  357. }
  358. this.attachDOM(cur);
  359. }
  360. return;
  361. }
  362.  
  363. //dom_tag为对象时,和普通情况一样
  364. if(typeof dom_tag==`object` && dom_tag.length==undefined){
  365. dom_attr=dom_tag.attr;
  366. dom_html=dom_tag.html;
  367. attach_type=dom_tag.type;
  368. dom_tag=dom_tag.tag;
  369. }
  370.  
  371. let domObject=$.getDOMObject(dom_tag, dom_attr, dom_html);
  372.  
  373. switch(attach_type){
  374. case `append`:
  375. this.append(domObject);
  376. break;
  377. case `prepend`:
  378. this.prepend(domObject);
  379. break;
  380. case `after`:
  381. this.after(domObject);
  382. break;
  383. case `before`:
  384. this.before(domObject);
  385. break;
  386. case `html`:
  387. this.html(domObject);
  388. break;
  389. }
  390. return domObject;
  391. }
  392.  
  393. $.fn.appendDOM=function(dom_tag,dom_attr,dom_html){
  394. return this.attachDOM(dom_tag,dom_attr,dom_html,`append`);
  395. }
  396. $.fn.prependDOM=function(dom_tag,dom_attr,dom_html){
  397. return this.attachDOM(dom_tag,dom_attr,dom_html,`prepend`);
  398. }
  399. $.fn.afterDOM=function(dom_tag,dom_attr,dom_html){
  400. return this.attachDOM(dom_tag,dom_attr,dom_html,`after`);
  401. }
  402. $.fn.beforeDOM=function(dom_tag,dom_attr,dom_html){
  403. return this.attachDOM(dom_tag,dom_attr,dom_html,`before`);
  404. }
  405. $.fn.htmlDOM=function(dom_tag,dom_attr,dom_html){
  406. return this.attachDOM(dom_tag,dom_attr,dom_html,`html`);
  407. }