http://www.cnblogs.com/jasonoiu/p/easyloader_source_code_analysis.html

Jquery easyui是一个javascript UI 组件库,使用它可以快速开发企业级的业务系统。如果你正准备开发系统后台,可以选择jquery easyui,也可以选择Ext JS。我个人的看法是,如果开发团队就两三个人,开发工期很短,就一两个月。那么选择jquery easyui就对了,jquery easyui源代码量不多,便于阅读和自行修改。而Ext JSy源代码太多,短时间很难看完,学习曲线也比较陡峭。如果人手充足,时间也富裕,可以考虑使用Ext JS来开发,毕竟Ext JS更强大,控件更多。

Jquery easyui是基于Jquery插件机制扩展的,所以如果你很熟悉Jquery,那么使用它开发会很简单。

Jquery easyui的源代码svn地址:http://jquery-easyui.googlecode.com/svn

easyloader模块是用来加载jquery easyui的js和css文件的,而且它可以分析模块的依赖关系,先加载依赖项。模块加载好了会调用parse模块来解析页面。把class是easyui开头的标签都转化成easyui的控件。

先看Demo1例子,再分析源代码。

  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <title>Demo1</title>
  6. <script type="text/javascript" src="jquery-easyui-1.2.3/jquery-1.4.4.min.js"></script>
  7. <script type="text/javascript" src="jquery-easyui-1.2.3/easyloader.js"></script>
  8. </head>
  9. <body>
  10. <div class="easyui-panel" title="Demo1" fit="true" collapsible="true" minimizable="true" maximizable="true" closable="true" style="width: 100%; height: 200px;" >
  11. easyloader会自动解析这个div,因为class属性中带有easyui开头的类!
  12. </div>
  13. </body>
  14. </html>

