-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
2532 lines (2297 loc) · 460 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title><2016/><2017></title>
<url>/2016-12-31/2016-to-2017.html</url>
<content><![CDATA[<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=530 height=86 src="//music.163.com/outchain/player?type=2&id=32507038&auto=0&height=66"></iframe>
<blockquote>
<p>与其在上一秒中沉醉,不如努力拥抱下一秒.</p>
</blockquote>
<h2 id="匆匆而去的2016"><a href="#匆匆而去的2016" class="headerlink" title="匆匆而去的2016"></a>匆匆而去的2016</h2><p>入行前端的第二年,也是毕业的第二年。</p>
<p>短短两载却有翻天覆地的改变:从大学走入社会,从设计跨行到前端。这其中有必然也有偶然。</p>
<h3 id="年初"><a href="#年初" class="headerlink" title="年初"></a>年初</h3><p>年初换了新东家,毕业后的第二份工作,有对自身能力的底气不足而提高的渴望,也有对新东家的满怀期望,一切在有条不紊的进行着。2016年2月22日入职,从此多了一个别号二月(2ue)。座位在老大旁边,感到一丝压力。</p>
<h3 id="适应与压力"><a href="#适应与压力" class="headerlink" title="适应与压力"></a>适应与压力</h3><p>经历了最初的彷徨后,慢慢开始适应新的环境,作为新手的我,跟着大神们一起做项目是开心的,但也同时感受到更多的压力。因此在入职后的几个月进入了疯狂学习模式,逛技术社区,微博关注技术达人,微信关注相关公众号,啃书等等,连早上挤公交地铁的时候都抽时间在手机上学习,当时感觉自己已经疯魔。虽然也就仅仅疯狂了三个月,但这短暂的三个月疯狂却让我焕然一新:从最初的复制粘贴到有自己的思考、从无处可问到能独立解决问题、更加擅于利用网络解决问题、能够更快的阅读新的知识、更好的编码习惯…林林总总,这三个月是很重要的三个月。</p>
<h3 id="生活"><a href="#生活" class="headerlink" title="生活"></a>生活</h3><p>换了新房东,空间更大,也换了一台新电脑,更方便撸(打)代(游)码(戏)。总之一切还算满意。</p>
<h3 id="同事"><a href="#同事" class="headerlink" title="同事"></a>同事</h3><p>我其实是个不擅交际,怕生的人儿。因为我说话很笨,所以在新的环境想要和人混熟,总是要花更多的时间去处理这些关系。不过幸运的是遇到一群很好相处的同事,让我更容易的处理好这些问题。所以再后来遇到各种问题后我都是大胆的去问部门大神,充分发挥了死灿烂打的精神(这个三秒,市委应该深有体会)。当然作为一个胖纸,肯定也有一堆饭友,也会利用工作过的闲暇之余去腐败腐败。</p>
<h3 id="项目与加班"><a href="#项目与加班" class="headerlink" title="项目与加班"></a>项目与加班</h3><p>新东家的项目总是要得比较急,这就常常导致加班和代码的低质量产出。这是我最开始的想法,但到后来发现,诚然这两者是有一定的因果关系,但是有些东西本身就不可力抗(比如项目交付时间节点),如果一直持有因为时间导致自己加班这种心态,而不去提高自身的能力,那么不论你换到哪家公司你都会陷入无尽的加班与抱怨中。加班不可避免,那就努力提高自己,减少加班时间吧。</p>
<h3 id="技术浪潮"><a href="#技术浪潮" class="headerlink" title="技术浪潮"></a>技术浪潮</h3><p>这一年是技术浪潮爆发的一年。大数据、<code>AI</code>、人工智能、无人驾驶…各种技术名词频频见诸于头条新闻。在这喷薄的大浪中,前端领域也爆发出自己的色彩:<code>MVC</code>与<code>MVVC</code>、<code>stylus</code>,<code>less</code>与<code>sass</code>、<code>grunt</code>,<code>gulp</code>与<code>webpack</code>、<code>ng</code>,<code>react</code>与<code>vue</code>、<code>node</code>、大前端开发….等等,技术的更新换代不断地推动着前端领域的向前发展。作为一个前端开发者,深深的感受到我大前端的魅力,也越发对技术存有敬畏之心,不断的驱使我追赶它的浪潮,我愿意在它的浪潮中沉浮。</p>
<h3 id="我的Github"><a href="#我的Github" class="headerlink" title="我的Github"></a>我的Github</h3><p><code>github</code>是在2015年末注册的,期间一直不知怎么玩。在上半年,学习了<code>git</code>,喜欢使用命令行,也喜欢在<code>github</code>上提交一些东西,后面学习了<code>vue</code>后,慢慢的提交一些简单的<code>demo</code>上去,挺享受这个过程的。对了,我也通过<code>github</code>+<code>hexo</code>托管了一个静态博客,平时自己的写的东西也往上丢,不过貌似没坚持多久…..2017我会更加勤劳。</p>
<h3 id="换了个显示器"><a href="#换了个显示器" class="headerlink" title="换了个显示器"></a>换了个显示器</h3><p>这是一个不得不说的显示器:前端开发当然得用大的好的显示器,于是三秒写了一年的12Q换来一个帅气的显示器,从此以后心情舒畅,撸码不累,加班更勤。</p>
<h3 id="进步与不足"><a href="#进步与不足" class="headerlink" title="进步与不足"></a>进步与不足</h3><p>踩着2016的尾巴,我细数了2016发生在我身上的变化,虽有些许进步,但却也说不出个所以然,如果非要说,那么就是自己解决问题的能力强了,眼界开阔了,有自己的思考了,目标清晰了。<br>相对于进步,不足之处就很明显了,有很多也是我的致命伤,更是职业道路前进的致命伤。</p>
<ul>
<li>习惯<ul>
<li>有点小拖拉</li>
<li>三分钟热情</li>
<li>不仔细</li>
</ul>
</li>
<li>技术<ul>
<li>基础不够</li>
<li>没有创新</li>
<li>阅读很不够</li>
<li>至今没有代表作</li>
</ul>
</li>
</ul>
<p>有不足,能正视不足,更需要我弥补不足。</p>
<h2 id="滚滚而来的2017"><a href="#滚滚而来的2017" class="headerlink" title="滚滚而来的2017"></a>滚滚而来的2017</h2><p>2017年似乎要做的事情很多。一件件做,总有完成;一步步走,总有尽头。</p>
<h3 id="TODO"><a href="#TODO" class="headerlink" title="TODO"></a>TODO</h3><ul>
<li>EMAC 2016-2017</li>
<li>VUE,REACT</li>
<li>NODE</li>
<li>涨工资</li>
</ul>
<p>又是新的一年开启,新年愿有一番好景。</p>
]]></content>
<categories>
<category>record</category>
</categories>
<tags>
<tag>总结</tag>
</tags>
</entry>
<entry>
<title>Git系列之SSH Key配置</title>
<url>/2018-03-08/Git%E7%B3%BB%E5%88%97%E4%B9%8BSSH%20Key%E9%85%8D%E7%BD%AE.html</url>
<content><![CDATA[<blockquote>
<p>在使用Git进行版本控制时,SSH密钥是一种常见的身份验证方式。当你需要在同一台机器上管理多个Git账户时,如何配置和使用多个SSH密钥呢?本文将为你提供一份的教程</p>
</blockquote>
<h2 id="说明"><a href="#说明" class="headerlink" title="说明"></a>说明</h2><p>本篇文章以github仓库为例来进行说明</p>
<h2 id="生成新的SSH密钥"><a href="#生成新的SSH密钥" class="headerlink" title="生成新的SSH密钥"></a>生成新的SSH密钥</h2><p>首先,你需要为每个远程仓库生成一对SSH密钥。在终端中运行以下命令:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">ssh-keygen -t rsa -b 4096 -C <span class="string">"your_email@example.com"</span></span><br></pre></td></tr></table></figure>
<p>然后回车:</p>
<ul>
<li>提示设置密码<ul>
<li>如果不设置,直接按回车,然后会提示你确认密码,再按一次回车</li>
<li>如果设置密码,输入你想设置的密码,并确认,这样以后每次提交需要输入密码</li>
</ul>
</li>
<li>提示生成key的文件名<ul>
<li>如果不修改,则使用默认文件名<code>id_rsa</code></li>
<li>如果你有在该电脑管理多个key或者已经有生成的key占用了该文件名,则需要重命令</li>
</ul>
</li>
</ul>
<p>然后在用户主目录(如果是windows系统一般就在:C:\Users\Administrator.ssh, Mac系统一般是在~/.ssh目录)找到<code>.ssh</code>,其中<code>id_rsa</code>表示私钥不能泄露和<code>id_rsa.pub</code>表示公钥,用于对外。</p>
<p>可以使用不同的文件名来区分不同的密钥对,例如:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 工作仓库对于的ssh key</span></span><br><span class="line">~/.ssh/id_rsa_work</span><br><span class="line"><span class="comment"># github仓库对于的ssh key</span></span><br><span class="line">~/.ssh/id_rsa_github</span><br></pre></td></tr></table></figure>
<h2 id="SSH密钥的添加与代理"><a href="#SSH密钥的添加与代理" class="headerlink" title="SSH密钥的添加与代理"></a>SSH密钥的添加与代理</h2><p>生成密钥后,需要将它们添加到SSH代理中,以便Git可以使用它们。首先启动SSH代理:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">eval</span> <span class="string">"<span class="subst">$(ssh-agent -s)</span>"</span></span><br></pre></td></tr></table></figure>
<p>然后,将你的SSH密钥添加到代理中:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">ssh-add ~/.ssh/id_rsa_work</span><br><span class="line">ssh-add ~/.ssh/id_rsa_github</span><br></pre></td></tr></table></figure>
<h2 id="SSH配置文件的定制"><a href="#SSH配置文件的定制" class="headerlink" title="SSH配置文件的定制"></a>SSH配置文件的定制</h2><p>为了区分不同的远程仓库,编辑或创建SSH配置文件<code>~/.ssh/config</code>,为每个仓库配置一个规则:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">Host work.git</span><br><span class="line"> HostName work.example.com</span><br><span class="line"> User git</span><br><span class="line"> IdentityFile ~/.ssh/id_rsa_work</span><br><span class="line"></span><br><span class="line">Host github.git</span><br><span class="line"> HostName github.example.com</span><br><span class="line"> User github</span><br><span class="line"> IdentityFile ~/.ssh/id_rsa_github</span><br></pre></td></tr></table></figure>
<h2 id="添加SSH密钥到Git账户"><a href="#添加SSH密钥到Git账户" class="headerlink" title="添加SSH密钥到Git账户"></a>添加SSH密钥到Git账户</h2><p>现在,你需要将新的公钥(例如<code>~/.ssh/id_rsa_github.pub</code>)添加到对应的Git账户。你可以使用<code>cat</code>命令查看公钥:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">cat</span> ~/.ssh/id_rsa_github.pub</span><br></pre></td></tr></table></figure>
<p>然后,复制输出的内容,并将其添加到你的Git账户的SSH密钥部分。</p>
<h2 id="测试你的设置"><a href="#测试你的设置" class="headerlink" title="测试你的设置"></a>测试你的设置</h2><p>最后,你可以通过SSH到你的Git账户来测试你的设置:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">ssh -T git@github.com</span><br></pre></td></tr></table></figure>
<h2 id="SSH密钥的管理与维护"><a href="#SSH密钥的管理与维护" class="headerlink" title="SSH密钥的管理与维护"></a>SSH密钥的管理与维护</h2><p>随着时间推移,可能需要添加、删除或修改SSH密钥。使用<code>ssh-add</code>、<code>ssh-keygen</code>和<code>ssh-keyscan</code>等命令来管理你的SSH密钥。</p>
<h3 id="安全与权限"><a href="#安全与权限" class="headerlink" title="安全与权限"></a>安全与权限</h3><p>确保SSH私钥文件的权限设置正确,通常应为600(<code>chmod 600 id_rsa</code>)。不要将私钥文件泄露给未授权人员。</p>
<h3 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h3><p>通过上述步骤,你可以在Git中为不同的远程仓库配置多个SSH密钥,实现更高效的工作流程和更安全的代码管理。本文提供的终极指南将帮助你在多项目协作或使用多个Git服务提供商时游刃有余。</p>
<h3 id="常见问题解答"><a href="#常见问题解答" class="headerlink" title="常见问题解答"></a>常见问题解答</h3><ol>
<li><p><strong>Q:</strong> 我需要为每个远程仓库生成一个SSH密钥对吗?<br><strong>A:</strong> 是的,推荐为每个远程仓库生成一个单独的SSH密钥对,以实现更细粒度的访问控制。</p>
</li>
<li><p><strong>Q:</strong> 我可以同时添加多个SSH密钥到SSH代理吗?<br><strong>A:</strong> 可以,你可以使用<code>ssh-add</code>命令添加多个SSH密钥到SSH代理。</p>
</li>
<li><p><strong>Q:</strong> 如果我更换了计算机,如何迁移我的SSH密钥?<br><strong>A:</strong> 只需将<code>~/.ssh</code>目录下的私钥文件复制到新计算机的相应位置,并确保权限设置正确。</p>
</li>
<li><p><strong>Q:</strong> 如何确保我的SSH密钥安全?<br><strong>A:</strong> 除了设置正确的文件权限外,避免在不安全的网络环境下使用SSH密钥,并且不要将私钥文件泄露给其他人。</p>
</li>
</ol>
<p>通过这篇文章,你已经掌握了在Git中管理多个SSH密钥的关键技巧。这将帮助你在保证安全的同时,提高工作效率,更好地管理你的Git项目。</p>
]]></content>
<categories>
<category>工具/git</category>
</categories>
<tags>
<tag>git</tag>
<tag>ssh</tag>
<tag>ssh-key</tag>
</tags>
</entry>
<entry>
<title>Git系列常用命令之放弃修改</title>
<url>/2018-01-20/Git%E7%B3%BB%E5%88%97%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4%E4%B9%8B%E6%94%BE%E5%BC%83%E4%BF%AE%E6%94%B9.html</url>
<content><![CDATA[<blockquote>
<p>Git 是一种流行的分布式版本控制系统,它允许开发者在不同的分支上进行工作,同时保持代码的完整性和历史记录。在使用 Git 进行版本控制的过程中,我们可能会遇到需要放弃当前工作进度的情况,例如,当发现当前分支的修改与主分支的代码不兼容,或者需要切换到另一个分支继续工作时。</p>
</blockquote>
<h2 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h2><p>这篇文章会介绍如何在 Git 中放弃对文件的修改,包括以下几个方面:</p>
<ul>
<li>放弃对单个文件/文件夹的修改:如果只想放弃对某个特定文件的修改,可以使用 git checkout 命令。</li>
<li>放弃所有未提交的修改:如果需要放弃对所有未提交文件的修改,可以使用 git reset 命令。</li>
<li>撤销已经提交的更改:如果需要撤销已经提交但尚未推送到远程仓库的更改,可以使用 git revert 命令。</li>
<li>清理未跟踪的文件:有时候,你可能想要删除那些被错误添加到工作目录中但未被 Git 跟踪的文件,可以使用 git clean 命令。</li>
</ul>
<p>文章可能会通过具体的命令示例和场景,帮助读者理解在不同情况下如何使用 Git 命令来放弃修改,以保持工作流程的流畅和代码的整洁。</p>
<h2 id="两个概念"><a href="#两个概念" class="headerlink" title="两个概念"></a>两个概念</h2><p>在 Git 中,<code>index</code> 和 <code>commit</code> 是两个核心概念,它们在版本控制过程中扮演着不同的角色,理解这两个概念有助于加深对git工作原理的理解:</p>
<h3 id="Index(索引)"><a href="#Index(索引)" class="headerlink" title="Index(索引)"></a>Index(索引)</h3><ul>
<li>Index 是 Git 用来准备下一次提交的暂存区。你可以将其视为一个准备提交的文件列表,这些文件已经被审查和选择,准备成为下一次提交的一部分。</li>
<li>当你对工作目录中的文件进行更改并希望将这些更改包含在下一次提交中时,你需要使用 <code>git add</code> 命令将它们添加到 index 中。</li>
<li>Index 允许你在提交之前进行多次修改,并且可以对这些修改进行排序和组织,以确保提交是有意义的。</li>
<li>Index 是一个文件,位于 <code>.git/index</code> 文件中。</li>
</ul>
<h3 id="Commit(提交)"><a href="#Commit(提交)" class="headerlink" title="Commit(提交)"></a>Commit(提交)</h3><ul>
<li><p>Commit 是项目快照的记录,它包含了项目的某个特定版本。当你执行 <code>git commit</code> 命令时,Git 会将当前 index 中的内容以及一些附加的元数据(如提交信息、作者、时间戳等)打包成一个提交对象,并存储在本地仓库中。</p>
</li>
<li><p>提交是不可变的,意味着一旦创建,其内容就不能被更改。这保证了项目历史的完整性和一致性。</p>
</li>
<li><p>提交可以看作是项目的版本号,每个提交都有一个唯一的哈希值,用于标识和引用特定的项目状态。</p>
</li>
<li><p>提交是 Git 分布式特性的基础,因为它允许开发者在本地进行提交,而不必立即与远程仓库同步。</p>
</li>
</ul>
<p>两者之间的关系可以这样理解:</p>
<ul>
<li>你首先对文件进行修改。</li>
<li>使用 <code>git add</code> 将这些修改的文件添加到 index 中,这时候修改被暂存,准备提交。</li>
<li>使用 <code>git commit</code> 将 index 中的内容以及提交信息一起打包,创建一个新的提交对象。</li>
</ul>
<p>简而言之,index 是准备提交的暂存区,而 commit 是已经提交的快照记录。在进行提交之前,你可以多次修改 index,但是一旦执行了 commit,那么这个提交就是最终的,不可更改的。</p>
<p>请深刻理解这两个概念,有助于帮助您理解后面的内容</p>
<h2 id="命令"><a href="#命令" class="headerlink" title="命令"></a>命令</h2><h3 id="Git-Checkout-切换分支或恢复工作目录树文件"><a href="#Git-Checkout-切换分支或恢复工作目录树文件" class="headerlink" title="Git Checkout - 切换分支或恢复工作目录树文件"></a>Git Checkout - 切换分支或恢复工作目录树文件</h3><blockquote>
<p>更新工作区中的文件,使其与索引或指定的树中的版本一致。 如果没有给出pathspec,’git checkout’也将更新<code>HEAD</code>,将指定的分支设为当前分支</p>
</blockquote>
<p>使用git checkout来切换分支用的很多,但是没想到还可以用来恢复工作目录,可以理解为:<br>将一个文件从另一个提交中取出,从索引中恢复,所以它不会影响到git add及之后的内容。</p>
<p>具体用法如下:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git checkout -- <filename></span><br></pre></td></tr></table></figure>
<p>注意这里的filename是支持通配符匹配的,比如</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 恢复hello.html</span></span><br><span class="line">git checkout -- hello.html</span><br><span class="line"></span><br><span class="line"><span class="comment"># 恢复hello.开头的文件</span></span><br><span class="line">git checkout -- <span class="string">"hello.*"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 恢复.html结尾的文件</span></span><br><span class="line">git checkout -- *.html</span><br></pre></td></tr></table></figure>
<blockquote>
<p>注意此方法只是将本地文件恢复了,没有对git add 和git commit 产生影响</p>
</blockquote>
<h3 id="Git-reset-重置当前HEAD到指定的状态"><a href="#Git-reset-重置当前HEAD到指定的状态" class="headerlink" title="Git-reset - 重置当前HEAD到指定的状态"></a>Git-reset - 重置当前HEAD到指定的状态</h3><blockquote>
<p>复制条目到索索引或者将当前的分支头(<code>HEAD</code>)设置为某个commit</p>
</blockquote>
<h3 id="Git-revert-还原某些现有提交"><a href="#Git-revert-还原某些现有提交" class="headerlink" title="Git-revert - 还原某些现有提交"></a>Git-revert - 还原某些现有提交</h3><blockquote>
<p>给定一个或多个现有提交,还原相关补丁引入的更改,并记录一些新提交来记录这些更改。 这要求你的工作区是干净的(没有对 HEAD 提交的修改)。</p>
</blockquote>
<h3 id="Git-clean-删除工作目录树中未跟踪的文件"><a href="#Git-clean-删除工作目录树中未跟踪的文件" class="headerlink" title="Git-clean - 删除工作目录树中未跟踪的文件"></a>Git-clean - 删除工作目录树中未跟踪的文件</h3><blockquote>
<p>从当前目录开始,通过递归删除不在版本控制之下的文件来清理工作区。<br>通常情况下,只有 Git 未知的文件会被删除,但如果指定了 <code>-x</code> 选项,被忽略的文件也会被删除。例如,这对删除所有构建产品很有用。<br>如果给出任何可选的<code><路径规范>…</code>参数,只有那些与路径规范相匹配的路径会受到影响</p>
</blockquote>
<h2 id="一些常见场景"><a href="#一些常见场景" class="headerlink" title="一些常见场景"></a>一些常见场景</h2><h3 id="本地修改了一些文件-并没有使用-Git-Add-到暂存区-,想放弃修改"><a href="#本地修改了一些文件-并没有使用-Git-Add-到暂存区-,想放弃修改" class="headerlink" title="本地修改了一些文件 (并没有使用 Git Add 到暂存区),想放弃修改"></a>本地修改了一些文件 (并没有使用 Git Add 到暂存区),想放弃修改</h3><ul>
<li> 单个文件/文件夹:</li>
</ul>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git checkout -- <filename></span><br></pre></td></tr></table></figure>
<ul>
<li> 所有文件/文件夹:</li>
</ul>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git checkout .</span><br></pre></td></tr></table></figure>
<h3 id="本地新增了一些文件-并没有-Git-Add-到暂存区-,想放弃修改"><a href="#本地新增了一些文件-并没有-Git-Add-到暂存区-,想放弃修改" class="headerlink" title="本地新增了一些文件 (并没有 Git Add 到暂存区),想放弃修改"></a>本地新增了一些文件 (并没有 Git Add 到暂存区),想放弃修改</h3><ul>
<li> 单个文件/文件夹:</li>
</ul>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">rm</span> -rf <filename></span><br></pre></td></tr></table></figure>
<ul>
<li> 所有文件</li>
</ul>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git clean -xdf</span><br></pre></td></tr></table></figure>
<blockquote>
<p>删除新增的文件,如果文件已经已经 git add 到暂存区,并不会删除!</p>
</blockquote>
<ul>
<li> 所有文件和文件夹:</li>
</ul>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git clean -xdff</span><br></pre></td></tr></table></figure>
<blockquote>
<p>ps:谨慎操作: 本命令删除新增的文件和文件夹,如果文件已经已经 git add 到暂存区,并不会删除!</p>
</blockquote>
<h3 id="本地修改-新增了一些文件,已经-Git-Add-到暂存区,想放弃修改"><a href="#本地修改-新增了一些文件,已经-Git-Add-到暂存区,想放弃修改" class="headerlink" title="本地修改/新增了一些文件,已经 Git Add 到暂存区,想放弃修改"></a>本地修改/新增了一些文件,已经 Git Add 到暂存区,想放弃修改</h3><ul>
<li> 单个文件/文件夹:</li>
</ul>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git reset HEAD <filename></span><br></pre></td></tr></table></figure>
<ul>
<li> 所有文件/文件夹:</li>
</ul>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git reset HEAD .</span><br></pre></td></tr></table></figure>
<h3 id="本地通过-Git-Add-和-Git-Commit-后,想要撤销此次-Commit"><a href="#本地通过-Git-Add-和-Git-Commit-后,想要撤销此次-Commit" class="headerlink" title="本地通过 Git Add 和 Git Commit 后,想要撤销此次 Commit"></a>本地通过 Git Add 和 Git Commit 后,想要撤销此次 Commit</h3><ul>
<li>撤销 commit, 同时保留该 commit 修改:</li>
</ul>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git reset <commit_id></span><br></pre></td></tr></table></figure>
<p>这个 <code>commit_id</code> 是你想要回到的那个节点,可以通过 git log 查看,可以只选前 6 位。</p>
<blockquote>
<p>撤销之后,你所做的已经 commit 的修改还在工作区!</p>
</blockquote>
<ul>
<li> 撤销 commit, 同时本地删除该 commit 修改:</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">git reset --hard <commit_id></span><br></pre></td></tr></table></figure>
<p>这个 <code>commit_id</code> 是你想要回到的那个节点,可以通过 git log 查看,可以只选前6位</p>
<blockquote>
<p>ps:谨慎操作: 撤销之后,你所做的已经 commit 的修改将会清除,仍在工作区/暂存区的代码也将会清除!</p>
</blockquote>
<h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><p>1.<span class="exturl" data-url="aHR0cHM6Ly9naXQtc2NtLmNvbS9kb2NzL2dpdC1jaGVja291dC96aF9IQU5TLUNO">Git - git-checkout Documentation<i class="fa fa-external-link-alt"></i></span><br>2.<span class="exturl" data-url="aHR0cHM6Ly9naXQtc2NtLmNvbS9kb2NzL2dpdC1yZXNldC96aF9IQU5TLUNO">Git - git-reset Documentation<i class="fa fa-external-link-alt"></i></span><br>3.<span class="exturl" data-url="aHR0cHM6Ly9naXQtc2NtLmNvbS9kb2NzL2dpdC1yZXZlcnQvemhfSEFOUy1DTg==">Git - git-revert Documentation<i class="fa fa-external-link-alt"></i></span><br>4.<span class="exturl" data-url="aHR0cHM6Ly9naXQtc2NtLmNvbS9kb2NzL2dpdC1jbGVhbi96aF9IQU5TLUNO">Git - git-clean Documentation<i class="fa fa-external-link-alt"></i></span></p>
]]></content>
<categories>
<category>工具/git</category>
</categories>
<tags>
<tag>git</tag>
</tags>
</entry>
<entry>
<title>Mac提示”xxx.app已损坏,无法打开,你应该将它移到废纸篓”的解决方法</title>
<url>/2021-09-14/Mac%E6%8F%90%E7%A4%BA%E2%80%9Dxxx.app%E5%B7%B2%E6%8D%9F%E5%9D%8F%EF%BC%8C%E6%97%A0%E6%B3%95%E6%89%93%E5%BC%80%EF%BC%8C%E4%BD%A0%E5%BA%94%E8%AF%A5%E5%B0%86%E5%AE%83%E7%A7%BB%E5%88%B0%E5%BA%9F%E7%BA%B8%E7%AF%93%E2%80%9D%E7%9A%84%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95.html</url>
<content><![CDATA[<p>随着mac系统的升级,对app安全控制越来越严,经常遇到一些非官方渠道安装的app,安装后无法打开的情况,如提示”xxx.app已损坏,无法打开,你应该将它移到废纸篓”,一般情况下,出现该问题是因为软件没有签名,所以被MAC系统禁止运行。可以尝试以下解决方案</p>
<h2 id="老系统:设置允许任何来源下载的App"><a href="#老系统:设置允许任何来源下载的App" class="headerlink" title="老系统:设置允许任何来源下载的App"></a>老系统:设置允许任何来源下载的App</h2><p>比较老的版本系统,可以按以下步骤操作:<br>打开”系统偏好设置 -> 安全与隐私 -> 通用”选项卡,检查是否已经启用了”任何来源”选项。如果没有启用,先点击左下角的小黄锁图标解锁,然后选中”任何来源”。(由于作者mac系统比较新,故此图来源网络)<br><img data-src="https://raw.githubusercontent.com/2ue/post-files/main/files/20240424125739-50d88ba9028afaa7fbbfd06d2ff6c107-1713934660.png" alt="image.png"></p>
<p>如果没有”任何来源”的选项,打开终端,输入以下命令:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">sudo spctl --master-disable</span><br></pre></td></tr></table></figure>
<p><code>sudo spctl --master-disable</code> 是一个在macOS操作系统中使用的命令行指令,用于修改系统安全策略控制(System Integrity Protection,简称SIP)的设置。SIP 是一种安全特性,用于保护系统文件和目录免受未授权的修改。</p>
<p><code>sudo spctl --master-disable</code> 的作用如下:</p>
<ol>
<li><strong>禁用 SIP</strong>:这个命令会禁用 SIP 功能,允许用户对系统文件进行修改。默认情况下,macOS 会阻止对某些系统文件和目录的修改,以保护系统安全。</li>
<li><strong>需要管理员权限</strong>:由于这个命令涉及到系统级别的更改,因此需要使用 <code>sudo</code> 来获取管理员权限。</li>
<li><strong>临时禁用</strong>:这个命令的禁用效果是临时的,重启计算机后 SIP 会重新启用。</li>
<li><strong>安全性风险</strong>:禁用 SIP 会降低系统的安全性,因为它允许对系统文件进行修改。因此,只有在确实需要修改系统文件时才应该使用这个命令,并且在完成修改后应立即重新启用 SIP。</li>
<li><strong>重新启用 SIP</strong>:要重新启用 SIP,可以使用 <code>sudo spctl --master-enable</code> 命令。</li>
</ol>
<p>一般来讲到这一步就可以了,但是如果你的系统比较新,你还得继续看下去</p>
<h2 id="新系统:使用xattr-rd命令"><a href="#新系统:使用xattr-rd命令" class="headerlink" title="新系统:使用xattr -rd命令"></a>新系统:使用xattr -rd命令</h2><p>如果你的系统比较新,或者已经打开了通用 > 信任任何来源安装后还是报错,那么在终端里执行以下命令: </p>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line"><span class="built_in">sudo</span> xattr -rd com.apple.quarantine /Applications/xxxx.app</span><br><span class="line"><span class="comment"># 将xxx替换成app的名字,如果你无法准确知道app名称,可以直接将app拖到终端中</span></span><br><span class="line"><span class="comment"># 按提示输入你的电脑密码即可。</span></span><br></pre></td></tr></table></figure>
<p><code>sudo xattr -rd com.apple.quarantine /Applications/xxxx.app</code> 是一个在macOS操作系统中使用的命令行指令,它用于移除文件或应用程序的扩展属性(extended attribute),具体来说,是移除一个名为 <code>com.apple.quarantine</code> 的属性。</p>
<p>这个属性通常在文件或应用程序从互联网下载后被添加,作为macOS的一种安全机制。它提示用户,该文件可能来自不信任的来源,需要确认是否信任并运行该应用程序。这个属性有时也被称为”隔离标记”(quarantine flag)。</p>
<p>命令的各个部分含义如下:</p>
<ol>
<li><code>sudo</code>:以管理员权限执行后面的命令。由于修改文件的扩展属性需要管理员权限,所以这里使用 <code>sudo</code>。</li>
<li><code>xattr</code>:这是用于查看和修改文件扩展属性的命令行工具。</li>
<li><code>-rd</code>:<code>-r</code> 表示递归地移除属性,<code>-d</code> 表示删除指定的属性。</li>
<li><code>com.apple.quarantine</code>:这是要删除的扩展属性的名称。</li>
<li><code>/Applications/xxxx.app</code>:这是要移除隔离标记的应用程序的路径。<code>xxxx.app</code> 应该替换为实际的应用程序名称。</li>
</ol>
<p>使用这个命令后,应用程序将不再显示警告,提示它可能来自互联网。这在安装从可信来源下载的应用程序时很有用,尤其是当用户确信该应用程序是安全的,但macOS仍然显示隔离警告时。</p>
]]></content>
<categories>
<category>mac</category>
</categories>
<tags>
<tag>mac</tag>
<tag>app损坏</tag>
</tags>
</entry>
<entry>
<title>移动端适配方案</title>
<url>/2016-11-22/Mobile-terminal-adapter.html</url>
<content><![CDATA[<blockquote>
<p>移动端越来越被大众所接收,那么相应的技术就越来越向它靠拢,这是一种不可阻挡的趋势,也是万物发展的规律。移动端有三大难题:兼容、调试和适配。这三大问题就好像三座无法逾越的大山阻挡者我们前进的步伐,此文将记录我在项目中关于移动端适配的一些方式,供大家参考</p>
</blockquote>
<h2 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h2><p>移动端适配的根本原因</p>
<ul>
<li>屏幕窗口的大小</li>
<li>设备像素比(devicepixelratio,简称dpr)</li>
</ul>
<p>很多地方介绍设备像素比的,这里就不做具体探讨,简单总结一下:<code>devicepixelratio</code>(设备像素比,即dpr) = <code>physicalpixel</code> (物理像素) / <code>density-independent pixel</code>(设备独立像素,即dip)。<code>dip</code>或<code>dp</code>,(<code>device independent pixels</code>,设备独立像素)与屏幕密度有关。<code>dip</code>可以用来辅助区分视网膜设备还是非视网膜设备。<br>在<code>JavaScript</code>中,可以通过<code>window.devicePixelRatio</code>获取到当前设备的dpr,但遗憾的是并不是所有的都支持。<br>在CSS中,可以分别针对屏幕大小和设备像素比做适配:<br>针对窗口大小,一般使用媒体查询的<code>only screen</code>、<code>min-width</code>、<code>max-width</code>来适配,也是使用<code>css</code>做适配最常见的一种方式<br>针对像素比,可以使用<code>-webkit-device-pixel-ratio</code>,<code>-webkit-min-device-pixel-ratio</code>和 <code>-webkit-max-device-pixel-ratio</code>属性,同样他的支持度一样不高(其实是很低),所以几乎没有用武之地。</p>
<h2 id="适配方式"><a href="#适配方式" class="headerlink" title="适配方式"></a>适配方式</h2><p>移动端适配主要有两大不同的方向:</p>
<ul>
<li>响应式布局:它是根据屏幕大小自动的调整布局位置(非单纯的缩放),实现适配</li>
<li>自适应布局:它是根据屏幕大小自动的缩放大小,实现适配。</li>
</ul>
<p>两种方式应用的场景不同,各有优劣,本人对自适应布局使用的比较多</p>
<h2 id="解决方案"><a href="#解决方案" class="headerlink" title="解决方案"></a>解决方案</h2><p>为了解决这个老大难问题,从最初开始百分比到<code>em</code>,然后到现在<code>rem</code>的使用,都一一体现着技术的滚滚向前。目前是用的最多的也就是<code>rem</code>,他们的区别和有点请自行<code>GG</code>。<br>有了<code>rem</code>这个大杀器,解决问题就变得简单起来,具体请往下看。</p>
<h2 id="纯css实现方式-–-媒体查询"><a href="#纯css实现方式-–-媒体查询" class="headerlink" title="纯css实现方式 – 媒体查询"></a>纯css实现方式 – 媒体查询</h2><p>使用原生<code>css</code>来实现媒体查询是很繁琐的,因为每个媒体查询都要去设定规则。推荐使用<code>css</code>的预编译器(sass,less,stylus),比较方便。</p>
<figure class="highlight css"><table><tr><td class="code"><pre><span class="line"><span class="comment">/* 定义规则 */</span></span><br><span class="line"><span class="selector-tag">html</span> {</span><br><span class="line"> <span class="attribute">font-size</span>: <span class="number">20px</span>;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">@media</span> <span class="keyword">only</span> screen <span class="keyword">and</span> (<span class="attribute">min-width</span>: <span class="number">401px</span>) {</span><br><span class="line"> <span class="selector-tag">html</span> {</span><br><span class="line"> <span class="attribute">font-size</span>: <span class="number">24px</span> <span class="meta">!important</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">@media</span> <span class="keyword">only</span> screen <span class="keyword">and</span> (<span class="attribute">min-width</span>: <span class="number">428px</span>) {</span><br><span class="line"> <span class="selector-tag">html</span> {</span><br><span class="line"> <span class="attribute">font-size</span>: <span class="number">28</span> <span class="meta">!important</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">@media</span> <span class="keyword">only</span> screen <span class="keyword">and</span> (<span class="attribute">min-width</span>: <span class="number">481px</span>) {</span><br><span class="line"> <span class="selector-tag">html</span> {</span><br><span class="line"> <span class="attribute">font-size</span>: <span class="number">30px</span> <span class="meta">!important</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">@media</span> <span class="keyword">only</span> screen <span class="keyword">and</span> (<span class="attribute">min-width</span>: <span class="number">569px</span>) {</span><br><span class="line"> <span class="selector-tag">html</span> {</span><br><span class="line"> <span class="attribute">font-size</span>: <span class="number">35px</span> <span class="meta">!important</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">@media</span> <span class="keyword">only</span> screen <span class="keyword">and</span> (<span class="attribute">min-width</span>: <span class="number">641px</span>) {</span><br><span class="line"> <span class="selector-tag">html</span> {</span><br><span class="line"> <span class="attribute">font-size</span>: <span class="number">40px</span> <span class="meta">!important</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">@media</span> <span class="keyword">only</span> screen <span class="keyword">and</span> (<span class="attribute">min-width</span>: <span class="number">751px</span>) {</span><br><span class="line"> <span class="selector-tag">html</span> {</span><br><span class="line"> <span class="attribute">font-size</span>: <span class="number">50px</span> <span class="meta">!important</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">@media</span> <span class="keyword">only</span> screen <span class="keyword">and</span> (<span class="attribute">min-width</span>: <span class="number">1080px</span>) {</span><br><span class="line"> <span class="selector-tag">html</span> {</span><br><span class="line"> <span class="attribute">font-size</span>: <span class="number">60px</span> <span class="meta">!important</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<figure class="highlight less"><table><tr><td class="code"><pre><span class="line"><span class="comment">//less 方式调用</span></span><br><span class="line"><span class="variable">@unit:</span> <span class="number">50rem</span>; <span class="comment">//基准单位,根据设计稿来确定。假设:设计稿尺寸为750,那么@unit设置为50rem(1rem=50px更方便下面计算)</span></span><br><span class="line"><span class="selector-class">.warp</span>{with: 100 / @unit} <span class="comment">// 设计稿上元素的尺寸为100px => .warp{with: 2rem}</span></span><br><span class="line"><span class="selector-class">.warp</span>{with: 10 / @unit} <span class="comment">// 设计稿上元素的尺寸为10px => .warp{with: 0.2rem}</span></span><br></pre></td></tr></table></figure>
<p>如果这里使用原生<code>css</code>来做,每个尺寸都需要去计算,如果使用预处理器,只需要定义一个变量,计算的事情直接交给它们就行。</p>
<p>这样当页面展示在<code>750</code>的屏幕上时,html的<code>font-size</code>为<code>50px</code>,那么当设置为2rem的元素显示的尺寸就为<code>2*50px=100px</code>。在其他尺寸的设备也会根据媒体查询设置的不同<code>font-size</code>进行自动缩放适配。<br>当然上面也提到了,在<code>css</code>中也是可以获取到<code>devicePixelRatio</code>的值,那么为了更精确在写媒体查询的时候可以把它也加上去,这里就不展开了。</p>
<h2 id="纯css实现方式-–-计算属性"><a href="#纯css实现方式-–-计算属性" class="headerlink" title="纯css实现方式 – 计算属性"></a>纯css实现方式 – 计算属性</h2><p>当然除了媒体查询,还有一种更潮的方式就是利用css3的一些新属性:计算属性和<code>vw</code>属性来实现自动设置根字体大小的目的</p>
<figure class="highlight css"><table><tr><td class="code"><pre><span class="line"><span class="selector-tag">html</span>{<span class="attribute">font-size</span>:<span class="built_in">calc</span>(<span class="number">100vw</span>/<span class="number">6.4</span>)} //<span class="number">6.4</span>为psd设计稿尺寸/<span class="number">100</span></span><br></pre></td></tr></table></figure>
<p>这套方案几乎是目前最简洁的方案了,并且<code>calc</code>和<code>vw</code>在移动端的支持也不错哟。</p>
<h2 id="js的实现方式"><a href="#js的实现方式" class="headerlink" title="js的实现方式"></a>js的实现方式</h2><p>js的实现方式,参考了<code>网易</code>和<code>淘宝</code>的实现方式,对他们进行了整合。并且修复了手机端<code>1px问题</code>。</p>
<ul>
<li><code>网易实现方式</code>是通过设备尺寸动态的设置DOM的根元素字体大小,没有考虑devicePixelRatio的因素;</li>
<li><code>淘宝实现方式</code>也是通过设备尺寸动态的设置DOM的根元素字体大小,并且考虑了devicePixelRatio的因素,但淘宝在设置rem时,显得较复杂(不方便写css把px转化成rem);</li>
<li><code>1px问</code>题简单点说就是因为<code>devicePixelRatio</code>的存在,css的1px不等于移动端的1px。</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line">(<span class="keyword">function</span>(<span class="params">doc, win, designSize</span>) { <span class="comment">//designSize为设计稿的尺寸(宽)</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">var</span> docEl = <span class="variable language_">document</span>.<span class="property">documentElement</span>,</span><br><span class="line"> devWidth = docEl.<span class="property">clientWidth</span> > <span class="number">1080</span> ? <span class="number">1080</span> : docEl.<span class="property">clientWidth</span>,</span><br><span class="line"> dpr = devicePixelRatio || <span class="number">1</span>,</span><br><span class="line"> scale = <span class="number">1</span> / dpr,</span><br><span class="line"> width = dpr * devWidth,</span><br><span class="line"> resizeEvt = <span class="string">'orientationchange'</span> <span class="keyword">in</span> <span class="variable language_">window</span> ? <span class="string">'orientationchange'</span> : <span class="string">'onresize'</span>, <span class="comment">//判断横屏和窗口重置</span></span><br><span class="line"> recalc = <span class="keyword">function</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">var</span> clientWidth = docEl.<span class="property">clientWidth</span>;</span><br><span class="line"> <span class="keyword">if</span> (!clientWidth) <span class="keyword">return</span>;</span><br><span class="line"> <span class="variable language_">document</span>.<span class="title function_">querySelector</span>(<span class="string">'meta[name="viewport"]'</span>)</span><br><span class="line"> .<span class="title function_">setAttribute</span>(<span class="string">'content'</span>,<span class="string">'width='</span> + width +</span><br><span class="line"> <span class="string">', initial-scale='</span> + scale +</span><br><span class="line"> <span class="string">', maximum-scale='</span> + scale +</span><br><span class="line"> <span class="string">', minimum-scale='</span> + scale +</span><br><span class="line"> <span class="string">', user-scalable=no'</span>);</span><br><span class="line"> docEl.<span class="property">style</span>.<span class="property">fontSize</span> = devWidth / (designSize / <span class="number">100</span>) * dpr + <span class="string">'px'</span>;</span><br><span class="line"> };</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (!doc.<span class="property">addEventListener</span>) <span class="keyword">return</span>;</span><br><span class="line"> win.<span class="title function_">addEventListener</span>(resizeEvt, recalc, <span class="literal">false</span>);</span><br><span class="line"> doc.<span class="title function_">addEventListener</span>(<span class="string">'DOMContentLoaded'</span>, recalc, <span class="literal">false</span>);</span><br><span class="line"></span><br><span class="line">})(<span class="variable language_">document</span>, <span class="variable language_">window</span>, <span class="number">750</span>);</span><br></pre></td></tr></table></figure>
<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><ul>
<li>以上三种方案对比,第一种媒体查询是最死板的,基本就是纯体力活。</li>
<li>利用<code>css</code>的计算属性可以很优雅的解决问题,但是在兼容方面来说,目前还不是很完美</li>
<li>并且利用纯<code>css</code>也没考虑<code>devicePixelRatio</code>(像素问题)这个因素。</li>
<li>最后的<code>javascript</code>解决方案则是考虑到了兼容和<code>devicePixelRatio</code>这些因素,但是这里有一个很大的弊端就是:页面在某些情况(性能慢)会经过两次重回(给<code>HTML</code>根设置<code>font-size</code>和设置<code>meta</code>标签时),在网络或者终端性能不是很好的情况用户体验很不错甚至页面错乱的情况。</li>
</ul>
]]></content>
<categories>
<category>javascript</category>
</categories>
<tags>
<tag>rem</tag>
<tag>mobile</tag>
</tags>
</entry>
<entry>
<title>Node.js开发必看系列之-如何在ES模块中正确使用__dirname和__filename</title>
<url>/2024-05-26/Node.js%E5%BC%80%E5%8F%91%E5%BF%85%E7%9C%8B%E7%B3%BB%E5%88%97%E4%B9%8B-%E5%A6%82%E4%BD%95%E5%9C%A8ES%E6%A8%A1%E5%9D%97%E4%B8%AD%E6%AD%A3%E7%A1%AE%E4%BD%BF%E7%94%A8__dirname%E5%92%8C__filename.html</url>
<content><![CDATA[<h2 id="引言"><a href="#引言" class="headerlink" title="引言"></a>引言</h2><p>在Node.js中,<code>__dirname</code>是一个非常有用的全局变量,它返回当前正在执行的脚本所在的目录名。然而,随着Node.js对ES模块(ESM)的支持,直接在ES模块中使用<code>__dirname</code>会导致“<code>__dirname is not defined in ES module scope</code>”的错误信息。本文将探讨这一问题,并提供有效的解决方案。</p>
<h2 id="理解ES模块与CommonJS"><a href="#理解ES模块与CommonJS" class="headerlink" title="理解ES模块与CommonJS"></a>理解ES模块与CommonJS</h2><ul>
<li><strong>CommonJS</strong>:主要用于服务器端编程,特别是在Node.js环境中。它通过<code>require()</code>方法加载模块,并通过<code>module.exports</code>或<code>exports</code>导出功能。</li>
<li><strong>ES模块</strong>:由ECMAScript标准定义,旨在提供一个标准化的模块化解决方案,适用于浏览器和服务器端。ES模块通过<code>import</code>和<code>export</code>关键字来管理依赖关系。</li>
</ul>
<p><strong>为什么ES模块不支持<code>__dirname</code>和<code>__filename</code>等CommonJS变量?</strong></p>
<p>ES模块的设计理念与CommonJS不同,它更注重标准化和跨平台兼容性。因此,ES模块并没有直接提供像<code>__dirname</code>这样的变量。相反,ES模块提供了<code>import.meta</code>对象来获取模块的元数据。</p>
<h2 id="在ES模块中使用-dirname和-filename的替代方案"><a href="#在ES模块中使用-dirname和-filename的替代方案" class="headerlink" title="在ES模块中使用__dirname和__filename的替代方案"></a>在ES模块中使用<code>__dirname</code>和<code>__filename</code>的替代方案</h2><p>由于ES模块的设计理念不同,它并不支持<code>__dirname</code>这样的CommonJS变量。但是,ES模块引入了<code>import.meta</code>对象,该对象包含了一些元数据,其中包括<code>url</code>属性,可以用来获取当前模块的URL地址。</p>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="comment">// ES模块中获取当前文件的绝对路径</span></span><br><span class="line"><span class="keyword">import</span> { fileURLToPath } <span class="keyword">from</span> <span class="string">'url'</span>;</span><br><span class="line"><span class="keyword">import</span> path <span class="keyword">from</span> <span class="string">'path'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> __filename = <span class="title function_">fileURLToPath</span>(<span class="keyword">import</span>.<span class="property">meta</span>.<span class="property">url</span>);</span><br><span class="line"><span class="keyword">const</span> __dirname = path.<span class="title function_">dirname</span>(__filename);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`当前文件所在目录: <span class="subst">${__dirname}</span>`</span>);</span><br></pre></td></tr></table></figure>
<p>这段代码首先使用<code>fileURLToPath</code>将<code>import.meta.url</code>转换成文件路径,然后利用<code>path.dirname()</code>函数获取文件所在的目录名称。</p>
<h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ul>
<li><span class="exturl" data-url="aHR0cHM6Ly9ub2RlanMub3JnL2FwaS9lc20uaHRtbA==">Node.js官方文档 - ES Modules<i class="fa fa-external-link-alt"></i></span></li>
<li><span class="exturl" data-url="aHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvU3RhdGVtZW50cy9pbXBvcnQubWV0YQ==">MDN Web Docs - import.meta<i class="fa fa-external-link-alt"></i></span></li>
<li><span class="exturl" data-url="aHR0cHM6Ly9ub2RlanMub3JnL2FwaS91cmwuaHRtbA==">Node.js官方文档 - URL Module<i class="fa fa-external-link-alt"></i></span></li>
</ul>
]]></content>
<categories>
<category>前端/Nodejs</category>
</categories>
<tags>
<tag>Nodejs</tag>
<tag>__dirname</tag>
<tag>__filename</tag>
</tags>
</entry>
<entry>
<title>Oh My Zsh 自动化:轻松管理多个 Git 用户身份信息</title>
<url>/2024-04-23/Oh%20My%20Zsh%20%E8%87%AA%E5%8A%A8%E5%8C%96-%E8%BD%BB%E6%9D%BE%E7%AE%A1%E7%90%86%E5%A4%9A%E4%B8%AA%20Git%20%E7%94%A8%E6%88%B7%E8%BA%AB%E4%BB%BD%E4%BF%A1%E6%81%AF.html</url>
<content><![CDATA[<blockquote>
<p>在 Git 工作流中,有时需要在同一台电脑上针对不同的项目设置不同的用户身份。例如,开发人员可能需要在个人项目和公司项目之间切换,而这两个项目可能需要不同的 Git 用户名和电子邮件地址。Oh My Zsh 提供了强大的自定义功能,允许我们通过编写自定义的 shell 函数来实现这一需求。本文将展示如何使用 Oh My Zsh 的 <code>chpwd</code> 函数来自动设置特定目录及其子目录、孙目录下的 Git 用户配置。</p>
</blockquote>
<h2 id="开始之前"><a href="#开始之前" class="headerlink" title="开始之前"></a>开始之前</h2><p>假设你对git身份信息和ssh key概念有比较清晰的认识和了解其基础使用,比如git身份信息是用户名和邮箱,在你使用git commit的时候进行记录;而ssh key是一个凭证(分为公钥和私钥),用于远端身份信息验证,和git没有直接关系,也可以用于其他场景使用,比如ssh登录远程主机。</p>
<p>简单说下为什么要使用不同的git身份信息呢?<br>公司项目要求使用规定的name(比如企微名,花名或者公司内部系统的唯一标识等)和email(公司邮箱)作为git提交记录,这样方便团队协作和代码管理,这些信息有一定的敏感性。所有在提交代码到外网的时候必须考虑使用不同的git身份信息来提交。</p>
<p>当然我们可以在每次克隆一个新项目的时候,根据不同需要使用git config –local进行设置,但这明手动操作容易遗忘而且繁琐,所以想到使用脚本来自动化完成。</p>
<h2 id="最终效果"><a href="#最终效果" class="headerlink" title="最终效果"></a>最终效果</h2><p>本文不是解决:不同的远程仓库(比如github和gitee,公司自建的gitlab等)使用不同的ssh key凭证这个问题,而且为了解决以下问题:</p>
<ul>
<li>不同的远程仓库(比如github和gitee,公司自建的gitlab等)使用不同的git身份信息</li>
</ul>
<p>最终想达到:</p>
<ul>
<li>进入到指定目录及其子目录,孙目录,如果是git仓库,就自动设置对应的git身份信息</li>
</ul>
<h3 id="约定目录结构:"><a href="#约定目录结构:" class="headerlink" title="约定目录结构:"></a>约定目录结构:</h3><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">/Users/developer/teamA # 根目录</span><br><span class="line"> └── projectA # 子目录,团队项目</span><br><span class="line"> └── src # 孙目录</span><br><span class="line"></span><br><span class="line">/Users/developer/teamB</span><br></pre></td></tr></table></figure>
<h2 id="解决方案"><a href="#解决方案" class="headerlink" title="解决方案"></a>解决方案</h2><p>解决这个问题的方案有很多,下面分享一种使用zsh脚本的方案。首先无论哪一种方案,都需要在全局设置全局git信息:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">git config --global user.name "name1"</span><br><span class="line">git config --global user.email"email1@email.com"</span><br></pre></td></tr></table></figure>
<h3 id="安装-Oh-My-Zsh"><a href="#安装-Oh-My-Zsh" class="headerlink" title="安装 Oh My Zsh"></a>安装 Oh My Zsh</h3><p>如果尚未安装,通过以下命令安装(已经安装就跳过):</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"</span><br></pre></td></tr></table></figure>
<h3 id="编辑-zshrc-文件"><a href="#编辑-zshrc-文件" class="headerlink" title="编辑 .zshrc 文件"></a>编辑 <code>.zshrc</code> 文件</h3><p><strong>添加 <code>chpwd</code> 函数</strong>:在 <code>.zshrc</code> 最后添加以下函数</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">vi ~/.zshrc</span><br></pre></td></tr></table></figure>
<p>确保启用了plugin:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line"># 保证这一行不被注释, 括号的内容可能不一样</span><br><span class="line">plugins=(git)</span><br></pre></td></tr></table></figure>
<p>在 <code>.zshrc</code> 最后,添加 <code>chpwd</code> 函数:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"> chpwd() {</span><br><span class="line"><span class="meta prompt_"> # </span><span class="language-bash">指定目标目录</span></span><br><span class="line"> local root_dir="/Users/developer/teamA" # 指定目录</span><br><span class="line"> # 指定该目录要设置的git name信息</span><br><span class="line"> local user_name="name"</span><br><span class="line"> # 指定该目录要设置的git email信息</span><br><span class="line"> local user_email="email@email.com"</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">获取到当前目录</span></span><br><span class="line"> local current_dir="$(pwd -P)"</span><br><span class="line"> # 如果当前目录是否是目标目录,或者是否其子目录,孙目录</span><br><span class="line"> if [[ "$current_dir" == "$root_dir"* ]]; then</span><br><span class="line"> # 输出当前目录,用于调试,后续可删除</span><br><span class="line"> echo "chpwd: $PWD"</span><br><span class="line"> </span><br><span class="line"> if [ -d "$current_dir/.git" ]; then</span><br><span class="line"> git -C "$current_dir" config --local user.name "$user_name"</span><br><span class="line"> git -C "$current_dir" config --local user.email "$user_email"</span><br><span class="line"> echo "chpwd: 成功设置 user.name 和 user.email"</span><br><span class="line"> fi</span><br><span class="line"> fi</span><br><span class="line"> }</span><br><span class="line"><span class="meta prompt_"> # </span><span class="language-bash">执行 chpwd 函数</span></span><br><span class="line"> chpwd</span><br></pre></td></tr></table></figure>
<p>为了让更改生效,需要重新加载 <code>.zshrc</code> 文件。在终端中运行以下命令(或者关闭后重新打开)</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">source ~/.zshrc</span><br></pre></td></tr></table></figure>
<p>ps: 当然你如果使用的其他命令行终端,可以参考这个脚本,根据终端的特点,自行配置</p>
<h4 id="测试"><a href="#测试" class="headerlink" title="测试"></a>测试</h4><h3 id="在vscode中打开控制台:"><a href="#在vscode中打开控制台:" class="headerlink" title="在vscode中打开控制台:"></a>在vscode中打开控制台:</h3><p>使用vscode打开项目<code>/Users/developer/teamA/projectA</code>,并且打开控制台,如果发现有成功输出信息,就表示成功了。</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">chpwd: 成功设置 user.name 和 user.email</span><br></pre></td></tr></table></figure>
<p>保险起见,也用<code>git config --local</code>命令查看一下信息有没有正确设置。如果输出的信息是你预期的表示脚本成功了。</p>
<p>同样,使用vscode打开一个不在<code>/Users/developer/teamA</code>目录下的项目,如果没有输出该消息说明符合预期的</p>
<h3 id="测试cd命令"><a href="#测试cd命令" class="headerlink" title="测试cd命令"></a>测试cd命令</h3><p>打开zsh终端,使用cd命令进入<code>/Users/developer/teamA/projectA</code>,如果发现有成功输出信息,就表示成功了。</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">cd /Users/developer/teamA/projectA</span><br><span class="line"></span><br><span class="line">chpwd: 成功设置 user.name 和 user.email</span><br></pre></td></tr></table></figure>
<p>保险起见,也用<code>git config --local</code>命令查看一下信息有没有正确设置。</p>
<p>同样,进入<code>/Users/developer/teamB/projectB</code>:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">cd /Users/developer/teamB/projectB</span><br></pre></td></tr></table></figure>
<p>如果没有输出该消息说明符合预期的</p>
<h2 id="方案限制"><a href="#方案限制" class="headerlink" title="方案限制"></a>方案限制</h2><p>必须限制不同的远程仓库放到对应的目录,如果你现在的本地项目已经分散到不同的目录了,就必须要重新移动一下本地目录或者重新clone一下远程仓库到对应目录</p>
<h4 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h4><p>通过 Oh My Zsh 的 <code>chpwd</code> 函数,我们能够自动化 Git 用户信息的设置,这不仅提升了工作效率,也减少了配置错误的可能性。本文提供的步骤和测试验证了解决方案的有效性,展示了 Oh My Zsh 在自动化 shell 任务中的实用性。</p>
]]></content>
<categories>
<category>git</category>
<category>oh-my-zsh</category>
</categories>
<tags>
<tag>git</tag>
<tag>oh-my-zsh</tag>
<tag>git多身份</tag>
</tags>
</entry>
<entry>
<title>实现数字滚动变化以及延伸</title>
<url>/2016-06-14/animate-number.html</url>
<content><![CDATA[<blockquote>
<p>利用jquery的插件jquery.animateNumber实现一个简单的数字滚动效果</p>
</blockquote>
<h2 id="需求分析"><a href="#需求分析" class="headerlink" title="需求分析"></a>需求分析</h2><ol>
<li>处理数据:因为数据是后端提供,所以有可能格式不是我们想要的,所以也许需要格式化数据;</li>
<li>根据页面设计的效果图(如图),需要把数字字符串拆分成单个数字字符串<br> <img data-src="/images/posts/animateNumber_01.png" alt="animateNumber_01"></li>
<li>每一个数字进行滚动变化</li>
<li>最后,在项目中,我选取了插件<span class="exturl" data-url="aHR0cDovL2Fpc2hlay5naXRodWIuaW8vanF1ZXJ5LWFuaW1hdGVOdW1iZXIv">jquery.animateNumber<i class="fa fa-external-link-alt"></i></span>来实现滚动效果。这个插件的使用方式很简单,在官方有很详尽的文档来展示各个案例,就不一一赘述了。</li>
</ol>
<h2 id="HTML布局"><a href="#HTML布局" class="headerlink" title="HTML布局"></a>HTML布局</h2><p>其中num是后台传入的值,notChangeUint用来标记不进行单位变换的值</p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"warp"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"net-credit-num"</span> ></span></span><br><span class="line"> <span class="tag"><<span class="name">p</span>></span>平台累积会员人数(人)<span class="tag"></<span class="name">p</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">span</span> <span class="attr">date-num</span>=<span class="string">"123"</span> <span class="attr">class</span>=<span class="string">"animateNumber notChangeUint"</span>></span><span class="tag"></<span class="name">span</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"net-credit-money"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">p</span>></span>平台完成投资金额(万元)<span class="tag"></<span class="name">p</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">span</span> <span class="attr">date-num</span>=<span class="string">"91,123,456.00"</span> <span class="attr">class</span>=<span class="string">"animateNumber"</span>></span><span class="tag"></<span class="name">span</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"net-return-money"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">p</span>></span>累计已还款金额(万元)<span class="tag"></<span class="name">p</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">span</span> <span class="attr">date-num</span>=<span class="string">"8,895,678.00"</span> <span class="attr">class</span>=<span class="string">"animateNumber"</span>></span><span class="tag"></<span class="name">span</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure>
<h2 id="撸JS"><a href="#撸JS" class="headerlink" title="撸JS"></a>撸JS</h2><h3 id="去除逗号"><a href="#去除逗号" class="headerlink" title="去除逗号(,)"></a>去除逗号(,)</h3><figure class="highlight js"><table><tr><td class="code"><pre><span class="line">num = num.<span class="title function_">replace</span>(<span class="string">','</span>,<span class="string">''</span>);</span><br></pre></td></tr></table></figure>
<p>上面这种方法只能去除字符串中的第一个逗号,但是实际数据中可能存在多个逗号,所以需要用到正则全局匹配替换,代码如下:</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> reg = <span class="keyword">new</span> <span class="title class_">RegExp</span>(<span class="string">','</span>,<span class="string">'g'</span>);</span><br><span class="line">num = num.<span class="title function_">replace</span>(reg,<span class="string">''</span>);</span><br></pre></td></tr></table></figure>
<h3 id="转化单位-元–-万元"><a href="#转化单位-元–-万元" class="headerlink" title="转化单位(元–>万元)"></a>转化单位(元–>万元)</h3><p>把金额单位转化为万元,并且保留两位小数,人数不进行转化</p>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">if</span>(!numWarpParent.<span class="title function_">hasClass</span>(<span class="string">'notChangeUint'</span>)){</span><br><span class="line"> num = (<span class="title class_">Number</span>(num) / <span class="number">10000</span>).<span class="title function_">toFixed</span>(<span class="number">2</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="字符串拆分为数组"><a href="#字符串拆分为数组" class="headerlink" title="字符串拆分为数组"></a>字符串拆分为数组</h3><figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line">numArry = num.<span class="title function_">split</span>(<span class="string">''</span>);</span><br></pre></td></tr></table></figure>
<h3 id="把数字添加到页面并调用animateNumber的方法"><a href="#把数字添加到页面并调用animateNumber的方法" class="headerlink" title="把数字添加到页面并调用animateNumber的方法"></a>把数字添加到页面并调用animateNumber的方法</h3><figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i = <span class="number">0</span>; i < numArry.<span class="property">length</span>; i++){</span><br><span class="line"> <span class="keyword">var</span> thisNum = <span class="built_in">parseInt</span>(numArry[i]);</span><br><span class="line"> <span class="keyword">var</span> spanNum;</span><br><span class="line"> <span class="keyword">if</span> (!<span class="built_in">isNaN</span>(thisNum)){</span><br><span class="line"> spanNum = $(<span class="string">'<span class="single-num">'</span> + numArry[i] +<span class="string">'</span>'</span>);</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> spanNum = $(<span class="string">'<span class="single-point">.</span>'</span>);</span><br><span class="line"> };</span><br><span class="line"> numWarpParent.<span class="title function_">append</span>(spanNum);</span><br><span class="line"> thisNumWarp.<span class="title function_">prop</span>(<span class="string">'number'</span>, stratNum).<span class="title function_">animateNumber</span>({</span><br><span class="line"> <span class="attr">number</span>: thisNum</span><br><span class="line"> }, time);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="最后代码"><a href="#最后代码" class="headerlink" title="最后代码"></a>最后代码</h2><figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line">$(<span class="string">'.animateNumber'</span>).<span class="title function_">each</span>(<span class="keyword">function</span>(<span class="params"></span>){</span><br><span class="line"> <span class="keyword">var</span> _this = $(<span class="variable language_">this</span>);</span><br><span class="line"> <span class="keyword">var</span> totalNum = _this.<span class="title function_">attr</span>(<span class="string">'date-num'</span>); <span class="comment">//后台数据储存在date-num上</span></span><br><span class="line"> <span class="title function_">appendNum</span>(totalNum,_this);</span><br><span class="line">});</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">appendNum</span>(<span class="params">num,numWarpParent</span>){</span><br><span class="line"> <span class="keyword">var</span> newNum;</span><br><span class="line"> <span class="keyword">var</span> reg = <span class="keyword">new</span> <span class="title class_">RegExp</span>(<span class="string">','</span>,<span class="string">'g'</span>); <span class="comment">//正则匹配所有逗号</span></span><br><span class="line"> newNum = num.<span class="title function_">replace</span>(reg,<span class="string">''</span>);</span><br><span class="line"> <span class="keyword">if</span>(<span class="built_in">isNaN</span>(num)) newNum = <span class="number">0</span>; <span class="comment">//容错,当后台传入的参数错误(非数字)时,将只值置为0,以保证页面的正常渲染</span></span><br><span class="line"> <span class="keyword">if</span>(!numWarpParent.<span class="title function_">hasClass</span>(<span class="string">'notChangeUint'</span>)){ <span class="comment">//判断是否需要转换单位</span></span><br><span class="line"> newNum = (<span class="title class_">Number</span>(newNum) / <span class="number">10000</span>).<span class="title function_">toFixed</span>(<span class="number">2</span>);</span><br><span class="line"> };</span><br><span class="line"> numArry = newNum.<span class="title function_">split</span>(<span class="string">''</span>);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">var</span> i = <span class="number">0</span>; i < numArry.<span class="property">length</span>; i++){</span><br><span class="line"> <span class="keyword">var</span> thisNum = numArry[i];</span><br><span class="line"> <span class="keyword">var</span> numWarp;</span><br><span class="line"> <span class="keyword">if</span> (!<span class="built_in">isNaN</span>(thisNum)){ <span class="comment">//判断是否可以转化为数字</span></span><br><span class="line"> numWarp = $(<span class="string">'<label class="single-num">'</span> + numArry[i] +<span class="string">'</label>'</span>);</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> numWarp = $(<span class="string">'<label class="single-point">.</label>'</span>);</span><br><span class="line"> };</span><br><span class="line"> numWarpParent.<span class="title function_">append</span>(numWarp);</span><br><span class="line"> <span class="title function_">isAnimate</span>(thisNum,numWarpParent,i);</span><br><span class="line"> };</span><br><span class="line">};</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">isAnimate</span>(<span class="params">num,numWarpParent,index</span>){</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">isNaN</span>(num))<span class="keyword">return</span>;</span><br><span class="line"> <span class="comment">//调用animate.js插件方法</span></span><br><span class="line"> numWarpParent.<span class="title function_">find</span>(<span class="string">'label'</span>).<span class="title function_">eq</span>(index).<span class="title function_">prop</span>(<span class="string">'number'</span>, <span class="number">0</span>).<span class="title function_">animateNumber</span>({</span><br><span class="line"> <span class="attr">number</span>: num</span><br><span class="line"> }, num * <span class="number">100</span>);</span><br><span class="line">};</span><br></pre></td></tr></table></figure>
<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>1.功能模块化,尽量一个方法(函数)只做一件事情<br>2.容错,由于涉及到DOM操作,所以为了保证页面的正常渲染必须有容错处理机制:数据出错不影响整个流程(页面渲染)的畅通</p>
]]></content>
<categories>
<category>javascript</category>
</categories>
<tags>
<tag>animation</tag>
</tags>
</entry>
<entry>
<title>Babun导致本地SSH-KEY不可用</title>
<url>/2017-06-15/babun-casue-ssh-key-bad.html</url>
<content><![CDATA[<blockquote>
<p>Babun是一款集颜值功能于一身的window平台下的命令行工具。它集成了zsh、Cygwin等强大的工具,支持各种配置,并且有丰富的插件支持;并且有丰富的命令和命令提示功能,以及超级棒的历史命令提示。</p>
</blockquote>
<p>ps: 前文有我记录的关于<code>Babun</code>的一些特点,以及使用,请看<span class="exturl" data-url="aHR0cHM6Ly8ydWUuZ2l0aHViLmlvLzIwMTcvMDMvMTUvQmFidW4v">windows平台下超强的cmd工具Babun使用笔记<i class="fa fa-external-link-alt"></i></span>一文</p>
<h2 id="问题描述"><a href="#问题描述" class="headerlink" title="问题描述"></a>问题描述</h2><p>如果你本地先安装了git命令行工具并生成了<code>ssh-key</code>,再安装<code>Babun</code>之后,可能会导致原有的<code>ssh-key</code>不可用,原因:<br>安装<code>Babun</code>会添加全局变量<code>Home</code>,指向<code>Babun</code>安装目录下的<code>.Babun/cymwin/home</code>,因此在使用命令生成key时不会在<code>C:\Users\userName\.ssh</code>目录。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">ssh -T git@github.com</span><br><span class="line">Permission denied (publickey).</span><br></pre></td></tr></table></figure>
<h3 id="解决办法"><a href="#解决办法" class="headerlink" title="解决办法"></a>解决办法</h3><ul>
<li>删掉以前目录(<code>C:\Users\userName\.ssh</code>)下的ssh-key。</li>
<li>生成重新生成<code>ssh key</code>,此时生成的key在<code>.Babun\cymwin\home\userName\.ssh</code>下。</li>
<li>把生成的key映射到<code>C:\Users\userName\.ssh</code>目录。</li>
<li>获取权限</li>
<li>把key关联到相应github账户(此处以github为例)。</li>
<li>测试<code>ssh key</code>是否可用</li>
</ul>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">ssh -T git@github.com</span><br><span class="line">@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@</span><br><span class="line">@ WARNING: UNPROTECTED PRIVATE KEY FILE! @</span><br><span class="line">@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@</span><br><span class="line">Permissions 0670 <span class="keyword">for</span> <span class="string">'/home/Administrator/.ssh/id_rsa'</span> are too open.</span><br><span class="line">It is recommended that your private key files are NOT accessible by others.</span><br><span class="line">This private key will be ignored.</span><br><span class="line">Load key <span class="string">"/home/Administrator/.ssh/id_rsa"</span>: bad permissions</span><br><span class="line">Permission denied (publickey).</span><br></pre></td></tr></table></figure>
<p>当生成key之后,测试是否联通,你会发现还是报错了,提示权限不够,错误信息为<code>Permissions 0670</code></p>
<h4 id="在终端切换到C-Users-userName-ssh目录,执行下面命令"><a href="#在终端切换到C-Users-userName-ssh目录,执行下面命令" class="headerlink" title="在终端切换到C:\Users\userName\.ssh目录,执行下面命令"></a>在终端切换到<code>C:\Users\userName\.ssh</code>目录,执行下面命令</h4><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">ln</span> -s /c/Users/userName/.ssh /home/userName/.ssh</span><br></pre></td></tr></table></figure>
<p>此操作会把<code>.Babun\cymwin\home\userName\.ssh</code>目录下的<code>ssh key</code>映射<code>C:\Users\userName\.ssh</code></p>
<h4 id="在终端切换到根目录(-),执行以下命令-一般只执行其中一个"><a href="#在终端切换到根目录(-),执行以下命令-一般只执行其中一个" class="headerlink" title="在终端切换到根目录(~),执行以下命令(一般只执行其中一个)"></a>在终端切换到根目录(~),执行以下命令(一般只执行其中一个)</h4><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">chmod</span> 400 ~/.ssh/id_rsa</span><br><span class="line"><span class="built_in">chmod</span> 600 ~/.ssh/id_rsa</span><br><span class="line"><span class="built_in">chmod</span> 700 ~/.ssh/id_rsa</span><br><span class="line">ssh -T git@github.com</span><br><span class="line">Hi 2ue! You<span class="string">'ve successfully authenticated, but GitHub does not provide shell access.</span></span><br></pre></td></tr></table></figure>
<p>参考文章:</p>
<p>1.<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL0JhYnVuL0JhYnVuL2lzc3Vlcy8zMjc=">https://github.com/Babun/Babun/issues/327<i class="fa fa-external-link-alt"></i></span><br>2.<span class="exturl" data-url="aHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy85MjcwNzM0L3NzaC1wZXJtaXNzaW9ucy1hcmUtdG9vLW9wZW4tZXJyb3I=">http://stackoverflow.com/questions/9270734/ssh-permissions-are-too-open-error<i class="fa fa-external-link-alt"></i></span></p>
]]></content>
<categories>
<category>tools</category>
</categories>
<tags>
<tag>git</tag>
<tag>Babun</tag>
<tag>cmd</tag>
<tag>shell</tag>
</tags>
</entry>
<entry>
<title>windows平台下超强的cmd工具Babun使用笔记</title>
<url>/2017-03-15/babun.html</url>
<content><![CDATA[<blockquote>
<p>Babun是一款集颜值功能于一身的window平台下的命令行工具。它集成了zsh、Cygwin等强大的工具,支持各种配置,并且有丰富的插件支持;并且有丰富的命令和命令提示功能,以及超级棒的历史命令提示。</p>
</blockquote>
<h2 id="Babun"><a href="#Babun" class="headerlink" title="Babun"></a><span class="exturl" data-url="aHR0cHM6Ly9iYWJ1bi5naXRodWIuaW8v">Babun<i class="fa fa-external-link-alt"></i></span></h2><p>官方贴出了Babun的十大特性</p>
<ul>
<li>Pre-configured Cygwin with a lot of addons: 预置大量的Cygwin插件</li>
<li>Silent command-line installer, no admin rights required:静默命令行安装,不需要管理员权限</li>
<li>pact - advanced package manager (like apt-get or yum): 支持pact高级包管理器,类似于apt-get、yum等</li>
<li>xTerm-256 compatible console: xterm-256兼容控制台</li>
<li>HTTP(s) proxying support: HTTP(s) 代理支持</li>
<li>Plugin-oriented architecture: 插件体系,可以安装丰富的插件</li>
<li>Pre-configured git and shell: 预置git和shell,支持自定义配置</li>
<li>Integrated oh-my-zsh: 集成了zsh</li>
<li>Auto update feature: 自动检测最新版本</li>
<li>“Open Babun Here” context menu entry: 支持右键菜单“此处打开Babun”</li>
</ul>
<p>当然对于上面这些特性,我不得不补充一点,那就是它强大的命令提示功能,能从根据你的输入匹配历史输入,狠棒!</p>
<h3 id="Cygwin"><a href="#Cygwin" class="headerlink" title="Cygwin"></a>Cygwin</h3><p><code>Babun</code>的核心包括一个预配置的<code>Cygwin</code>。<code>cygwin</code>是一个非常好的工具,但有很多使用技巧,使你能够节省大量的时间。<code>Babun</code>解决了很多问题,它里面包含了很多重要的软件包,是你能够第一时间能够使用它们</p>
<h3 id="shell"><a href="#shell" class="headerlink" title="shell"></a>shell</h3><p><code>Babun</code>的<code>shell</code>通过调整,已达到最佳的用户体验,<code>Babun</code>有两个配置之后马上使用的<code>shell</code>(默认使用<code>zsh</code>,可以使用<code>bash</code>或者<code>zsh</code>命令切换到对应的模式),<code>Babun</code>的<code>shell</code>具有以下的特点:</p>
<ul>
<li>语法高亮</li>
<li>具有unix的工具</li>
<li>软件开发工具</li>
<li>git-语义提示</li>
<li>自定义脚本和别名</li>
<li>…</li>
</ul>
<h3 id="Console"><a href="#Console" class="headerlink" title="Console"></a>Console</h3><p><code>Babun</code>支持<code>HTTP</code>代理,只需添加地址和<code>HTTP</code>代理服务器的凭据。<code>Babunrc</code>文件所在文件夹执行源<code>Babunrc</code>启用HTTP代理。目前还不支持<code>SOCKS</code>代理。</p>
<h3 id="开发者工具"><a href="#开发者工具" class="headerlink" title="开发者工具"></a>开发者工具</h3><p>Babun提供多种方便的工具和脚本,是你的开发工作更轻松,具有的功能如下:</p>
<ul>
<li>编程语言(python,Perl, etc等)</li>
<li>git(各种各样的别名调整)</li>
<li>UNIX工具((grep, wget, curl, etc)</li>
<li>vcs (svn, git)</li>
<li>oh-my-zsh</li>
<li>自定义脚本(pbcopy, pbpaste, Babun, etc)</li>
</ul>
<h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><h3 id="默认安装"><a href="#默认安装" class="headerlink" title="默认安装"></a>默认安装</h3><p>双击<code>install.bat</code>脚本,<code>Babun</code>使用默认安装位置<code>C:\Users\userName\.Babun</code>,安装好的<code>Babun</code>会在<code>C:\Users\userName\</code>下;<br>当然也可以指定安装位置</p>
<h3 id="自定义安装"><a href="#自定义安装" class="headerlink" title="自定义安装"></a>自定义安装</h3><p>通过<code>cmd</code>命令行在执行<code>install.bat</code>时指定参数<code>/t</code>或<code>/target</code>指定安装的目录。<br>执行:Babun.bat /t install-dir</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">Babun.bat /t c:\Babun</span><br></pre></td></tr></table></figure>
<p>安装好之后会在<code>d:\Babun</code>目录下生成一个<code>.Babun</code>的目录,<code>Babun</code>所有文件都在这个目录中。注意安装目录最好不要有空格,这是<code>cygwin</code>要求的</p>
<p>启动<code>Babun</code>默认是在’%userprofile%.Babun\cygwin\home\username’</p>
<h2 id="开发环境配置"><a href="#开发环境配置" class="headerlink" title="开发环境配置"></a>开发环境配置</h2><h3 id="pip"><a href="#pip" class="headerlink" title="pip"></a>pip</h3><p><code>Babun</code>内置了<code>Python</code>、<code>Perl</code>等解释器。<code>cygwin</code>自带的<code>python</code>没有<code>pip</code>,需手动安装。<br>直接执行下面这个命令就好了。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">wget https://bootstrap.pypa.io/get-pip.py -O - | python</span><br></pre></td></tr></table></figure>
<p>有了pip就可以自由的安装诸如<code>ipython</code>之类的东西,还有包罗万象的类库。</p>
<h3 id="常用插件"><a href="#常用插件" class="headerlink" title="常用插件"></a>常用插件</h3><p><code>Babun</code>默认是安装了<code>oh-my-zsh</code>的,这里可以根据自身情况安装一些插件。具体可参考<a href="http://blog.csdn.net/czg13548930186/article/details/72858289">利用<code>oh-my-zsh</code>打造你的超级终端一文</a>;</p>
<h3 id="包管理器使用"><a href="#包管理器使用" class="headerlink" title="包管理器使用"></a>包管理器使用</h3><p><code>Babun</code>提供一个叫<code>pact</code>包管理工具,类似于<code>linux</code>上面的<code>apt-get</code>或<code>yum</code>的包管理工具</p>
<h2 id="配置别名(alias)"><a href="#配置别名(alias)" class="headerlink" title="配置别名(alias)"></a>配置别名(alias)</h2><p>可以在<code>.Babun\cygwin\home\username</code>目录下配置对应工具的别名,而并不仅限于<code>git-bash</code>。<br>当然记忆别名其实也是体力活,我的想法是对一些常用的命令、经常手滑手速过快打错的命令、复杂的命令配置一些别名,例如</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">gt = git</span><br><span class="line">gti = git</span><br><span class="line">n = npm</span><br><span class="line">nr = npm run dev</span><br><span class="line">gtlg = git <span class="built_in">log</span> --color --graph --pretty=format:<span class="string">'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'</span> --abbrev-commit --<span class="built_in">date</span>=relative</span><br><span class="line">...等等</span><br></pre></td></tr></table></figure>
<h2 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h2><h3 id="本地SSH-KEY不可用"><a href="#本地SSH-KEY不可用" class="headerlink" title="本地SSH-KEY不可用"></a>本地SSH-KEY不可用</h3><p>查看我记录的<span class="exturl" data-url="aHR0cHM6Ly8ydWUuZ2l0aHViLmlvLzIwMTcvMDYvMTUvYmFidW4tY2FzdWUtc3NoLWtleS1iYWQv">Babun导致本地SSH-KEY不可用<i class="fa fa-external-link-alt"></i></span>一文</p>
<h3 id="中文乱码问题"><a href="#中文乱码问题" class="headerlink" title="中文乱码问题"></a>中文乱码问题</h3><p>找了很多解决方案,都不能完美的解决问题,最后还是回归原始:不解决!!!</p>
<h3 id="锁定文件夹"><a href="#锁定文件夹" class="headerlink" title="锁定文件夹"></a>锁定文件夹</h3><p>在使用<code>Babun</code>时(比如此时进入了<code>a</code>目录),它会锁定文件夹<code>a</code>目录,导致你可能无法做一些危险操作。必须关闭<code>Babun</code>后才能解锁进程</p>
<p>参考文章:</p>
<ul>
<li><span class="exturl" data-url="aHR0cDovL3d3dy5tYW1pY29kZS5jb20vaW5mby1kZXRhaWwtMTY1MzM1My5odG1s">windows下的命令行工具Babun<i class="fa fa-external-link-alt"></i></span></li>
</ul>
]]></content>
<categories>
<category>tools</category>
</categories>
<tags>
<tag>git</tag>
<tag>Babun</tag>
<tag>cmd</tag>
<tag>shell</tag>
</tags>
</entry>
<entry>
<title>风继续吹</title>
<url>/2017-11-29/blow-forever.html</url>
<content><![CDATA[<blockquote>
<p>最近在某些比较看重的事情上,处理的很失败,感觉整个心态都发生了变化。下班独行的那段路上,突然惊醒自己也许需要做出一些改变,晚饭后静静的思考了一阵:似乎勇往前行才是我最需需要的改变。古语有云:走自己的路,让别人去说吧。是的,生活需要你不断踽踽独行,活在他人的世界里是可怕的,特别他(她)还是陌生人。随手记录一些句子,它们是我最近的心态和生活的写照,也以此鞭策自己砥砺前行。</p>
</blockquote>
<hr>
<p>时间不会因你沮丧而停滞不前<br>生活不会因你懊恼而雨过天晴</p>
<p>如风,继续吹<br>吹来往日的欢歌笑语<br>吹来远方的殷殷思念<br>化作雨露滋润心田</p>
<p>如风,继续吹<br>随风飘荡去远方<br>随风逐浪勇往前<br>风不止浪不息</p>
<p>如风,继续吹<br>时而狂乱,掠过天空大地,高山河流<br>时而低喃,轻抚绿茵花朵,平原盆谷<br>最后都消散在其它风里</p>
<p>然后<br>其它风,继续吹</p>
<p>—-< 谨鼓励我砥砺前行 ></p>
]]></content>
<categories>
<category>随想</category>
</categories>
<tags>
<tag>人生</tag>
</tags>
</entry>
<entry>
<title>H5的Notification特性 - Web的桌面通知功能</title>
<url>/2017-10-16/desktop-notification.html</url>
<content><![CDATA[<blockquote>
<p>目前,<code>web</code>网页使用桌面通知功能的越来越多,包括微博,腾讯视频等大厂站,桌面通知功能是<code>H5</code>的一个<code>API</code> - <code>Notifications</code>。它允许网页或应用程序可以发出通知,通知将被显示在页面之外的[[系统]]层面上(通常使用操作[[系统]]的标准通知机制,但是在不同的平台和浏览器上的表现会有差异),这样即使应用程序空闲或在后台也可以向用户发送信息。</p>
</blockquote>
<h2 id="应用场景"><a href="#应用场景" class="headerlink" title="应用场景"></a>应用场景</h2><p><code>Notifications</code>的诞生简化了网站或者应用与用户之间的沟通成本(时间成本和开发成本),增强用户黏性(减少了用户离开应用的可能)。传统的通知方式,大多是通过站内信(消息),邮件,短信等方式,它们通常需要刷新(跳转)页面、离开应用打开其他应用或终端来查看消息;而桌面通知功能大大的简化了这个过程,消息的传递基本不消耗时间(如果不设置<code>setTimeout</code>,用时基本不会超过<code>1s</code>),并且用户不需要离开应用,这都带来了极大的方便。可以预见,<code>Notifications</code>将会在很多网页或应用中被大量使用。当然<code>Notifications</code>也具有它的局限性:无法存档、即看即毁<br>那么,这个功能到底能用在哪些场景呢?只能说能应用的场景很多:</p>
<ul>
<li>社交类网站</li>
<li>[[资讯]]类网站</li>
<li>网页版邮件服务</li>
<li>即时通知类网站</li>
<li>…</li>
</ul>
<p>举个例子,当你打开微博页面,你可能会看到(使用新版浏览器)如下图的通知:<br><img data-src="/images/posts/desktop-notification1.png" alt="desktop-notification1"></p>
<p>这就是网站使用了桌面通知功能,当你选择允许,那么当网站有推送消息或者你登陆账号有新的消息将会在桌面的右下角出现一个小弹窗通知,如下:<br><img data-src="/images/posts/desktop-notification2.png" alt="desktop-notification2"></p>
<p>感觉有点酷酷的!!!</p>
<h2 id="用户权限-Notification-permission"><a href="#用户权限-Notification-permission" class="headerlink" title="用户权限 - Notification.permission"></a>用户权限 - Notification.permission</h2><p><code>Notification.permission</code>是一个静态方法,可以获取用户当前的通知权限状态,返回一个<code>String</code>,可以根据返回值判断用户是否授予了通知权限。返回值有三种情况:</p>
<ul>
<li>default<ul>
<li>用户还未被询问是否授权,所以通知不会被显示。</li>
</ul>
</li>
<li>granted<ul>
<li>表示之前已经询问过用户,并且用户已经授予了显示通知的权限。</li>
</ul>
</li>
<li>denied<ul>
<li>用户已经明确的拒绝了显示通知的权限。</li>
</ul>
</li>
</ul>
<p>当值为<code>default</code>或者<code>denied</code>时都不会显示通知消息,只有明确的被设置成<code>granted</code>才会显示通知消息</p>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> permission = <span class="title class_">Notification</span>.<span class="property">permission</span>;</span><br><span class="line"><span class="keyword">if</span>(permission === <span class="string">'granted'</span>){</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'已经授权通知,可以进行你的通知啦!'</span>);</span><br><span class="line">}<span class="keyword">else</span>{</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'用户还未授权,请先授权!'</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="请求权限-Notification-requestPermission-CALLBACK"><a href="#请求权限-Notification-requestPermission-CALLBACK" class="headerlink" title="请求权限 - Notification.requestPermission(CALLBACK)"></a>请求权限 - Notification.requestPermission(CALLBACK)</h2><p>应用发送通知之前必须要取得发送通知的权限,才能成功进行通知。<code>Notification.requestPermission(CALLBACK)</code>是请求获取权限的方法(有点类似<code>javascript</code>的<code>confirm</code>弹窗窗),允许传入一个回调,回调会返回用户选择的何种权限,返回两个值,<code>granted</code>代表允许,<code>denied</code>代表拒绝。并且<code>Notification.requestPermission()</code>支持<code>then</code>方式的链式调用,也就意味着可以异步调用它。</p>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="title class_">Notification</span>.<span class="title function_">requestPermission</span>(<span class="keyword">function</span> (<span class="params">permission</span>) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'用户是否允许通知: '</span>,permission === <span class="string">'granted'</span> ? <span class="string">'允许'</span> : <span class="string">'拒绝'</span>);</span><br><span class="line">});</span><br><span class="line"><span class="comment">//两种方式是等价的</span></span><br><span class="line"><span class="title class_">Notification</span>.<span class="title function_">requestPermission</span>().<span class="title function_">then</span>(<span class="keyword">function</span> (<span class="params">permission</span>) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'用户是否允许通知: '</span>,permission === <span class="string">'granted'</span> ? <span class="string">'允许'</span> : <span class="string">'拒绝'</span>);</span><br><span class="line">});</span><br></pre></td></tr></table></figure>
<h2 id="创建通知-new-Notification-TITLE-OPTIONS"><a href="#创建通知-new-Notification-TITLE-OPTIONS" class="headerlink" title="创建通知 - new Notification(TITLE, OPTIONS)"></a>创建通知 - new Notification(TITLE, OPTIONS)</h2><p><code>new Notification(TITLE, OPTIONS)</code>方法创建可以创建一个通知实例,允许参入参数两个参数<code>TITLE</code>和<code>OPTIONS</code>。注意默认情况下(实际可以通过<code>OPTIONS</code>中的<code>timestamp</code>参数控制)一旦通知实例被创建出来,它会立即被显示出来。</p>
<h3 id="TITLE参数"><a href="#TITLE参数" class="headerlink" title="TITLE参数"></a>TITLE参数</h3><p><code>TITLE</code>表示通知的标题。必须参数,允许数字、字符串和空</p>
<h3 id="OPTIONS参数"><a href="#OPTIONS参数" class="headerlink" title="OPTIONS参数"></a>OPTIONS参数</h3><p><code>OPTIONS</code>是非必须参数,必须为一个对象,它包含:<br>ps: 部分参数在某些浏览器可能会不生效,建议使用最新版的谷歌浏览器。以下某些内容从<span class="exturl" data-url="aHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL25vdGlmaWNhdGlvbg==">Notification-MDN-EN<i class="fa fa-external-link-alt"></i></span>结合谷歌翻译得来,很有可能翻译不准确,如有,请提出。</p>
<figure class="highlight json"><table><tr><td class="code"><pre><span class="line"><span class="punctuation">{</span></span><br><span class="line"> <span class="comment">//通知显示正文。非必须,默认为空</span></span><br><span class="line"> body<span class="punctuation">:</span> '你的好友XX上线了!'<span class="punctuation">,</span></span><br><span class="line"> <span class="comment">//通知显示正文的图片地址。非必须,默认为空</span></span><br><span class="line"> image<span class="punctuation">:</span> 'imgae url'<span class="punctuation">,</span></span><br><span class="line"> <span class="comment">//通知左侧图标。非必须,默认为空</span></span><br><span class="line"> icon<span class="punctuation">:</span> 'imgae url'<span class="punctuation">,</span></span><br><span class="line"> <span class="comment">//通知的分类标记(ID)。非必须,默认为空</span></span><br><span class="line"> tag<span class="punctuation">:</span> 'test'<span class="punctuation">,</span></span><br><span class="line"> <span class="comment">//通知相关联的数据,通常用于方法的回调,传参。非必须,默认为空</span></span><br><span class="line"> data<span class="punctuation">:</span> '可以是任意数据类型'<span class="punctuation">,</span></span><br><span class="line"> <span class="comment">//通知显示延迟的时间。非必须,默认通知实例创建完成就显示</span></span><br><span class="line"> timestamp<span class="punctuation">:</span> ''<span class="punctuation">,</span></span><br><span class="line"> <span class="comment">//通知主体内容的水平展示顺序,有点类似direction属性。非必须,默认值是auto, 可以是ltr或rtl</span></span><br><span class="line"> dir<span class="punctuation">:</span> 'auto'<span class="punctuation">,</span></span><br><span class="line"> <span class="comment">//当没有足够的空间来显示通知本身时,用于表示通知的图像的URL。非必须,默认为空</span></span><br><span class="line"> badge<span class="punctuation">:</span> 'xxx'<span class="punctuation">,</span></span><br><span class="line"> <span class="comment">//通知的语言。非必须默认为空</span></span><br><span class="line"> lang<span class="punctuation">:</span> ''<span class="punctuation">,</span></span><br><span class="line"> <span class="comment">//通知显示时,设备的振动模式。非必须,默认为空</span></span><br><span class="line"> vibrate<span class="punctuation">:</span> <span class="punctuation">[</span><span class="number">200</span><span class="punctuation">,</span> <span class="number">100</span><span class="punctuation">,</span> <span class="number">200</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line"> <span class="comment">//新通知出现是否覆盖旧的通知,覆盖(true)则永远只显示一条通知,不覆盖(false)则会多条通知重叠。非必须,默认为true</span></span><br><span class="line"> renotify<span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line"> <span class="comment">//通知是否静音。非必须,默认为false,表示无声</span></span><br><span class="line"> silent<span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line"> <span class="comment">//通知声源文件地址。非必须,默认为空</span></span><br><span class="line"> sound<span class="punctuation">:</span> 'mp3'<span class="punctuation">,</span></span><br><span class="line"> <span class="comment">//是否不在屏幕上显示通知信息。非必须,默认为false表示要显示</span></span><br><span class="line"> noscreen<span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line"> <span class="comment">//指定通知是否应该粘滞性,即不容易被用户清理。非必须,默认false表示不具粘滞性</span></span><br><span class="line"> sticky<span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line"> <span class="comment">//指定通知是否保持活性,知道用户点击或关闭。非必须,默认为false</span></span><br><span class="line"> requireInteraction<span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span></span><br><span class="line"><span class="punctuation">}</span></span><br></pre></td></tr></table></figure>
<h3 id="事件及事件钩子"><a href="#事件及事件钩子" class="headerlink" title="事件及事件钩子"></a>事件及事件钩子</h3><p>当通知被创建成功后:</p>
<ul>
<li>通知实例具有一个静态方法可以用来关闭通知</li>
<li>通知实例具有四个事件钩子,来跟踪通知当前的状态。这些事件可以通过事件处理跟踪<code>onshow</code>、<code>onclick</code>、<code>onclose</code>和<code>onerror</code>。因为<code>Notification</code>同样继承自<code>EventTarget</code>,因此可以对它调用<code>addEventListener()</code>方法。</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> n = <span class="keyword">new</span> <span class="title class_">Notification</span>(<span class="string">'XX网站消息通知'</span>, {</span><br><span class="line"> <span class="attr">body</span>: <span class="string">'你的朋友有新状态啦,快去围观吧!'</span>,</span><br><span class="line"> <span class="attr">tag</span>: <span class="string">'2ue'</span>,</span><br><span class="line"> <span class="attr">icon</span>: <span class="string">'https://2ue.github.io/images/common/avatar.png'</span>,</span><br><span class="line"> <span class="attr">data</span>: {</span><br><span class="line"> <span class="attr">url</span>: <span class="string">'https://2ue.github.io'</span></span><br><span class="line"> },</span><br><span class="line"> <span class="attr">timestamp</span>: <span class="number">3000</span></span><br><span class="line">});</span><br><span class="line"></span><br><span class="line">n.<span class="property">onshow</span> = <span class="keyword">function</span> (<span class="params"></span>) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'通知显示了!'</span>);</span><br><span class="line">}</span><br><span class="line">n.<span class="property">onclick</span> = <span class="keyword">function</span> (<span class="params">e</span>) {</span><br><span class="line"> <span class="comment">//可以直接通过实例的方式获取data内自定义的数据</span></span><br><span class="line"> <span class="comment">//也可以通过访问回调参数e来获取data的数据</span></span><br><span class="line"> <span class="variable language_">window</span>.<span class="title function_">open</span>(n.<span class="property">data</span>.<span class="property">url</span>, <span class="string">'_blank'</span>);</span><br><span class="line"> n.<span class="title function_">close</span>();</span><br><span class="line">}</span><br><span class="line">n.<span class="property">onclose</span> = <span class="keyword">function</span> (<span class="params"></span>) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'你墙壁了我!!!'</span>);</span><br><span class="line">}</span><br><span class="line">n.<span class="property">onerror</span> = <span class="keyword">function</span> (<span class="params">err</span>) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'出错了,小伙子在检查一下吧'</span>);</span><br><span class="line"> <span class="keyword">throw</span> err;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="demo"><a href="#demo" class="headerlink" title="demo"></a>demo</h2><p>写一个简单的例子,可以打开页面体验一下,建议用最新版谷歌浏览器打开~ <span class="exturl" data-url="aHR0cHM6Ly9jb2RlcGVuLmlvLzJ1ZS9wZW4vcllZendC">Notification.js<i class="fa fa-external-link-alt"></i></span></p>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title class_">NotificationInstance</span> = <span class="title class_">Notification</span> || <span class="variable language_">window</span>.<span class="property">Notification</span>;</span><br><span class="line"><span class="keyword">if</span> (!!<span class="title class_">NotificationInstance</span>) {</span><br><span class="line"> <span class="keyword">const</span> permissionNow = <span class="title class_">NotificationInstance</span>.<span class="property">permission</span>;</span><br><span class="line"> <span class="keyword">if</span> (permissionNow === <span class="string">'granted'</span>) {<span class="comment">//允许通知</span></span><br><span class="line"> <span class="title class_">CreatNotification</span>();</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (permissionNow === <span class="string">'denied'</span>) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'用户拒绝了你!!!'</span>);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="title function_">setPermission</span>();</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">function</span> <span class="title function_">setPermission</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="comment">//请求获取通知权限</span></span><br><span class="line"> <span class="title class_">NotificationInstance</span>.<span class="title function_">requestPermission</span>(<span class="keyword">function</span> (<span class="params">PERMISSION</span>) {</span><br><span class="line"> <span class="keyword">if</span> (<span class="variable constant_">PERMISSION</span> === <span class="string">'granted'</span>) {</span><br><span class="line"> <span class="title class_">CreatNotification</span>();</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'用户无情残忍的拒绝了你!!!'</span>);</span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">function</span> <span class="title function_">CreatNotification</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">const</span> n = <span class="keyword">new</span> <span class="title class_">NotificationInstance</span>(<span class="string">'XX网站消息通知'</span>, {</span><br><span class="line"> <span class="attr">body</span>: <span class="string">'你的朋友有新状态啦,快去围观吧!'</span>,</span><br><span class="line"> <span class="attr">tag</span>: <span class="string">'2ue'</span>,</span><br><span class="line"> <span class="attr">icon</span>: <span class="string">'https://2ue.github.io/images/common/avatar.png'</span>,</span><br><span class="line"> <span class="attr">data</span>: {</span><br><span class="line"> <span class="attr">url</span>: <span class="string">'https://2ue.github.io'</span></span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line"> n.<span class="property">onshow</span> = <span class="keyword">function</span> (<span class="params"></span>) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'通知显示了!'</span>);</span><br><span class="line"> }</span><br><span class="line"> n.<span class="property">onclick</span> = <span class="keyword">function</span> (<span class="params">e</span>) {</span><br><span class="line"> <span class="comment">//可以直接通过实例的方式获取data内自定义的数据</span></span><br><span class="line"> <span class="comment">//也可以通过访问回调参数e来获取data的数据</span></span><br><span class="line"> <span class="variable language_">window</span>.<span class="title function_">open</span>(n.<span class="property">data</span>.<span class="property">url</span>, <span class="string">'_blank'</span>);</span><br><span class="line"> n.<span class="title function_">close</span>();</span><br><span class="line"> }</span><br><span class="line"> n.<span class="property">onclose</span> = <span class="keyword">function</span> (<span class="params"></span>) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'你墙壁了我!!!'</span>);</span><br><span class="line"> }</span><br><span class="line"> n.<span class="property">onerror</span> = <span class="keyword">function</span> (<span class="params">err</span>) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'出错了,小伙子在检查一下吧'</span>);</span><br><span class="line"> <span class="keyword">throw</span> err;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">setTimeout</span>(<span class="function">() =></span> {</span><br><span class="line"> n.<span class="title function_">close</span>();</span><br><span class="line"> }, <span class="number">2000</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="兼容"><a href="#兼容" class="headerlink" title="兼容"></a>兼容</h2><iframe data-feature="notifications" src="https://caniuse.bitsofco.de/embed/index.html?feat=notifications&periods=current&accessible-colours=false" frameborder="0" width="100%" height="400px"></iframe>
<h2 id="待整理-专题-模型驱动-参考-参考"><a href="#待整理-专题-模型驱动-参考-参考" class="headerlink" title="[[待整理/专题/模型驱动/参考|参考]]"></a>[[待整理/专题/模型驱动/参考|参考]]</h2><ul>
<li><span class="exturl" data-url="aHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL25vdGlmaWNhdGlvbg==">Notification-MDN-EN<i class="fa fa-external-link-alt"></i></span></li>
<li><span class="exturl" data-url="aHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvemgtQ04vZG9jcy9XZWIvQVBJL25vdGlmaWNhdGlvbg==">Notification-MDN-CN<i class="fa fa-external-link-alt"></i></span></li>
</ul>
]]></content>
<categories>
<category>H5</category>
</categories>
<tags>
<tag>Notification</tag>
<tag>javascript</tag>
</tags>
</entry>
<entry>
<title>前端测试探索</title>
<url>/2017-10-10/fed-test.html</url>
<content><![CDATA[<blockquote>
<p>前端测试是保证代码质量以及程序稳定的一种可靠方式,同时也从代码层面解决了自测难,自测烦等前端测试综合症。当然在前端开发引入测试环节无疑会增加人力和时间成本,如果最终产生的结果和增加的成本能够两两抵消产生正面效应,那么有必要考虑把测试环节加入到团队的规划中。但是在实际开发过程中,测试用例更多的被用于开源项目中,在大部分公司的生成项目很少使用维护测试用例,其根本原因是不纯粹的生产环境导致维护测试用例变得困难,而目的性很强的开源项目则更纯粹,所以前端测试的发展任重而道远。</p>
</blockquote>
<p>Ps:本次更多的是讲述概念性的东西,代码性的具体实例不做过多实践</p>
<hr>
<h2 id="GUI-Graphical-User-Interface-软件测试"><a href="#GUI-Graphical-User-Interface-软件测试" class="headerlink" title="GUI(Graphical User Interface)软件测试"></a>GUI(Graphical User Interface)软件测试</h2><blockquote>
<p>前端测试不同于后端测试,因为除了一般的逻辑测试以外,由于存在界面交互,所以涉及到模拟用户行为达到测试的目的。由此引入了一个概念:GUI(Graphical User Interface)软件测试,也就是图形用户界面软件测试</p>
</blockquote>
<h2 id="TDD-Test-Driven-Development-BDD-Behaviour-Driven-Development"><a href="#TDD-Test-Driven-Development-BDD-Behaviour-Driven-Development" class="headerlink" title="TDD(Test Driven Development) & BDD(Behaviour Driven Development)"></a>TDD(Test Driven Development) & BDD(Behaviour Driven Development)</h2><p><code>TDD</code>很明显的意思是测试驱动开发,也就是说我们可以从测试的角度来检验整个项目。大概的流程是先针对每个功能点抽象出接口代码,然后编写单元测试代码,接下来实现接口,运行单元测试代码,循环此过程,直到整个单元测试都通过。<br><code>TDD</code>的好处自然不用多说,它能让你减少程序逻辑方面的错误,尽可能的减少项目中的<code>bug</code>,开始接触编程的时候我们大都有过这样的体验,可能你觉得完成得很完美,自我感觉良好,但是实际测试或者应用的时候才发现里面可能存在一堆bug,或者存在设计问题,或者更严重的逻辑问题,而<code>TDD</code>正好可以帮助我们尽量减少类似事件的发生。<br>当然,并不是所有的项目都适合<code>TDD</code>,要使用<code>TDD</code>,我认为必须至少具备以下两个条件</p>
<ul>
<li>项目的业务逻辑很清晰,并且程序员对开发逻辑很清晰</li>
<li>项目模块的复杂度和依赖度不高。如果复杂度高和依赖度高会导致在最开始拆分单元的时候造成很大的困扰,有可能根本不能顺利拆分</li>
</ul>
<p><code>BDD</code>行为驱动开发,这里的行为不是指程序员的行为,而是指业务(程序)的逻辑行为,实际上<code>BDD</code>可以看作是对<code>TDD</code>的一种补充,当然你也可以把它看作<code>TDD</code>的一个分支,因为在<code>TDD</code>中,我们并不能完全保证根据设计所编写的测试就是用户所期望的功能</p>
<h2 id="如何实现自动化"><a href="#如何实现自动化" class="headerlink" title="如何实现自动化"></a>如何实现自动化</h2><p>说一千道一万,新环节的引入必然带来成本的增加,那么我们如何控制增加的成本在合理范围内?很自然的我们想到了使用工具来实现自动化的测试,让机器帮我完成复杂的交互和测试,并自动监控返回错误报警,为我们手动排除问题提供参考</p>
<h2 id="可覆盖的测试"><a href="#可覆盖的测试" class="headerlink" title="可覆盖的测试"></a>可覆盖的测试</h2><blockquote>
<p>那到底前端在开发中需要测试哪些东西?在目前技术又可以实现那些测试?</p>
</blockquote>
<ul>
<li>函数功能测试<ul>
<li>全局变量</li>
<li>公共方法</li>
</ul>
</li>
<li>界面&交互测试<ul>
<li>事件交互</li>
<li>数据输入交互</li>
<li>特征检测<ul>
<li>设计图还原度</li>
<li>图片大小</li>
<li>…</li>
</ul>
</li>
<li>特殊情况<ul>
<li>自适应和响应式测试</li>
<li>浏览器兼容</li>
<li>多端测试</li>
<li>…</li>
</ul>
</li>
</ul>
</li>
<li>网络请求测试<ul>
<li>数据库访问</li>
<li>模拟用户登陆等</li>
<li>ajax请求</li>
</ul>
</li>
<li>直观的错误信息展示<ul>
<li>网页表格</li>
<li>截图</li>
</ul>
</li>
<li>性能测试</li>
<li>回归测试</li>
<li>自动化<ul>
<li>测试用例数据自动化 - 结合mockjs打造假数据</li>
<li>测试用例自动化创建 - 通过读取源码中的注释来自动生成测试用例?</li>
</ul>
</li>
</ul>
<h2 id="业务逻辑-业务代码-测试用例的关系"><a href="#业务逻辑-业务代码-测试用例的关系" class="headerlink" title="业务逻辑/业务代码/测试用例的关系"></a>业务逻辑/业务代码/测试用例的关系</h2><p>业务代码的颗粒度与测试用例的复杂度成反比:颗粒度划分越多(细),复杂度越低<br>业务代码的量与测试用例的量成正比</p>
<h2 id="Good"><a href="#Good" class="headerlink" title="Good"></a>Good</h2><ul>
<li>相对于等待问题产生,更倾向于避免可能的问题</li>
<li>有利于形成团队代码规范,对团队未来成员的扩充是一个很好的约束规范</li>
<li>对输出的产品有进一步的质量保证</li>
</ul>
<h2 id="Bad"><a href="#Bad" class="headerlink" title="Bad"></a>Bad</h2><ul>
<li>增加维护测试用例本(时间和人力)</li>
<li>增加编码复杂度(需要靠如何更友好的进行测试),对团队人员的编码要求提高了</li>
<li>也许会增加学习成本(并不一定所有人都会写测试用例)</li>
<li>需要把控测试用例的合理性、覆盖率、通过率</li>
</ul>
<h2 id="测试框架"><a href="#测试框架" class="headerlink" title="测试框架"></a>测试框架</h2><h3 id="PhantomJS-CasperJS"><a href="#PhantomJS-CasperJS" class="headerlink" title="PhantomJS/CasperJS"></a><span class="exturl" data-url="aHR0cDovL3BoYW50b21qcy5vcmcv">PhantomJS<i class="fa fa-external-link-alt"></i></span>/<span class="exturl" data-url="aHR0cDovL2Nhc3BlcmpzLm9yZy8=">CasperJS<i class="fa fa-external-link-alt"></i></span></h3><p><code>PhantomJS</code>是一个服务器端的支持<code>JavaScript API</code>的<code>WebKit</code>。其支持各种Web标准:<code>DOM</code>处理, <code>CSS</code>选择器, <code>JSON</code>, <code>Canvas</code>和<code>SVG</code>。对于<code>web</code>测试、界面、网络捕获、页面自动化访问等等方面。当启动的时候会在内存在开启一个无界面浏览器,以此模拟用户各种操作,可以对界面截图<br><code>Casperjs</code>是对<code>PhantomJS</code>的封装,提供了更加易用的<code>API</code>, 增强了测试等方面的支持</p>
<h3 id="PhantomCSS"><a href="#PhantomCSS" class="headerlink" title="PhantomCSS"></a><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL0h1ZGRsZS9QaGFudG9tQ1NT">PhantomCSS<i class="fa fa-external-link-alt"></i></span></h3><p>像素对比工具,基于<code>PhantomJs</code>开发,结合了<code>Casperjs</code>截图和<code>ResembleJs</code>图像对比分析</p>
<h3 id="Page-monitor"><a href="#Page-monitor" class="headerlink" title="Page-monitor"></a><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2ZvdWJlci9wYWdlLW1vbml0b3I=">Page-monitor<i class="fa fa-external-link-alt"></i></span></h3><p><code>DOM</code>结构对比工具,基于<code>PhantomJS</code>开发,根据<code>DOM</code>结构与样式的对比来对比整个页面的变动部分</p>
<h3 id="BackstopJS"><a href="#BackstopJS" class="headerlink" title="BackstopJS"></a><span class="exturl" data-url="aHR0cHM6Ly9nYXJyaXMuZ2l0aHViLmlvL0JhY2tzdG9wSlM=">BackstopJS<i class="fa fa-external-link-alt"></i></span></h3><p>主要通过<code>PhantomJS</code>、<code>capserJS</code>等工具在不同尺寸下截图,然后根据<code>resemberJS</code>进行像素比对判断是否正常,以实现响应式测试</p>
<h3 id="Mocha-Chai"><a href="#Mocha-Chai" class="headerlink" title="Mocha + Chai"></a><span class="exturl" data-url="aHR0cHM6Ly93d3cuenlidWx1by5jb20vbWRlZGl0b3IjOTExNzE0LWZ1bGwtcmVhZGVy">Mocha + Chai<i class="fa fa-external-link-alt"></i></span></h3><p><code>mocha+chai</code>是一个经典的组合主要用来测试函数功能,也能测试异步操作。也有常用<code>chai</code>的超集(拓展库)<code>sion-chai</code>来加强<code>chai</code></p>
<h3 id="Selenium2"><a href="#Selenium2" class="headerlink" title="Selenium2"></a><span class="exturl" data-url="aHR0cDovL3d3dy5zZWxlbml1bWhxLm9yZy9kb2Nz">Selenium2<i class="fa fa-external-link-alt"></i></span></h3><p><code>Selenium2</code>,它的主要新功能是集成了<code>Selenium1.0</code>以及<code>WebDriver</code>。<br>也就是说<code>Selenium2</code>是<code>Selenium</code>和<code>WebDriver</code>两个项目的合并,即<code>Selenium2</code>兼容<code>Selenium</code>,它既支持<code>Selenium API</code>也支持<code>WebDriver API</code>。<code>WebDriver</code>是一个用来进行复杂重复的<code>web</code>自动化测试的工具,意在提供一种比<code>Selenium1.0</code>更简单易学,有利于维护的<code>API</code>。它没有和任何测试框架进行绑定,所以他可以很好的在单元测试中调用。当启动<code>Selenium2</code>时通常会调起一个可见的界面,但也可以通过设置,让它以<code>PhantomJS</code>的形式进行无界面的测试<br>当然使用<code>Selenium2</code>必须额外的安装每种浏览器的<code>WebDriver</code><br><code>Selenium2</code>上手难度大于<code>PhantomJS</code></p>
<h3 id="NightwatchJs"><a href="#NightwatchJs" class="headerlink" title="NightwatchJs"></a><span class="exturl" data-url="aHR0cDovL25pZ2h0d2F0Y2hqcy5vcmcvZ3VpZGU=">NightwatchJs<i class="fa fa-external-link-alt"></i></span></h3><p>推特出品,基于<code>Selenium WebDriver API</code>开发,意味着支持浏览器自动化测试,内部集成了<code>mocha+chai</code>并将它加强,同时支持分组测试和单个测试,对语法进行了简化,归纳有以下特点:</p>
<ul>
<li>简单但强大的语法(更符合<code>js</code>书写习惯),只需要使用<code>JavaScript</code>和<code>CSS</code>选择器,开发者就能够非常迅捷地撰写测试。</li>
<li>开发者也不必初始化其他对象和类,只需要编写测试规范即可。</li>
<li>使用<code>CSS</code>选择器或<code>Xpath</code>,定位并验证页面中的元素或是执行命令。</li>
<li>易于扩展,便于开发者根据需要,实现与自己应用相关的命令。</li>
<li>…</li>
</ul>
<p>目前,<code>Selenium</code>是<code>JavaScript</code>的验收测试方面最流行的工具之一,同类的还有<code>PhantomJS</code>。二者都有其独到的方法:<code>Selenium</code>使用<code>WebDriver API</code>,而<code>PhantomJS</code>使用无界面的<code>WebKit</code>浏览器。它们都是非常成熟的工具,都具有强大的社区支持。它们与<code>Nightwatch</code>之间最大的不同,主要是在于语法的简易度以及对持续集成的支持。与<code>Nightwatch</code>相比,<code>Selenium</code>和<code>PhantomJS</code>都拥有更加冗长的语法,这会让编码变得更庞大</p>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="variable language_">this</span>.<span class="property">demoTestGoogle</span> = <span class="keyword">function</span> (<span class="params">browser</span>) {</span><br><span class="line"> browser</span><br><span class="line"> .<span class="title function_">url</span>(“<span class="attr">http</span>:<span class="comment">//www.google.com”)</span></span><br><span class="line"> .<span class="title function_">waitForElementVisible</span>(<span class="string">'body'</span>, <span class="number">1000</span>)</span><br><span class="line"> .<span class="title function_">setValue</span>(<span class="string">'input[type=text]'</span>, <span class="string">'nightwatch'</span>)</span><br><span class="line"> .<span class="title function_">waitForElementVisible</span>(<span class="string">'button[name=btnG]'</span>, <span class="number">1000</span>)</span><br><span class="line"> .<span class="title function_">click</span>(<span class="string">'button[name=btnG]'</span>)</span><br><span class="line"> .<span class="title function_">pause</span>(<span class="number">1000</span>)</span><br><span class="line"> .<span class="property">assert</span>.<span class="title function_">containsText</span>(<span class="string">'#main'</span>, <span class="string">'The Night Watch'</span>)</span><br><span class="line"> .<span class="title function_">end</span>();</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="comment">//也可以</span></span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = {</span><br><span class="line"> <span class="string">'step one'</span> : <span class="keyword">function</span> (<span class="params">browser</span>) {</span><br><span class="line"> browser</span><br><span class="line"> .<span class="title function_">url</span>(<span class="string">'http://www.google.com'</span>)</span><br><span class="line"> .<span class="title function_">waitForElementVisible</span>(<span class="string">'body'</span>, <span class="number">1000</span>)</span><br><span class="line"> .<span class="title function_">setValue</span>(<span class="string">'input[type=text]'</span>, <span class="string">'nightwatch'</span>)</span><br><span class="line"> .<span class="title function_">waitForElementVisible</span>(<span class="string">'button[name=btnG]'</span>, <span class="number">1000</span>)</span><br><span class="line"> },</span><br><span class="line"></span><br><span class="line"> <span class="string">'step two'</span> : <span class="keyword">function</span> (<span class="params">browser</span>) {</span><br><span class="line"> browser</span><br><span class="line"> .<span class="title function_">click</span>(<span class="string">'button[name=btnG]'</span>)</span><br><span class="line"> .<span class="title function_">pause</span>(<span class="number">1000</span>)</span><br><span class="line"> .<span class="property">assert</span>.<span class="title function_">containsText</span>(<span class="string">'#main'</span>, <span class="string">'Night Watch'</span>)</span><br><span class="line"> .<span class="title function_">end</span>();</span><br><span class="line"> }</span><br><span class="line">};</span><br></pre></td></tr></table></figure>
<h2 id="对前端框架的支持"><a href="#对前端框架的支持" class="headerlink" title="对前端框架的支持"></a>对前端框架的支持</h2><p>在实际开发中,我们可能是用了不同的框架。虽然我们完全可以在把源码编译成普通的<code>HTML/CSS/JS</code>代码然后测试,但是此种方法的弊端也显而易见:不易于自动化,必须等到所有模块开发完成才能测试…为此我们必须寻找某种方式使得测试不收框架的限制</p>
<h3 id="Vue"><a href="#Vue" class="headerlink" title="Vue"></a>Vue</h3><p>本身可以通过<code>new</code>一个<code>Vue</code>的方式挂载节点达到效果。<br>下面是一个简单的测试用例,测试<code>.hello h1</code>标签内容是否符合预期</p>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">Vue</span> <span class="keyword">from</span> <span class="string">'vue'</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">HelloWorld</span> <span class="keyword">from</span> <span class="string">'@/components/HelloWorld'</span></span><br><span class="line"></span><br><span class="line"><span class="title function_">describe</span>(<span class="string">'HelloWorld.vue'</span>, <span class="function">() =></span> {</span><br><span class="line"> <span class="title function_">it</span>(<span class="string">'should render correct contents'</span>, <span class="function">() =></span> {</span><br><span class="line"> <span class="keyword">const</span> <span class="title class_">Constructor</span> = <span class="title class_">Vue</span>.<span class="title function_">extend</span>(<span class="title class_">HelloWorld</span>)</span><br><span class="line"> <span class="keyword">const</span> vm = <span class="keyword">new</span> <span class="title class_">Constructor</span>().$mount()</span><br><span class="line"> <span class="title function_">expect</span>(vm.<span class="property">$el</span>.<span class="title function_">querySelector</span>(<span class="string">'.hello h1'</span>).<span class="property">textContent</span>)</span><br><span class="line"> .<span class="property">to</span>.<span class="title function_">equal</span>(<span class="string">'Welcome to Your Vue.js App'</span>)</span><br><span class="line"> })</span><br><span class="line">})</span><br></pre></td></tr></table></figure>
<h3 id="React"><a href="#React" class="headerlink" title="React"></a>React</h3><p>1.官方提供了两种方法:</p>
<ul>
<li>渲染虚拟<code>DOM</code>(<code>Shallow Rendering</code>)</li>
</ul>
<p>只渲染第一层,不渲染子组件,速度快,返回一个浅渲染的虚拟<code>DOM</code>对象。然后拿到节点的各种信息,进行测试</p>
<ul>
<li>渲染真实<code>DOM</code>节点(<code>renderIntoDocument</code>)</li>
</ul>
<p><code>renderIntoDocument</code> 方法要求存在一个真实的<code>DOM</code>环境,否则会报错。因此,测试用例之中,<code>DOM</code>环境(即<code>window</code>, <code>document</code> 和 <code>navigator</code> 对象)必须是存在的。<code>jsdom</code>库提供这项功能</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">import jsdom from 'jsdom';</span><br><span class="line"></span><br><span class="line">if (typeof document === 'undefined') {</span><br><span class="line"> global.document = jsdom.jsdom('<!doctype html><html><body></body></html>');</span><br><span class="line"> global.window = document.defaultView;</span><br><span class="line"> global.navigator = global.window.navigator;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>2.<code>Enzyme</code><br><code>Enzyme</code>是官方测试工具库的封装,它模拟了<code>jQuery</code>的<code>API</code>,非常直观,易于使用和学习,主要提供三种方法:</p>
<ul>
<li>shallow</li>
</ul>
<p><code>shallow</code>方法就是官方的<code>shallow rendering</code>的封装</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">import {shallow} from 'enzyme';</span><br><span class="line"></span><br><span class="line">describe('Enzyme Shallow', function () {</span><br><span class="line"> it('App\'s title should be Todos', function () {</span><br><span class="line"> let app = shallow(<App/>);</span><br><span class="line"> expect(app.find('h1').text()).to.equal('Todos');</span><br><span class="line"> });</span><br><span class="line">};</span><br></pre></td></tr></table></figure>
<ul>
<li>render</li>
</ul>
<p><code>render</code>方法将<code>React</code>组件渲染成静态的<code>HTML</code>字符串,然后分析这段<code>HTML</code>代码的结构,返回一个对象。它跟<code>shallow</code>方法非常像,主要的不同是采用了第三方HTML解析库<code>Cheerio</code>,它返回的是一个<code>Cheerio</code>实例对象。</p>
<ul>
<li>mount</li>
</ul>
<p><code>mount</code>方法用于将<code>React</code>组件加载为真实<code>DOM</code>节点</p>
<h2 id="最后"><a href="#最后" class="headerlink" title="最后"></a>最后</h2><p>回到开始,个人认为不要滥用测试,需要合理评估测试用例对团队项目的积极作用和消极作用。不合理或者不恰当的使用测试只会增加工作复杂度和成本。<br>并且测试用例只是检查代码的工具,所以不要本末倒置以测试用例强行约束业务代码</p>
<h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul>
<li><span class="exturl" data-url="aHR0cDovL3d3dy5jbmJsb2dzLmNvbS91c3Rid3V5aS9hcmNoaXZlLzIwMTIvMTAvMjYvMjc0MTIyMy5odG1s">关于TDD、BDD和DDD的一些看法<i class="fa fa-external-link-alt"></i></span></li>
<li><span class="exturl" data-url="aHR0cDovL3d3dy5pbmZvcS5jb20vY24vYXJ0aWNsZXMvdmlydHVhbC1wYW5lbC0lNjBUREQlNjAtJTYwQkREJTYw">虚拟座谈会:代码测试比率、测试驱动开发及行为驱动开发<i class="fa fa-external-link-alt"></i></span></li>
<li><span class="exturl" data-url="aHR0cDovL3d3dy5ydWFueWlmZW5nLmNvbS9ibG9nLzIwMTUvMTIvYS1tb2NoYS10dXRvcmlhbC1vZi1leGFtcGxlcy5odG1s">Mocha<i class="fa fa-external-link-alt"></i></span></li>
<li><span class="exturl" data-url="aHR0cHM6Ly9zZWdtZW50ZmF1bHQuY29tL2EvMTE5MDAwMDAwOTMzMzE1Nw==">PhantomJS<i class="fa fa-external-link-alt"></i></span></li>
<li><span class="exturl" data-url="aHR0cDovL3d3dy5pbmZvcS5jb20vY24vbmV3cy8yMDE0LzAyL25pZ2h0d2F0Y2g=">NightwatchJs<i class="fa fa-external-link-alt"></i></span></li>
<li><span class="exturl" data-url="aHR0cDovL2ZleC5iYWlkdS5jb20vYmxvZy8yMDE1LzA3L2Zyb250LWVuZC10ZXN0Lw==">前端自动化测试探索<i class="fa fa-external-link-alt"></i></span></li>
</ul>
]]></content>
<categories>
<category>test</category>
</categories>
<tags>
<tag>自动化测试</tag>
<tag>前端测试</tag>
</tags>
</entry>
<entry>
<title>慎重用for...in与for...of</title>
<url>/2017-10-27/for-in-and-for-of.html</url>
<content><![CDATA[<blockquote>
<p><code>for...in</code>和<code>for...of</code>都是用于数据的遍历。<code>for...in</code>是<code>ES5</code>标准,用于遍历对象属性(键),而<code>for...of</code>是<code>ES6</code>标准,是对<code>for...in</code>的修正,用于遍历对象元素(值),<code>for...of</code>兼容性不是很好(除了PC端老顽固<code>IE</code>之外,移动端某些安卓机和浏览器也是不支持它,具体可以<span class="exturl" data-url="aHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvemgtQ04vZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvU3RhdGVtZW50cy9mb3IuLi5vZg==">查看MDN<i class="fa fa-external-link-alt"></i></span>)。</p>
</blockquote>
<h2 id="for…in"><a href="#for…in" class="headerlink" title="for…in"></a>for…in</h2><figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="title class_">Object</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">objMethod</span> = <span class="keyword">function</span>(<span class="params"></span>) {};</span><br><span class="line"><span class="title class_">Array</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">arrMethod</span> = <span class="keyword">function</span>(<span class="params"></span>) {};</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> arr = [<span class="number">2</span>, <span class="number">9</span>, <span class="number">5</span>], obj = { <span class="attr">name</span>: <span class="string">'2ue'</span>, <span class="attr">w</span>: <span class="number">130</span> };</span><br><span class="line">arr.<span class="property">msg</span> = <span class="string">'hello'</span>;</span><br><span class="line">obj.<span class="property">msg</span> = <span class="string">'hello'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> i <span class="keyword">in</span> arr) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(i); <span class="comment">// "0", "1", "2", "msg", "arrCustom", "objCustom"</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> i <span class="keyword">in</span> arr) {</span><br><span class="line"> <span class="keyword">if</span> (arr.<span class="title function_">hasOwnProperty</span>(i)) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(i); <span class="comment">// "0", "1", "2", "msg"</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> i <span class="keyword">in</span> obj) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(i); <span class="comment">// "name", "w", "msg", "objCustom"</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> i <span class="keyword">in</span> obj) {</span><br><span class="line"> <span class="keyword">if</span> (obj.<span class="title function_">hasOwnProperty</span>(i)) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(i); <span class="comment">// "name", "w", "msg"</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>由上面的例子可以看出,<code>for...in</code>的一些特性:</p>
<ul>
<li>可以对<code>JSON</code>对象(数组和对象)进行遍历</li>
<li><code>for...in</code>会遍历对象的所有可枚举属性,包括原型,例如一些我们挂载到原型链上的一些<code>method</code>和<code>name</code></li>
<li>遍历很有可能不是按照对象的内部顺序(我们预期的)进行</li>
<li>对数组遍历时index索引为字符串型,在某些时候直接进行几何运算可能达不到预期结果</li>
</ul>
<h2 id="for…of"><a href="#for…of" class="headerlink" title="for…of"></a>for…of</h2><p><code>for...in</code>貌似强大的同时也带来很多副作用,想要达到预期的记过需要额外的代码来处理,所以<code>for...of</code>应运而生</p>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="title class_">Object</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">objMethod</span> = <span class="keyword">function</span>(<span class="params"></span>) {};</span><br><span class="line"><span class="title class_">Array</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">arrMethod</span> = <span class="keyword">function</span>(<span class="params"></span>) {};</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> arr = [<span class="number">2</span>, <span class="number">9</span>, <span class="number">5</span>], obj = { <span class="attr">name</span>: <span class="string">'2ue'</span>, <span class="attr">w</span>: <span class="number">130</span> };</span><br><span class="line">arr.<span class="property">msg</span> = <span class="string">'hello'</span>;</span><br><span class="line">obj.<span class="property">msg</span> = <span class="string">'hello'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> i <span class="keyword">of</span> arr) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(i); <span class="comment">// 2, 9, 5</span></span><br><span class="line">}</span><br><span class="line"><span class="comment">//如果用for...of循环对象,会报错`obj is not iterable`</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> i <span class="keyword">of</span> obj) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(i);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>可以看出,<code>for...of</code>方法在<code>for...in</code>上做了优化,并且限制了只能遍历数组。当然在<code>ES5</code>中,具有遍历数组功能的还有<code>map</code>、<code>filter</code>、<code>some</code>、<code>every</code>、<code>reduce</code>、<code>reduceRight</code>等,但是需要注意的是,有些方法不能被<code>break</code>句柄打断循环,使用<code>retun</code>也不能返回到外层,如<code>forEach</code></p>
<p>其实不难看出<code>for...in</code>是属于鸡肋属性了,而<code>for...of</code>由于兼容性原因,在某些地方也应该慎用,即使是移动端也要慎用,应该它并不兼容所有内核。</p>
<h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><p><span class="exturl" data-url="aHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvemgtQ04vZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvU3RhdGVtZW50cy9mb3IuLi5pbg==">for…in<i class="fa fa-external-link-alt"></i></span><br><span class="exturl" data-url="aHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvemgtQ04vZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvU3RhdGVtZW50cy9mb3IuLi5vZg==">for…of<i class="fa fa-external-link-alt"></i></span><br><span class="exturl" data-url="aHR0cDovL2VzNi5ydWFueWlmZW5nLmNvbS8jZG9jcy9pdGVyYXRvcg==">for-of循环是遍历实现iterator接口的成员<i class="fa fa-external-link-alt"></i></span></p>
]]></content>
<categories>
<category>javascript</category>
</categories>
<tags>
<tag>遍历</tag>
<tag>for...in</tag>
<tag>for...of</tag>
</tags>
</entry>
<entry>
<title>利用javascrit获取url传递的参数</title>
<url>/2016-06-15/get-url-values.html</url>
<content><![CDATA[<h2 id="神奇的url"><a href="#神奇的url" class="headerlink" title="神奇的url"></a>神奇的url</h2><p>一条url包含了很丰富的信息,那么我们如何来获取这些信息并有效的加以利用呢?<br>随便举个例子:<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD91dGY4PSVFMiU5QyU5MyZxPWphdmFzY3JpcHQ=">https://github.com/search?utf8=%E2%9C%93&q=javascript<i class="fa fa-external-link-alt"></i></span><br>这条url就是在github上搜索javascript后跳转页面对应的url。我们要做的就是获取’?’后面的参数,以及获取后可以用来做什么。</p>
<h2 id="获取参数"><a href="#获取参数" class="headerlink" title="获取参数"></a>获取参数</h2><h3 id="window-location的对象方法"><a href="#window-location的对象方法" class="headerlink" title="window.location的对象方法"></a>window.location的对象方法</h3><p><img data-src="/images/posts/windowLocation.png" alt="window.location的参数"></p>
<h3 id="获取url所有的参数"><a href="#获取url所有的参数" class="headerlink" title="获取url所有的参数"></a>获取url所有的参数</h3><p>我们可以直接通过<code>window.location.search</code>来取得这部分,也就是我们需要的url参数。</p>
<p>当<code>url</code>没有包含<code>?</code>时,<code>window.location.search</code>会返回<code>undefined</code>。</p>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">getUrlVal</span>(<span class="params">str</span>){</span><br><span class="line"> <span class="keyword">if</span>(!str || str.<span class="title function_">indexOf</span>(<span class="string">'?'</span>) != <span class="number">0</span>) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> <span class="keyword">var</span> urlValArry = str.<span class="title function_">replace</span>(<span class="string">'?'</span>,<span class="string">''</span>).<span class="title function_">split</span>(<span class="string">'&'</span>);</span><br><span class="line"> <span class="keyword">var</span> urlValObject = {};</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">var</span> i <span class="keyword">in</span> urlValArry){</span><br><span class="line"> urlValObject[urlValArry[i].<span class="title function_">split</span>(<span class="string">'='</span>)[<span class="number">0</span>]] = urlValArry[i].<span class="title function_">split</span>(<span class="string">'='</span>)[<span class="number">1</span>];</span><br><span class="line"> };</span><br><span class="line"> <span class="keyword">return</span> urlValObject;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="comment">// https://github.com/search?utf8=%E2%9C%93&q=javascript</span></span><br><span class="line"><span class="keyword">var</span> urlStr = <span class="variable language_">window</span>.<span class="property">location</span>.<span class="property">search</span>.<span class="title function_">replace</span>(<span class="string">'?'</span>,<span class="string">''</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">getUrlVal</span>(urlStr)); <span class="comment">//输出 Object {utf8: "%E2%9C%93", q: "javascript"}</span></span><br></pre></td></tr></table></figure>
<h3 id="获取url中指定键名-name-的键值-val"><a href="#获取url中指定键名-name-的键值-val" class="headerlink" title="获取url中指定键名(name)的键值(val)"></a>获取url中指定键名(name)的键值(val)</h3><figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">getOneVal</span>(<span class="params">str,name</span>){</span><br><span class="line"> <span class="keyword">if</span>(!str || str.<span class="title function_">indexOf</span>(<span class="string">'?'</span>) != <span class="number">0</span>) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> <span class="keyword">var</span> afterNameStr = str.<span class="title function_">replace</span>(<span class="string">'?'</span>,<span class="string">''</span>).<span class="title function_">split</span>(name)[<span class="number">1</span>];</span><br><span class="line"> <span class="keyword">var</span> strFirstSite = afterNameStr.<span class="title function_">indexOf</span>(<span class="string">'&'</span>);</span><br><span class="line"> <span class="comment">// 返回第一个&位置,如果没有'&'则返回字符串长度</span></span><br><span class="line"> strFirstSite = (strFirstSite == -<span class="number">1</span>) ? afterNameStr.<span class="property">length</span> : strFirstSite</span><br><span class="line"> <span class="keyword">var</span> reslt = afterNameStr.<span class="title function_">slice</span>(<span class="number">1</span>,strFirstSite);</span><br><span class="line"> <span class="keyword">return</span> reslt;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="comment">// 'http://www.gotoplay.com/active?itemtype=sport&active=basketball&time=20160614&place=N230&peopleNum=657'</span></span><br><span class="line"><span class="keyword">var</span> urlStr = <span class="variable language_">window</span>.<span class="property">location</span>.<span class="property">search</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">getOneVal</span>(urlStr,<span class="string">'time'</span>)) <span class="comment">//输出20160614</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">getOneVal</span>(urlStr,<span class="string">'peopleNum'</span>)) <span class="comment">//657</span></span><br></pre></td></tr></table></figure>
<h2 id="将方法绑定到原型链上"><a href="#将方法绑定到原型链上" class="headerlink" title="将方法绑定到原型链上"></a>将方法绑定到原型链上</h2><figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="title class_">String</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">toObj</span> = <span class="keyword">function</span>(<span class="params">key</span>){</span><br><span class="line"> <span class="comment">/*</span></span><br><span class="line"><span class="comment"> 如果有传入key,那么就只返回key对应的Val(找不到则返回undefined)</span></span><br><span class="line"><span class="comment"> 如果没有传入key,那么就返回一个object对象</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">var</span> str = <span class="variable language_">this</span>;</span><br><span class="line"> <span class="keyword">if</span>(str.<span class="title function_">indexOf</span>(<span class="string">'?'</span>) != <span class="number">0</span>) <span class="keyword">return</span> {};</span><br><span class="line"> <span class="keyword">if</span>(str.<span class="title function_">indexOf</span>(key) == -<span class="number">1</span>) <span class="keyword">return</span> <span class="literal">undefined</span>;</span><br><span class="line"> <span class="keyword">var</span> tmpArry = str.<span class="title function_">replace</span>(<span class="string">'?'</span>,<span class="string">''</span>).<span class="title function_">split</span>(<span class="string">'&'</span>);</span><br><span class="line"> <span class="keyword">var</span> reslt = {};</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">var</span> i <span class="keyword">in</span> tmpArry){</span><br><span class="line"> <span class="keyword">var</span> tempKeyVal = tmpArry[i].<span class="title function_">split</span>(<span class="string">'='</span>);</span><br><span class="line"> <span class="keyword">if</span>(!!key) {</span><br><span class="line"> <span class="keyword">if</span>(tempKeyVal[<span class="number">0</span>] != key) reslt = <span class="literal">undefined</span>;</span><br><span class="line"> reslt = tempKeyVal[<span class="number">1</span>];</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }<span class="keyword">else</span> {</span><br><span class="line"> reslt[tempKeyVal[<span class="number">0</span>]] = tempKeyVal[<span class="number">1</span>];</span><br><span class="line"> }</span><br><span class="line"> };</span><br><span class="line"> <span class="keyword">return</span> reslt;</span><br><span class="line">};</span><br><span class="line"><span class="comment">// http://www.gotoplay.com/active?itemtype=sport&active=basketball&time=20160614</span></span><br><span class="line"><span class="keyword">var</span> urlStr = <span class="variable language_">window</span>.<span class="property">location</span>.<span class="property">search</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(urlStr.<span class="title function_">toObj</span>()) <span class="comment">//{itemtype:'sport',active:'basketball',time:'20160614'}</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(urlStr.<span class="title function_">toObj</span>(<span class="string">'active'</span>)) <span class="comment">//basketball</span></span><br></pre></td></tr></table></figure>
<h2 id="利用正则表达式来获取参数"><a href="#利用正则表达式来获取参数" class="headerlink" title="利用正则表达式来获取参数"></a>利用正则表达式来获取参数</h2><p>强大的正则总是让人心生向往,利用正则无疑是最简洁优雅的一种方法</p>
<h3 id="获取指定某个参数"><a href="#获取指定某个参数" class="headerlink" title="获取指定某个参数"></a>获取指定某个参数</h3><figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">getUrlParam</span>(<span class="params">url,name</span>){</span><br><span class="line"> <span class="keyword">if</span>(!name) <span class="keyword">return</span>;</span><br><span class="line"> <span class="keyword">var</span> reg = <span class="keyword">new</span> <span class="title class_">RegExp</span>(<span class="string">'(^|&)'</span> + name + <span class="string">'=([^&]*)(&|$)'</span>, <span class="string">'i'</span>),</span><br><span class="line"> r = url.<span class="title function_">substr</span>(<span class="number">1</span>).<span class="title function_">match</span>(reg);</span><br><span class="line"> <span class="keyword">if</span> (r != <span class="literal">null</span>) {</span><br><span class="line"> <span class="keyword">return</span> (r[<span class="number">2</span>]);</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="获取所有的参数"><a href="#获取所有的参数" class="headerlink" title="获取所有的参数"></a>获取所有的参数</h3><figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">parse_url</span>(<span class="params">url</span>){</span><br><span class="line"> <span class="keyword">if</span>(!url) <span class="keyword">return</span>;</span><br><span class="line"> <span class="keyword">var</span> pattern = <span class="regexp">/(\w+)=(\w+)/ig</span>;</span><br><span class="line"> <span class="keyword">var</span> parames = {};</span><br><span class="line"> url.<span class="title function_">replace</span>(pattern, <span class="keyword">function</span>(<span class="params">a, b, c</span>){</span><br><span class="line"> parames[b] = c;</span><br><span class="line"> });</span><br><span class="line"> <span class="keyword">return</span> parames;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="参数的利用"><a href="#参数的利用" class="headerlink" title="参数的利用"></a>参数的利用</h2><p>在项目中这些参数有哪些用处呢,下面列举几个比较常用的用处</p>
<ul>
<li>传递数据</li>
<li>导航定位</li>
<li>更改状态</li>
<li>…</li>
</ul>
<h3 id="导航定位"><a href="#导航定位" class="headerlink" title="导航定位"></a>导航定位</h3><p>什么是导航定位?就是点击导航栏的标签,页面跳转后,对应的标签相应的会突出变化。如下图:<br><img data-src="/images/posts/navLocation.png" alt="navLocation"></p>
<p>跳转后有两种情况:<br>一种ajax异步刷新,只是局部页面发生变化,因为可以直接用点击事件来控制。<br>另外一种比较常见的方式就是整个页面刷新,这种情况下,点击事件就没用了,就必须另辟蹊径:<br> 1.比较传统的方法就是每个页面里面写一段CSS样式来控制<br> 2.那么另外一种不用说就是通过url的参数来定位咯<br>假如用每个页面写CSS样式来控制,可以明显感受到的弊端是:每次新的页面都需要修改对应的CSS<br>那么利用url来控制又需要做哪些事呢?<br> 1.首先需要约定参数,并且后台来传递这些参数<br> 2.然后在导航栏部分,对应的地方加上参数值,这一步,导航栏都是公用模板,并且规则都一样,所以只需要一次添加<br> 3.跳转后定位</p>
<h2 id="html代码"><a href="#html代码" class="headerlink" title="html代码"></a>html代码</h2><figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"nav"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"/index.htm?nav=index"</span>></span>首页<span class="tag"></<span class="name">a</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"/layout/post.htm?nav=post"</span>></span>文章<span class="tag"></<span class="name">a</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"/layout/tag.htm?nav=tags"</span>></span>标签<span class="tag"></<span class="name">a</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"/layout/about.htm?nav=aboutUs"</span>></span>关于我<span class="tag"></<span class="name">a</span>></span></span><br><span class="line"><span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure>
<h3 id="js代码"><a href="#js代码" class="headerlink" title="js代码"></a>js代码</h3><figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">getOneVal</span>(<span class="params">name,urlValStr</span>){</span><br><span class="line"> <span class="keyword">var</span> afterNameStr = urlValStr.<span class="title function_">split</span>(name)[<span class="number">1</span>];</span><br><span class="line"> <span class="keyword">var</span> strFirstSite = afterNameStr.<span class="title function_">indexOf</span>(<span class="string">'&'</span>);</span><br><span class="line"> strFirstSite = (strFirstSite == -<span class="number">1</span>) ? afterNameStr.<span class="property">length</span> : strFirstSit;</span><br><span class="line"> <span class="keyword">var</span> val = afterNameStr.<span class="title function_">slice</span>(<span class="number">1</span>,strFirstSite);</span><br><span class="line"> <span class="keyword">return</span> val;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> thisUrlVal = <span class="variable language_">window</span>.<span class="property">location</span>.<span class="property">search</span>.<span class="title function_">replace</span>(<span class="string">'?'</span>,<span class="string">''</span>);</span><br><span class="line"><span class="keyword">var</span> thisNVal = <span class="title function_">getOneVal</span>(<span class="string">'nav'</span>,urlValStr);</span><br><span class="line"></span><br><span class="line"><span class="comment">//定位</span></span><br><span class="line">$(<span class="string">'.nav a'</span>).<span class="title function_">each</span>(<span class="keyword">function</span>(<span class="params"></span>){</span><br><span class="line"> <span class="keyword">var</span> _this = $(<span class="variable language_">this</span>);</span><br><span class="line"> <span class="keyword">var</span> urlValStr = _this.<span class="title function_">attr</span>(<span class="string">'href'</span>).<span class="title function_">split</span>(<span class="string">'?'</span>)[<span class="number">1</span>];</span><br><span class="line"> <span class="keyword">var</span> nVal = <span class="title function_">getOneVal</span>(<span class="string">'nav'</span>,urlValStr);</span><br><span class="line"> <span class="keyword">if</span>(nVal == thisNVal) {</span><br><span class="line"> _this.<span class="title function_">addClass</span>(<span class="string">'on'</span>);</span><br><span class="line"> }</span><br><span class="line">})</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>javascript</category>
</categories>
<tags>
<tag>url</tag>
</tags>
</entry>
<entry>
<title>如何解决“cannot remove directory not empty”</title>
<url>/2019-05-29/how%20to%20solve%20cannot%20remove%20directory%20not%20empty.html</url>
<content><![CDATA[<blockquote>
<p>在windows系统下,删除文件或者文件夹,出现”Cannot remove xxx: Directory not empty”,如果在使用各种删除方法(比如使用命令行删除,解除占用,kill相关进程等)都得到相同的提示后,那么一般是磁盘存在问题,可以尝试使用<code>CHKDSK</code>命令来修复磁盘解决问题</p>
</blockquote>
<h2 id="CHKDSK"><a href="#CHKDSK" class="headerlink" title="CHKDSK"></a>CHKDSK</h2><p><code>CHKDSK</code>的全称是check disk,就是磁盘检查的意思。该工具基于被检测的分区所用的<span class="exturl" data-url="aHR0cHM6Ly9iYWlrZS5iYWlkdS5jb20vaXRlbS8lRTYlOTYlODclRTQlQkIlQjYlRTclQjMlQkIlRTclQkIlOUYvNDgyNzIxNT9mcm9tTW9kdWxlPWxlbW1hX2lubGluaw==">文件系统<i class="fa fa-external-link-alt"></i></span>,可以检查硬盘文件系统的完整性,并可以修复FAT16、FAT32和NTFS硬盘上的各种文件系统错误,创建和显示磁盘的状态报告。CHKDSK 还会列出并纠正磁盘上的错误。</p>
<h2 id="解决方案及步骤"><a href="#解决方案及步骤" class="headerlink" title="解决方案及步骤"></a>解决方案及步骤</h2><p>1、以管理员身份打开<code>CMD</code>命令行工具</p>
<p>2、输入<code>CHKDSK E:/F</code>,并回车。其中<code>E:</code>为出问题的磁盘,在使用时需要换成出问题的磁盘</p>
<p>3、等待检查完毕,最好重启电脑后再去删除对应目录,此时就能成功删除了</p>
<h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><p><span class="exturl" data-url="aHR0cHM6Ly96aC53aWtpcGVkaWEub3JnL3dpa2kvQ0hLRFNL">CHKDSK - 维基百科,自由的百科全书<i class="fa fa-external-link-alt"></i></span></p>
<p><span class="exturl" data-url="aHR0cHM6Ly9iYWlrZS5iYWlkdS5jb20vaXRlbS9jaGtkc2s=">chkdsk_百度百科<i class="fa fa-external-link-alt"></i></span></p>
]]></content>
<categories>
<category>/</category>
</categories>
<tags>
<tag>Windows</tag>
</tags>
</entry>
<entry>
<title>如何写一个日历组件</title>
<url>/2017-11-02/how-to-make-a-kalendar.html</url>
<content><![CDATA[<blockquote>
<p>众所周知,虽然<code>javascript</code>中关于时间的API有不少,我们可以通过方法单独的获取年、月、日、时、分、秒、毫秒…貌似很多,最近写了一个日历(以前写的,但写得很烂,最近优化一下),所以下面简单的记录一下如何写一个日历,列出了一些我在写日历过程中自己封装的一些方法</p>
</blockquote>
<h2 id="效果图"><a href="#效果图" class="headerlink" title="效果图"></a>效果图</h2><p>先来一张效果图,由于没有UI设计,所以就自己简单的设计了一个样式(好歹我也是设计专业的,虽然已不做设计很多年),虽然略丑,但重要的是功能!!!</p>
<p><img data-src="/images/posts/datepicker.gif" alt="datepicker"></p>
<h2 id="思路"><a href="#思路" class="headerlink" title="思路"></a>思路</h2><p>一个日历到底是怎样用代码生成的?其实观察一下现有的日历展现形式,可以很快的形成思路,就是:根据计算把日期号数对应到正确的星期几上,并按照顺序逐一输出。<br>以下是我的思路:</p>
<ul>
<li>取得月份的天数</li>
<li>取得月份第一天是星期几</li>
<li>循环对应号数和星期几返回一个数组对象<ul>
<li>返回数组对象的每一个子项至少包含:号数,星期几,然后根据情况添加:是否高亮,是否当前月,是否节日…等属性</li>
</ul>
</li>
</ul>
<h2 id="方法封装"><a href="#方法封装" class="headerlink" title="方法封装"></a>方法封装</h2><p>注意,为了保持方便调用<code>javascript</code>的方法,以及保持输出结果符合实际,所有的方法都有如下约定:</p>
<ul>
<li>在计算过程中<ul>
<li>所有的关于月份都是0~11的数字</li>
<li>所有的关于星期都是0~6的数字</li>
</ul>
</li>
<li>在输出的结果中<ul>
<li>所有关于月份的输出默认都是1-12的数字</li>
<li>所有关于星期的输出默认都是1-7的数字</li>
</ul>
</li>
</ul>
<p>所以在向调用方法传递参数过程中,月份以及星期几统统都需要按照实际月份减一</p>
<h3 id="获取月份天数"><a href="#获取月份天数" class="headerlink" title="获取月份天数"></a>获取月份天数</h3><p>在<code>javascript</code>中没有直接获取月份天数的方法,但是它提供了一个<code>getDate</code>方法可以获取日期的某一天。那我们只需要获取月份的最后一天(下一个月的第0天)就可以得知这个月的天数:</p>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="comment">// year是要获取的年份,闰年不一样</span></span><br><span class="line"><span class="comment">// month是要获取的月份</span></span><br><span class="line"><span class="comment">// 返回当前月天数</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">getMonthDays</span>(<span class="params">year, month</span>){</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Date</span>(year, month + <span class="number">1</span>, <span class="number">0</span>).<span class="title function_">getDate</span>();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="title function_">getMonthDays</span>(<span class="number">2016</span>,<span class="number">2</span>) <span class="comment">//29</span></span><br><span class="line"><span class="title function_">getMonthDays</span>(<span class="number">2017</span>,<span class="number">2</span>) <span class="comment">//28</span></span><br></pre></td></tr></table></figure>
<h3 id="获取星期几"><a href="#获取星期几" class="headerlink" title="获取星期几"></a>获取星期几</h3><figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="comment">// year是要获取的年份</span></span><br><span class="line"><span class="comment">// month是要获取的月份</span></span><br><span class="line"><span class="comment">// 返回数字几则是星期几</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">getWeekday</span>(<span class="params">year, month, day</span>){</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Date</span>(year, month, day).<span class="title function_">getDate</span>() + <span class="number">1</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="title function_">getWeekday</span>(<span class="number">2016</span>,<span class="number">10</span>,<span class="number">9</span>) <span class="comment">//输出4,表示2016年11月9是星期4</span></span><br><span class="line"><span class="title function_">getWeekday</span>(<span class="number">2017</span>,<span class="number">10</span>,<span class="number">9</span>) <span class="comment">//输出5,表示2017年11月9是星期5</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h3 id="获取月份有几个星期"><a href="#获取月份有几个星期" class="headerlink" title="获取月份有几个星期"></a>获取月份有几个星期</h3><p>要计算月份包含几个星期,需要两个数据:月份天数和月份第一天是星期几,就能得到想要的结果</p>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="comment">// year是要获取的年份</span></span><br><span class="line"><span class="comment">// month是要获取的月份</span></span><br><span class="line"><span class="comment">// 返回当前月包含几个星期</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">getweeksInMonth</span>(<span class="params">year, month</span>){</span><br><span class="line"></span><br><span class="line"> <span class="keyword">var</span> days = <span class="title function_">getMonthDays</span>(year, month);</span><br><span class="line"> <span class="keyword">var</span> <span class="title class_">FirstDayWeekday</span> = <span class="title function_">getWeekday</span>(year, month, <span class="number">1</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="title class_">Math</span>.<span class="title function_">ceil</span>(days + <span class="title class_">FirstDayWeekday</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="循环生成月份对象"><a href="#循环生成月份对象" class="headerlink" title="循环生成月份对象"></a>循环生成月份对象</h3><p>有了以上方法之后,就可以通过循环生成一个简单的月份对象了。<br>在这里需要注意,日历的排序有两种:</p>
<ul>
<li>每一行以星期日开头</li>
<li>每一行以星期开头</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="comment">// year是要获取的年份</span></span><br><span class="line"><span class="comment">// month是要获取的月份</span></span><br><span class="line"><span class="comment">// day天,用来判断是否是当前天</span></span><br><span class="line"><span class="comment">// type表明要星期几开头,0为星期一开头,1为星期日开头,默认为0</span></span><br><span class="line"><span class="comment">// 返回当前月包含几个星期</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">WEEKTABLE</span> = [{</span><br><span class="line"> <span class="attr">cn</span>: [<span class="string">'星期日'</span>, <span class="string">'星期一'</span>, <span class="string">'星期二'</span>, <span class="string">'星期三'</span>, <span class="string">'星期四'</span>, <span class="string">'星期五'</span>, <span class="string">'星期六'</span>],</span><br><span class="line"> <span class="attr">cns</span>: [<span class="string">'日'</span>, <span class="string">'一'</span>, <span class="string">'二'</span>, <span class="string">'三'</span>, <span class="string">'四'</span>, <span class="string">'五'</span>, <span class="string">'六'</span>],</span><br><span class="line"> <span class="attr">en</span>: [<span class="string">'Sun'</span>, <span class="string">'Mon'</span>, <span class="string">'Tue'</span>, <span class="string">'Wed'</span>, <span class="string">'Thu'</span>, <span class="string">'Fri'</span>, <span class="string">'Sat'</span>]</span><br><span class="line">},{</span><br><span class="line"> <span class="attr">cn</span>: [<span class="string">'星期一'</span>, <span class="string">'星期二'</span>, <span class="string">'星期三'</span>, <span class="string">'星期四'</span>, <span class="string">'星期五'</span>, <span class="string">'星期六'</span>, <span class="string">'星期日'</span>],</span><br><span class="line"> <span class="attr">cns</span>: [<span class="string">'一'</span>, <span class="string">'二'</span>, <span class="string">'三'</span>, <span class="string">'四'</span>, <span class="string">'五'</span>, <span class="string">'六'</span>, <span class="string">'日'</span>],</span><br><span class="line"> <span class="attr">en</span>: [<span class="string">'Mon'</span>, <span class="string">'Tue'</span>, <span class="string">'Wed'</span>, <span class="string">'Thu'</span>, <span class="string">'Fri'</span>, <span class="string">'Sat'</span>, <span class="string">'Sun'</span>]</span><br><span class="line">}]</span><br><span class="line"></span><br><span class="line"><span class="title function_">getMonthDaysArray</span>(<span class="params">year, month, day, type</span>) {</span><br><span class="line"> <span class="keyword">if</span> (<span class="keyword">typeof</span> day === <span class="string">'undefined'</span> && year === <span class="variable constant_">YEAR</span> && month === <span class="variable constant_">MONTH</span>) day = <span class="variable constant_">DAY</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">var</span> dayArrays = [];</span><br><span class="line"> <span class="keyword">var</span> days = <span class="variable language_">this</span>.<span class="title function_">getMonthDays</span>(year, month), preDays = <span class="variable language_">this</span>.<span class="title function_">getMonthDays</span>(year, month - <span class="number">1</span>);</span><br><span class="line"> <span class="keyword">var</span> thisMonthFirstDayInWeek = <span class="variable language_">this</span>.<span class="title function_">getWeekday</span>(year, month, <span class="number">1</span>), thisMonthLastDayInWeek = <span class="variable language_">this</span>.<span class="title function_">getWeekday</span>(year, month, days);</span><br><span class="line"></span><br><span class="line"> type = !type || type !== <span class="number">1</span> ? <span class="number">0</span> : <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">//上月在当月日历面板中的排列</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i < thisMonthFirstDayInWeek; i++) {</span><br><span class="line"> dayArrays.<span class="title function_">push</span>({</span><br><span class="line"> <span class="attr">dayNum</span>: (preDays - thisMonthFirstDayInWeek + i + <span class="number">1</span>),</span><br><span class="line"> <span class="attr">weekDay</span>: <span class="variable constant_">WEEKTABLE</span>[type].<span class="property">cn</span>[i]</span><br><span class="line"> })</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//当月日历面板中的排列</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">1</span>; i <= days; i++) {</span><br><span class="line"> <span class="keyword">var</span> weekDayFlag = (thisMonthFirstDayInWeek + i - <span class="number">1</span>) % <span class="number">7</span></span><br><span class="line"> dayArrays.<span class="title function_">push</span>({</span><br><span class="line"> <span class="attr">dayNum</span>: i,</span><br><span class="line"> <span class="attr">weekDay</span>: <span class="variable constant_">WEEKTABLE</span>[type].<span class="property">cn</span>[weekDayFlag],</span><br><span class="line"> <span class="attr">selected</span>: i === +day,</span><br><span class="line"> <span class="attr">isThisMonth</span>: <span class="literal">true</span></span><br><span class="line"> })</span><br><span class="line"> };</span><br><span class="line"> <span class="comment">//下月在当月日历面板中的排列</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">1</span>; i <= (<span class="number">6</span> - thisMonthLastDayInWeek); i++) {</span><br><span class="line"> <span class="keyword">var</span> weekDayFlag = (thisMonthFirstDayInWeek + days + i - <span class="number">1</span>) % <span class="number">7</span></span><br><span class="line"> dayArrays.<span class="title function_">push</span>({</span><br><span class="line"> <span class="attr">dayNum</span>: i,</span><br><span class="line"> <span class="attr">weekDay</span>: <span class="variable constant_">WEEKTABLE</span>[type].<span class="property">cn</span>[weekDayFlag]</span><br><span class="line"> })</span><br><span class="line"> };</span><br><span class="line"> <span class="keyword">return</span> dayArrays;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="格式化时间"><a href="#格式化时间" class="headerlink" title="格式化时间"></a>格式化时间</h3><p>涉及到时间时,常常需要把时间格式进行转换,为了应对多中需求,所以自己封装了一个</p>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 参数fmt必须</span></span><br><span class="line"><span class="comment">// date参数不必须,允许字符串和时间对象,不传或者传无法转换成合法时间对象的字符串则默认当前时间,</span></span><br><span class="line"><span class="comment">// 年(YYYY/yyyy)固定四个占位符</span></span><br><span class="line"><span class="comment">// 月(M)、日(d)、小时(h)、分(m)、秒(s)可以用 1-2个占位符,严格区分大小写,</span></span><br><span class="line"><span class="comment">// 毫秒(ms/mss)最多三个占位符,分别对应56,056这种类型</span></span><br><span class="line"><span class="comment">// 例子:</span></span><br><span class="line"><span class="comment">// (Format("yyyy-MM-dd hh:mm:ss:ms") ==> 2006-07-02 08:09:04:23</span></span><br><span class="line"><span class="comment">// (Format("yyyy-MM-dd hh:mm:ss:mss") ==> 2006-07-02 08:09:04:023</span></span><br><span class="line"><span class="comment">// (Format("yyyy-M-d h:m:s:ms") ==> 2006-7-2 8:9:4.180</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">formate</span>(<span class="params">fmt, date</span>){</span><br><span class="line"> date = <span class="keyword">new</span> <span class="title class_">Date</span>(date).<span class="title function_">toString</span>() === <span class="string">'Invalid Date'</span> ? <span class="keyword">new</span> <span class="title class_">Date</span>() : <span class="keyword">new</span> <span class="title class_">Date</span>(date);</span><br><span class="line"> <span class="keyword">var</span> _rules = [{</span><br><span class="line"> <span class="attr">rule</span>: <span class="string">'[yY]{4}'</span>,</span><br><span class="line"> <span class="attr">value</span>: _date.<span class="title function_">getFullYear</span>()</span><br><span class="line"> }, {</span><br><span class="line"> <span class="attr">rule</span>: <span class="string">'M+'</span>,</span><br><span class="line"> <span class="attr">value</span>: _date.<span class="title function_">getMonth</span>() + <span class="number">1</span></span><br><span class="line"> }, {</span><br><span class="line"> <span class="attr">rule</span>: <span class="string">'[dD]+'</span>,</span><br><span class="line"> <span class="attr">value</span>: _date.<span class="title function_">getDate</span>()</span><br><span class="line"> }, {</span><br><span class="line"> <span class="attr">rule</span>: <span class="string">'h+'</span>,</span><br><span class="line"> <span class="attr">value</span>: _date.<span class="title function_">getHours</span>()</span><br><span class="line"> }, {</span><br><span class="line"> <span class="attr">rule</span>: <span class="string">'m+'</span>,</span><br><span class="line"> <span class="attr">value</span>: _date.<span class="title function_">getMinutes</span>()</span><br><span class="line"> }, {</span><br><span class="line"> <span class="attr">rule</span>: <span class="string">'s+'</span>,</span><br><span class="line"> <span class="attr">value</span>: _date.<span class="title function_">getSeconds</span>()</span><br><span class="line"> }, {</span><br><span class="line"> <span class="attr">rule</span>: <span class="string">'ms{1,2}'</span>,</span><br><span class="line"> <span class="attr">value</span>: _date.<span class="title function_">getMilliseconds</span>()</span><br><span class="line"> }];</span><br><span class="line"></span><br><span class="line"> _rules.<span class="title function_">forEach</span>(<span class="keyword">function</span> (<span class="params">_r</span>){</span><br><span class="line"> <span class="keyword">const</span> rule = _r.<span class="property">rule</span>, val = _r.<span class="property">value</span>;</span><br><span class="line"> fmt = fmt.<span class="title function_">replace</span>(<span class="keyword">new</span> <span class="title class_">RegExp</span>(rule), <span class="keyword">function</span> (<span class="params">$1</span>) {</span><br><span class="line"> <span class="keyword">const</span> rLen = val.<span class="title function_">toString</span>().<span class="property">length</span>, fLen = $1.<span class="property">length</span>;</span><br><span class="line"> <span class="keyword">return</span> (fLen !== <span class="number">2</span> || rLen >= fLen) ? val : [<span class="string">'00'</span>, val].<span class="title function_">join</span>().<span class="title function_">substr</span>(rLen);</span><br><span class="line"> });</span><br><span class="line"> });</span><br><span class="line"> <span class="keyword">return</span> fmt;</span><br><span class="line">}</span><br><span class="line"><span class="comment">//调用:</span></span><br><span class="line"><span class="keyword">var</span> time1 = <span class="title function_">formate</span>(<span class="string">"YYYY/MM/DD hh:mm:ss"</span>, <span class="keyword">new</span> <span class="title class_">Date</span>()); <span class="comment">//2017/11/2 11:09:20</span></span><br><span class="line"><span class="keyword">var</span> time2 = <span class="title function_">formate</span>(<span class="string">"YYYY-MM-DD"</span>, time1); <span class="comment">//2017-11-2</span></span><br><span class="line"><span class="keyword">var</span> time3 = <span class="title function_">formate</span>(<span class="string">"MM-DD-YYYY"</span>, time2); <span class="comment">//11-2-2017</span></span><br></pre></td></tr></table></figure>
<h2 id="最后"><a href="#最后" class="headerlink" title="最后"></a>最后</h2><p>附上这些方法的源码<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tLzJ1ZS92dWkvYmxvYi9tYXN0ZXIvc3JjL3V0aWxzL2RhdGVwaWNrZXIuanM=">datepicker<i class="fa fa-external-link-alt"></i></span><br>基于vue实现的一个日历:</p>
<ul>
<li>demo<span class="exturl" data-url="aHR0cHM6Ly8ydWUuZ2l0aHViLmlvL3Z1aS8jL0RhdGVQaWNrZXI=">vue-datepicker<i class="fa fa-external-link-alt"></i></span></li>
<li>源码<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tLzJ1ZS92dWkvYmxvYi9tYXN0ZXIvc3JjL2NvbXBvbmVudHMvZGF0ZVBpY2tlci9kYXRlUGlja2VyUGFuZWwudnVl">datePickerPanel.vue<i class="fa fa-external-link-alt"></i></span></li>
</ul>
<p>当然这只是最简单的日历输出,思路也是超级简单(感觉有点Low),如果有大神愿意分享它的经验欢迎,来邮~</p>
]]></content>
<categories>
<category>javascript</category>
</categories>
<tags>
<tag>日历</tag>
<tag>kalendar</tag>
</tags>
</entry>
<entry>
<title>Javascript系列 - Javascript数组方法</title>
<url>/2016-08-11/javascript-array-method.html</url>
<content><![CDATA[<blockquote>
<p>Javascript的Array(数组对象)方法整理,对比他们的功能,返回值,分析他们的参数,以及具体的作用。</p>
</blockquote>
<h2 id="length:获取数组长度"><a href="#length:获取数组长度" class="headerlink" title="length:获取数组长度"></a>length:获取数组长度</h2><blockquote>
<ul>
<li>Method: Arry.length</li>
<li><strong>被引用数组(Arry)是否改变: NO</strong></li>
<li>Arguments: 无</li>
<li>Return: 返回被引用数组长度</li>
</ul>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> arry = [<span class="number">1</span>,<span class="number">6</span>,<span class="number">8</span>,<span class="string">'2ue'</span>,<span class="string">'o90'</span>]</span><br><span class="line">arry.<span class="property">length</span> <span class="comment">//返回5,arry = [1,6,8,'2ue','o90']</span></span><br></pre></td></tr></table></figure>
<h2 id="join:连接数组内各元素组成一个字符串"><a href="#join:连接数组内各元素组成一个字符串" class="headerlink" title="join:连接数组内各元素组成一个字符串"></a>join:连接数组内各元素组成一个字符串</h2><blockquote>
<ul>
<li>Method: Arry.join(str)</li>
<li><strong>被引用数组(Arry)是否改变: NO</strong></li>
<li>Arguments: <code>str</code>非必需<ul>
<li><code>str</code>不存在时(不传递str)以默认逗号连接元素</li>
<li><code>str</code>可以为任意字符串,也可以为空(‘’)(字符串为空时,各元素之间无连接符号)</li>
</ul>
</li>
<li>Return: 返回连接后的字符串</li>
</ul>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> arry = [<span class="number">1</span>,<span class="number">6</span>,<span class="number">8</span>,<span class="string">'2ue'</span>,<span class="string">'o90'</span>]</span><br><span class="line">arry.<span class="title function_">join</span>() <span class="comment">//返回字符串1,6,8,2ue,o90,arry = [1,6,8,'2ue','o90']</span></span><br><span class="line">arry.<span class="title function_">join</span>(<span class="string">'-'</span>) <span class="comment">//返回字符串1-6-8-2ue-o90,arry = [1,6,8,'2ue','o90']</span></span><br><span class="line">arry.<span class="title function_">join</span>(<span class="string">''</span>) <span class="comment">//返回字符串1682ueo90,arry = [1,6,8,'2ue','o90']</span></span><br></pre></td></tr></table></figure>
<p><strong>注意如果需要加数组arry以逗号形式展示到页面,则不需要<code>.join()</code>方法,因为javascript的赋值操作会自动调用<code>.toString()</code>方法</strong>,如</p>