JQuery DOM

Optimize JQuery experience of insert DOM.

当前为 2022-12-10 提交的版本,查看 最新版本

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

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