作者开发此模块,说明应该尽量使用easyuiloader来加载。因为他定制性更强,可以自定义主题和国际化等。而压缩过的文件的优势在于一次性把所有模块都加载进来,速度上更快。

  1. 1 /**
  2. 2 * easyloader - jQuery EasyUI
  3. 3 *
  4. 4 * Licensed under the GPL:
  5. 5 * http://www.gnu.org/licenses/gpl.txt
  6. 6 *
  7. 7 * Copyright 2010 stworthy [ stworthy@gmail.com ]
  8. 8 *
  9. 9 */
  10. 10 (function(){
  11. 11 // 模块文件定义
  12. 12 var modules = {
  13. 13 draggable:{
  14. 14 js:'jquery.draggable.js'
  15. 15 },
  16. 16 droppable:{
  17. 17 js:'jquery.droppable.js'
  18. 18 },
  19. 19 resizable:{
  20. 20 js:'jquery.resizable.js'
  21. 21 },
  22. 22 linkbutton:{
  23. 23 js:'jquery.linkbutton.js',
  24. 24 css:'linkbutton.css'
  25. 25 },
  26. 26 pagination:{
  27. 27 js:'jquery.pagination.js',
  28. 28 css:'pagination.css',
  29. 29 dependencies:['linkbutton']
  30. 30 },
  31. 31 datagrid:{
  32. 32 js:'jquery.datagrid.js',
  33. 33 css:'datagrid.css',
  34. 34 dependencies:['panel','resizable','linkbutton','pagination']
  35. 35 },
  36. 36 treegrid:{
  37. 37 js:'jquery.treegrid.js',
  38. 38 css:'tree.css',
  39. 39 dependencies:['datagrid']
  40. 40 },
  41. 41 panel: {
  42. 42 js:'jquery.panel.js',
  43. 43 css:'panel.css'
  44. 44 },
  45. 45 window:{
  46. 46 js:'jquery.window.js',
  47. 47 css:'window.css',
  48. 48 dependencies:['resizable','draggable','panel']
  49. 49 },
  50. 50 dialog:{
  51. 51 js:'jquery.dialog.js',
  52. 52 css:'dialog.css',
  53. 53 dependencies:['linkbutton','window']
  54. 54 },
  55. 55 messager:{
  56. 56 js:'jquery.messager.js',
  57. 57 css:'messager.css',
  58. 58 dependencies:['linkbutton','window']
  59. 59 },
  60. 60 layout:{
  61. 61 js:'jquery.layout.js',
  62. 62 css:'layout.css',
  63. 63 dependencies:['resizable','panel']
  64. 64 },
  65. 65 form:{
  66. 66 js:'jquery.form.js'
  67. 67 },
  68. 68 menu:{
  69. 69 js:'jquery.menu.js',
  70. 70 css:'menu.css'
  71. 71 },
  72. 72 tabs:{
  73. 73 js:'jquery.tabs.js',
  74. 74 css:'tabs.css',
  75. 75 dependencies:['panel','linkbutton']
  76. 76 },
  77. 77 splitbutton:{
  78. 78 js:'jquery.splitbutton.js',
  79. 79 css:'splitbutton.css',
  80. 80 dependencies:['linkbutton','menu']
  81. 81 },
  82. 82 menubutton:{
  83. 83 js:'jquery.menubutton.js',
  84. 84 css:'menubutton.css',
  85. 85 dependencies:['linkbutton','menu']
  86. 86 },
  87. 87 accordion:{
  88. 88 js:'jquery.accordion.js',
  89. 89 css:'accordion.css',
  90. 90 dependencies:['panel']
  91. 91 },
  92. 92 calendar:{
  93. 93 js:'jquery.calendar.js',
  94. 94 css:'calendar.css'
  95. 95 },
  96. 96 combo:{
  97. 97 js:'jquery.combo.js',
  98. 98 css:'combo.css',
  99. 99 dependencies:['panel','validatebox']
  100. 100 },
  101. 101 combobox:{
  102. 102 js:'jquery.combobox.js',
  103. 103 css:'combobox.css',
  104. 104 dependencies:['combo']
  105. 105 },
  106. 106 combotree:{
  107. 107 js:'jquery.combotree.js',
  108. 108 dependencies:['combo','tree']
  109. 109 },
  110. 110 combogrid:{
  111. 111 js:'jquery.combogrid.js',
  112. 112 dependencies:['combo','datagrid']
  113. 113 },
  114. 114 validatebox:{
  115. 115 js:'jquery.validatebox.js',
  116. 116 css:'validatebox.css'
  117. 117 },
  118. 118 numberbox:{
  119. 119 js:'jquery.numberbox.js',
  120. 120 dependencies:['validatebox']
  121. 121 },
  122. 122 spinner:{
  123. 123 js:'jquery.spinner.js',
  124. 124 css:'spinner.css',
  125. 125 dependencies:['validatebox']
  126. 126 },
  127. 127 numberspinner:{
  128. 128 js:'jquery.numberspinner.js',
  129. 129 dependencies:['spinner','numberbox']
  130. 130 },
  131. 131 timespinner:{
  132. 132 js:'jquery.timespinner.js',
  133. 133 dependencies:['spinner']
  134. 134 },
  135. 135 tree:{
  136. 136 js:'jquery.tree.js',
  137. 137 css:'tree.css',
  138. 138 dependencies:['draggable','droppable']
  139. 139 },
  140. 140 datebox:{
  141. 141 js:'jquery.datebox.js',
  142. 142 css:'datebox.css',
  143. 143 dependencies:['calendar','validatebox']
  144. 144 },
  145. 145 parser:{
  146. 146 js:'jquery.parser.js'
  147. 147 }
  148. 148 };
  149. 149
  150. 150 // 国际化资源文件
  151. 151 var locales = {
  152. 152 'af':'easyui-lang-af.js',
  153. 153 'bg':'easyui-lang-bg.js',
  154. 154 'ca':'easyui-lang-ca.js',
  155. 155 'cs':'easyui-lang-cs.js',
  156. 156 'da':'easyui-lang-da.js',
  157. 157 'de':'easyui-lang-de.js',
  158. 158 'en':'easyui-lang-en.js',
  159. 159 'fr':'easyui-lang-fr.js',
  160. 160 'nl':'easyui-lang-nl.js',
  161. 161 'zh_CN':'easyui-lang-zh_CN.js',
  162. 162 'zh_TW':'easyui-lang-zh_TW.js'
  163. 163 };
  164. 164
  165. 165 // 加载队列
  166. 166 var queues = {};
  167. 167
  168. 168 /**
  169. 169 * 加载js文件函数,过程就是动态创建一个script标签,然后添加到head标签中去。
  170. 170 * 有一个问题是监听了script标签的两个事件函数,一个是onload,另一个是onreadystatechange,这个数要是针对IE和非IE浏览器准备的
  171. 171 * 万恶的IE浏览器!!!
  172. 172 */
  173. 173 function loadJs(url, callback){
  174. 174 var done = false;
  175. 175 var script = document.createElement('script');
  176. 176 script.type = 'text/javascript';
  177. 177 script.language = 'javascript';
  178. 178 script.src = url;
  179. 179 script.onload = script.onreadystatechange = function(){
  180. 180 if (!done && (!script.readyState || script.readyState == 'loaded' || script.readyState == 'complete')){
  181. 181 done = true;
  182. 182 script.onload = script.onreadystatechange = null;
  183. 183 if (callback){
  184. 184 callback.call(script);
  185. 185 }
  186. 186 }
  187. 187 }
  188. 188 document.getElementsByTagName("head")[0].appendChild(script);
  189. 189 }
  190. 190
  191. 191 /**
  192. 192 * 执行js文件。就是把js文件加载进来,再remove掉
  193. 193 * @param url js的url
  194. 194 * @callback 回调函数,执行完js时会调用这个函数
  195. 195 */
  196. 196 function runJs(url, callback){
  197. 197 loadJs(url, function(){
  198. 198 document.getElementsByTagName("head")[0].removeChild(this);
  199. 199 if (callback){
  200. 200 callback();
  201. 201 }
  202. 202 });
  203. 203 }
  204. 204
  205. 205 /**
  206. 206 * 加载css文件。和加载js文件一样,动态创建一个link标签,然后追加到head标签中去
  207. 207 * @param url css的url
  208. 208 * @param callback 回调函数,加载完成后调用此函数
  209. 209 */
  210. 210 function loadCss(url, callback){
  211. 211 var link = document.createElement('link');
  212. 212 link.rel = 'stylesheet';
  213. 213 link.type = 'text/css';
  214. 214 link.media = 'screen';
  215. 215 link.href = url;
  216. 216 document.getElementsByTagName('head')[0].appendChild(link);
  217. 217 if (callback){
  218. 218 callback.call(link);
  219. 219 }
  220. 220 }
  221. 221
  222. 222 /**
  223. 223 * 加载单独的一个模块
  224. 224 */
  225. 225 function loadSingle(name, callback){
  226. 226
  227. 227 // 加载队列存入该模块名,并表示状态为loading。
  228. 228 queues[name] = 'loading';
  229. 229
  230. 230 // 根据模块名,取出该模块定义
  231. 231 var module = modules[name];
  232. 232
  233. 233 // js加载状态
  234. 234 var jsStatus = 'loading';
  235. 235
  236. 236 // css加载状态,从这里你就可以看出easyloader.css就是一个开关变量,控制是否加载模块相应的css文件
  237. 237 var cssStatus = (easyloader.css && module['css']) ? 'loading' : 'loaded';
  238. 238
  239. 239 // 是css文件,就使用loadCss来加载之
  240. 240 if (easyloader.css && module['css']){
  241. 241 if (/^http/i.test(module['css'])){
  242. 242 var url = module['css'];
  243. 243 } else {
  244. 244 var url = easyloader.base + 'themes/' + easyloader.theme + '/' + module['css'];
  245. 245 }
  246. 246 loadCss(url, function(){
  247. 247 cssStatus = 'loaded';
  248. 248 if (jsStatus == 'loaded' && cssStatus == 'loaded'){
  249. 249 finish();
  250. 250 }
  251. 251 });
  252. 252 }
  253. 253
  254. 254 // 是js文件,就是用LoadJs来加载之
  255. 255 if (/^http/i.test(module['js'])){
  256. 256 var url = module['js'];
  257. 257 } else {
  258. 258 var url = easyloader.base + 'plugins/' + module['js'];
  259. 259 }
  260. 260 loadJs(url, function(){
  261. 261 jsStatus = 'loaded';
  262. 262 if (jsStatus == 'loaded' && cssStatus == 'loaded'){
  263. 263 finish();
  264. 264 }
  265. 265 });
  266. 266
  267. 267 // 最终调用finish函数,来结束加载。并触发onProgress函数,每加载成功一个模块,就调用一次onProgress
  268. 268 function finish(){
  269. 269 queues[name] = 'loaded';
  270. 270 easyloader.onProgress(name);
  271. 271 if (callback){
  272. 272 callback();
  273. 273 }
  274. 274 }
  275. 275 }
  276. 276
  277. 277 /**
  278. 278 * easyui模块加载函数
  279. 279 * @param name 模块名,可以是string,也可以是数组
  280. 280 * @param callback 回调函数,当加载结束后会调用此函数
  281. 281 */
  282. 282 function loadModule(name, callback){
  283. 283
  284. 284 // 模块名,根据依赖关系,从前到后,依次排开
  285. 285 var mm = [];
  286. 286
  287. 287 // 加载标识,当其值为true时,表示需要加载的模块已经加载好了
  288. 288 var doLoad = false;
  289. 289
  290. 290 // 模块名支持两中,一种是string,一种是数组。这样就可以一次加载多个模块了
  291. 291 if (typeof name == 'string'){
  292. 292 // 是string的时候,调用add方法把模块名push到mm数组中去
  293. 293 add(name);
  294. 294 } else {
  295. 295 for(var i=0; i<name.length; i++){
  296. 296 // 是数组的时候,循环调用add方法把模块名统统push到mm数组中去
  297. 297 add(name[i]);
  298. 298 }
  299. 299 }
  300. 300
  301. 301 /**
  302. 302 * loadModule函数中内嵌的一个函数,用来加载模块名到变量mm数组中去
  303. 303 * @param name 模块名,只能是string
  304. 304 */
  305. 305 function add(name){
  306. 306 // 保护措施,如果该模块名不存在,我们就不要加载了
  307. 307 if (!modules[name]) return;
  308. 308
  309. 309 // 否则,就是该模块存在。然后,我们在看看其有没有依赖模块
  310. 310 var d = modules[name]['dependencies'];
  311. 311 if (d){
  312. 312 // 如果有依赖模块,我们要先把依赖模块的名字push到mm中去
  313. 313 // 这里用了递归调用
  314. 314 for(var i=0; i<d.length; i++){
  315. 315 add(d[i]);
  316. 316 }
  317. 317 }
  318. 318
  319. 319 // 把模块名放到mm中
  320. 320 mm.push(name);
  321. 321 }
  322. 322
  323. 323 /**
  324. 324 * 当一个模块及其依赖模块加载完成时,执行回调函数,并且触发onLoad函数
  325. 325 */
  326. 326 function finish(){
  327. 327 if (callback){
  328. 328 callback();
  329. 329 }
  330. 330 easyloader.onLoad(name);
  331. 331 }
  332. 332
  333. 333 // 加载用时
  334. 334 var time = 0;
  335. 335
  336. 336 /**
  337. 337 * 加载所需要的模块,需要的模块,我们已经统计好了,并按依赖关系,先后push到mm中去了
  338. 338 */
  339. 339 function loadMm(){
  340. 340 // 判断mm是不是空的
  341. 341 if (mm.length){
  342. 342
  343. 343 // 第一个模块
  344. 344 var m = mm[0];
  345. 345
  346. 346 // 判断加载队列是否包含此模块
  347. 347 if (!queues[m]){
  348. 348
  349. 349 // 加载队列不包含此模块,开始加载该模块
  350. 350 // 把doLoad置成true,表示开始加载
  351. 351 doLoad = true;
  352. 352
  353. 353 // 调用loadSingle方法来加载模块,加载成功后会把此模块从mm中shift掉,然后继续调用loadMM方法,就形成了递归调用
  354. 354 loadSingle(m, function(){
  355. 355 mm.shift();
  356. 356 loadMm();
  357. 357 });
  358. 358 } else if (queues[m] == 'loaded'){
  359. 359 // 加载队列已经加载过此模块了,不需要在加载了,直接从mm中shift掉即可
  360. 360 mm.shift();
  361. 361 loadMm();
  362. 362 } else {
  363. 363 // 表示正在加载该模块,累计所用时间如果没有超过timeout
  364. 364 // 则过10毫秒再调用一次loadMm函数
  365. 365 if (time < easyloader.timeout){
  366. 366 time += 10;
  367. 367 setTimeout(arguments.callee, 10);
  368. 368 }
  369. 369 }
  370. 370 } else {
  371. 371 // 走到这里,表示该加载的模块都已经加载好了
  372. 372 if (easyloader.locale && doLoad == true && locales[easyloader.locale]){
  373. 373 // 如果设置了国际化,并且已经加载好了,而且该国际化资源还存在,那么加载该资源js
  374. 374 var url = easyloader.base + 'locale/' + locales[easyloader.locale];
  375. 375
  376. 376 // 执行js完事后,调用finish方法
  377. 377 runJs(url, function(){
  378. 378 finish();
  379. 379 });
  380. 380 } else {
  381. 381 // 没定义国际化文件,那么直接调用finish方法吧
  382. 382 finish();
  383. 383 }
  384. 384 }
  385. 385 }
  386. 386
  387. 387 loadMm();
  388. 388 }
  389. 389
  390. 390 /**
  391. 391 * easyloader定义为全局变量
  392. 392 */
  393. 393 easyloader = {
  394. 394
  395. 395 // 各个模块文件的定义,包括js、css和依赖模块
  396. 396 modules:modules,
  397. 397
  398. 398 // 国际化资源文件
  399. 399 locales:locales,
  400. 400
  401. 401 // jquery-easyui的根目录,在加载easyloader时,会自动根据你放置的位置而改变
  402. 402 base:'.',
  403. 403
  404. 404 // 控件的主题,一共就有两个,在theme目录中。还有一个gray主题,浅灰色的,很难看。
  405. 405 theme:'default',
  406. 406
  407. 407 // 这是一个开关变量,控制easyloader加载模块时,要不要加载相应的css文件,默认是需要加载的
  408. 408 css:true,
  409. 409
  410. 410 // 国际化语言,可以根据window.navigator.language或者window.navigator.userLanguage来获取当前浏览器的语言。
  411. 411 // 有两个属性,主要因为IE浏览器只认识userLanguage和sysLanguage,万恶的IE浏览器啊!
  412. 412 locale:null,
  413. 413
  414. 414 // 加载一个模块的最长时间,超过这个时间,就开始加载下一个模块了。
  415. 415 timeout:2000,
  416. 416
  417. 417 // easyloader就公开了这么一个方法,用来加载模块。
  418. 418 // name是模块名,callback是加载成功后执行的函数
  419. 419 load: function(name, callback){
  420. 420 if (//.css$/i.test(name)){
  421. 421 // 如果模块名是以.css结尾
  422. 422
  423. 423 if (/^http/i.test(name)){
  424. 424 // 如果模块名是以http开头,那么css是一个文件的url
  425. 425 loadCss(name, callback);
  426. 426 } else {
  427. 427 // 否则,说明模块名相对于jquery easyui根目录来说的
  428. 428 loadCss(easyloader.base + name, callback);
  429. 429 }
  430. 430 } else if (//.js$/i.test(name)){
  431. 431 // 如果模块名是以.js结尾
  432. 432
  433. 433 if (/^http/i.test(name)){
  434. 434 // 如果模块名是以http开头,那么js是一个文件的url
  435. 435 loadJs(name, callback);
  436. 436 } else {
  437. 437 // 否则,说明模块名相对于jquery easyui根目录来说的
  438. 438 loadJs(easyloader.base + name, callback);
  439. 439 }
  440. 440 } else {
  441. 441 // 以上两种都不是,说明是easyui自己的模块,直接使用loadModule来加载,就可以了
  442. 442 loadModule(name, callback);
  443. 443 }
  444. 444 },
  445. 445
  446. 446 // 当一个模块加载完会触发此函数
  447. 447 onProgress: function(name){},
  448. 448
  449. 449 // 当一个模块和其依赖都加载完会触发此函数
  450. 450 onLoad: function(name){}
  451. 451 };
  452. 452 /**
  453. 453 * 这一小段代码就是查找jquery-easyui的根目录,并赋值给easyloader的base属性上。这样easyloader再加载css文件和js文件就很方便定位了。
  454. 454 */
  455. 455 var scripts = document.getElementsByTagName('script');
  456. 456 for(var i=0; i<scripts.length; i++){
  457. 457 var src = scripts[i].src;
  458. 458 if (!src) continue;
  459. 459 var m = src.match(/easyloader/.js(/W|$)/i);
  460. 460 if (m){
  461. 461 easyloader.base = src.substring(0, m.index);
  462. 462 }
  463. 463 }
  464. 464 /**
  465. 465 * 这个就起一个别名的作用,比如页面中可以想如下这么下:
  466. 466 * using('window');
  467. 467 * 这样window模块就加载进来了!
  468. 468 */
  469. 469 window.using = easyloader.load;
  470. 470 /**
  471. 471 * easyloader.js加载的第一模块是parse模块,parser模块调用parse方法,可以解析页面上的easyui控件
  472. 472 */
  473. 473 if (window.jQuery){
  474. 474 jQuery(function(){
  475. 475 easyloader.load('parser', function(){
  476. 476 jQuery.parser.parse();
  477. 477 });
  478. 478 });
  479. 479 }
  480. 480
  481. 481 })();

easyloader.js源代码分析的更多相关文章

  1. jqueryui.position.js源代码分析

    近期要写前端组件了.狂砍各种组件源代码,这里分析一款jqueryui中的posistion插件,注意,它不是jqueryui widget,首先看下源代码整体结构图 1.看到$.fn.position ...

  2. 3.EasyUI学习总结(三)——easyloader源码分析

    easyloader模块是用来加载jquery easyui的js和css文件的,即easyloader可以在调用的时候自动加载当前页面所需的文件,不用再自己引用, 而且它可以分析模块的依赖关系,先加 ...

  3. EasyUI学习总结(三)——easyloader源码分析(转载)

    声明:这一篇文章是转载过来的,转载地址忘记了,原作者如果看到了,希望能够告知一声,我好加上去! easyloader模块是用来加载jquery easyui的js和css文件的,而且它可以分析模块的依 ...

  4. pomelo源代码分析(一)

    千里之行始于足下,一直说想了解pomelo,对pomelo有兴趣,但一直迟迟没有去碰,尽管对pomelo进行源代码分析,在网络上肯定不止我一个,已经有非常优秀的前辈走在前面,如http://golan ...

  5. WebViewJavascriptBridge源代码分析

    近期抽时间看了一遍WebViewJavascriptBridge这个开源框架,把看到的内容记录下来 源代码地址:https://github.com/marcuswestin/WebViewJavas ...

  6. Zepto源代码分析一~核心方法

    今天抽出时间复习了一下Zepto的源代码,依照自己的理解进行凝视. 欢迎大家拍砖. 源代码版本号:v1.1.4 源代码下载地址:http://zeptojs.com/ 分析总体代码之后,整理出架构图: ...

  7. Zepto源代码分析之二~三个API

    因为时间关系:本次仅仅对这三个API($.camelCase.$.contains.$.each)方法进行分析 第一个方法变量转驼峰:$.camelCase('hello-world-welcome' ...

  8. Nodejs源代码分析之Path

    今天介绍一下nodejs Path的源代码分析,Path的API文档在https://nodejs.org/dist/latest-v5.x/docs/api/path.html,使用相对简单,在AP ...

  9. 高德JS依赖分析工程及关键原理

    一.背景 高德 App 进行 Bundle 化后,由于业务的复杂性,Bundle 的数量非常多.而这带来了一个新的问题——Bundle 之间的依赖关系错综复杂,需要进行管控,使 Bundle 之间的依 ...

随机推荐

  1. linux64需要增加的依赖库

    sudo apt-get install git-core gnupg flex bison gperf build-essential \ zip curl zlib1g-dev gcc-multi ...

  2. [转]iOS 应用内付费(IAP)开发步骤

    FROM : http://blog.csdn.net/xiaoxiangzhu660810/article/details/17434907 参考文章链接: (1)http://mobile.51c ...

  3. PHP基础20:创建文件

    <?php /* 1.PHP 创建文件 - fopen() fopen() 函数也用于创建文件.也许有点混乱,但是在 PHP 中,创建文件所用的函数与打开文件的相同 如果您用 fopen() 打 ...

  4. Response.Redirect("x.aspx);跳转后session为null的解决方法

    通常我们做登陆的时候都是登录成功后为管理员保存一些信息,一般都会写类似下面的代码 if(登录成功) { Session["xx"] = "user"; Resp ...

  5. win系统 添加、修改右键“发送到”

    发现大家在往U盘,移动硬盘传东西的时候,总是喜欢在本地把文件复制(缺德的还会用剪切)然后在打开U盘选择粘贴,其实完全没必要使用那么多步骤,不知道大家注意没有,只要在你本地的文件上右键--发送到--你的 ...

  6. LeetCode 笔记26 Maximum Product Subarray

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  7. [MetaHook] R_RicochetSprite

    By hzqst void R_RicochetSprite(float *pos, model_t *pmodel, float duration, float scale) { TEMPENTIT ...

  8. 解决jquery $符号的冲突

    今天做项目的时候,写了一个ajax提交的js函数,然后在js调试的时候,提示发现 $.ajax ,前面的$ 符号不见了,通过网上搜索找到了下面的解决方法 jQuery中需要用到$符号,如果其他js库也 ...

  9. 【MPI学习7】MPI并行程序设计模式:MPI的进程组和通信域

    基于都志辉老师MPI编程书中的第15章内容. 通信域是MPI的重要概念:MPI的通信在通信域的控制和维护下进行 → 所有MPI通信任务都直接或间接用到通信域这一参数 → 对通信域的重组和划分可以方便实 ...

  10. Shadowsock搭建

    搭建Shadowsocks服务端: 搭建Shadowsocks之前首先必须购买一个VPS.一般VPS提供商会给一个测试地址,购买之前最好先ping一下速度.也可以通过以下网址测试下vps网络速度: h ...