-
Notifications
You must be signed in to change notification settings - Fork 3
/
atom.xml
555 lines (277 loc) · 133 KB
/
atom.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
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>I am Oliver</title>
<link href="https://ochukai.github.io/atom.xml" rel="self"/>
<link href="https://ochukai.github.io/"/>
<updated>2023-07-16T05:40:56.177Z</updated>
<id>https://ochukai.github.io/</id>
<author>
<name>Oliver Wang</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>Clearfix 的正确写法~</title>
<link href="https://ochukai.github.io/wrong-clearfix-make-me-crazy/"/>
<id>https://ochukai.github.io/wrong-clearfix-make-me-crazy/</id>
<published>2019-06-06T02:23:45.000Z</published>
<updated>2023-07-16T05:40:56.177Z</updated>
<content type="html"><![CDATA[<p>Clearfix 就是这么简单!</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.clearfix</span><span class="selector-pseudo">:after</span>,</span><br><span class="line"><span class="selector-class">.clearfix</span><span class="selector-pseudo">:before</span> {</span><br><span class="line"> <span class="attribute">display</span>: table;</span><br><span class="line"> <span class="attribute">content</span>: <span class="string">" "</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.clearfix</span><span class="selector-pseudo">:after</span> {</span><br><span class="line"> <span class="attribute">clear</span>: both</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><p>Clearfix 就是这么简单!</p>
<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</summary>
<category term="css" scheme="https://ochukai.github.io/categories/css/"/>
<category term="css" scheme="https://ochukai.github.io/tags/css/"/>
<category term="html" scheme="https://ochukai.github.io/tags/html/"/>
<category term="clearfix" scheme="https://ochukai.github.io/tags/clearfix/"/>
</entry>
<entry>
<title>我的第三个纹身 - 小死神 💀</title>
<link href="https://ochukai.github.io/my-third-tattoo/"/>
<id>https://ochukai.github.io/my-third-tattoo/</id>
<published>2019-05-06T09:54:06.000Z</published>
<updated>2023-07-16T03:46:17.423Z</updated>
<content type="html"><![CDATA[<p>其实很早之前就有第三个了,拖延症最近一直很严重,整整三个月才治好,哈哈~</p><p>这次手稿我搞丢了,就直接上图吧,咳咳,不该显示的我都已经屏蔽掉了,现在只剩下愉悦~ 😄</p><p><img src="/../images/third-tattoo.jpg" alt="我的死神"></p><p>这次纹身还是大众点评送的,不过纹身师水平还凑活,关键是力气大,男的,压得我喘不过气,因为他的手正好按住了我的肩膀,纹身的针在我胸前游走,又痒又疼,骨头也嗡嗡的,动又不敢动,简直酸爽。</p><p>介个纹身也还算喜欢吧,下次准备在左胸前来个图腾,或者字母,或者水墨来一团,总之就是还没有想好~ 假奶~</p>]]></content>
<summary type="html"><p>其实很早之前就有第三个了,拖延症最近一直很严重,整整三个月才治好,哈哈~</p>
<p>这次手稿我搞丢了,就直接上图吧,咳咳,不该显示的我都已经屏蔽掉了,现在只剩下愉悦~ 😄</p>
<p><img src="/../images/third-tattoo.jpg" al</summary>
<category term="TATTOO" scheme="https://ochukai.github.io/tags/tattoo/"/>
<category term="纹身" scheme="https://ochukai.github.io/tags/%E7%BA%B9%E8%BA%AB/"/>
<category term="死神" scheme="https://ochukai.github.io/tags/%E6%AD%BB%E7%A5%9E/"/>
</entry>
<entry>
<title>千字文</title>
<link href="https://ochukai.github.io/qian-zi-wen/"/>
<id>https://ochukai.github.io/qian-zi-wen/</id>
<published>2019-04-30T07:32:12.000Z</published>
<updated>2023-07-16T03:46:17.424Z</updated>
<content type="html"><![CDATA[<div style="text-align:center; font-size: 22px;line-height:2;font-family:'楷体';color: #111;margin-top: -50px;">天地玄黄 宇宙洪荒 日月盈昃(zè) 辰宿列张寒来暑往 秋收冬藏(cáng) 闰馀(yú)成岁 律吕调阳云腾致雨 露结为霜 金生丽水 玉出昆冈剑号巨阙(què) 珠称夜光 果珍李柰 菜重芥姜海咸河淡 鳞潜羽翔 龙师火帝 鸟官人皇始制文字 乃服衣裳 推位让国 有虞陶唐吊民伐罪 周发殷汤 坐朝(cháo)问道 垂拱平章爱育黎首 臣伏戎羌(qiāng) 遐迩一体 率宾归王鸣凤在竹 白驹食场 化被草木 赖及万方盖此身发 四大五常 恭惟鞠养 岂敢毁伤女慕贞洁 男效才良 知过必改 得能莫忘罔谈彼短 靡(mí)恃己长 信使可复 器欲难量墨悲丝染 诗赞羔羊 景行维贤 克念作圣德建名立 形端表正 空谷传声 虚堂习听祸因恶积 福缘善庆 尺璧非宝 寸阴是竞资父事君 曰(yuē)严与敬 孝当竭力 忠则尽命临深履薄 夙兴温凊 似兰斯馨 如松之盛川流不息 渊澄取映 容止若思 言辞安定笃初诚美 慎终宜令 荣业所基 籍甚无竟学优登仕 摄职从政 存以甘棠 去而益咏乐殊贵贱 礼别尊卑 上和下睦 夫唱妇随外受傅训 入奉母仪 诸姑伯叔 犹子比儿孔怀兄弟 同气连枝 交友投分 切磨箴(zhēn)规仁慈隐恻 造次弗离 节义廉退 颠沛匪亏性静情逸 心动神疲 守真志满 逐物意移坚持雅操 好爵自縻 都邑华夏 东西二京背邙(máng)面洛 浮渭据泾 宫殿盘郁 楼观飞惊图写禽兽 画彩仙灵 丙舍傍启 甲帐对楹(yíng)肆筵设席 鼓瑟吹笙 升阶纳陛 弁(biàn)转疑星右通广内 左达承明 既集坟典 亦聚群英杜稿钟隶 漆书壁经 府罗将相 路侠槐卿户封八县 家给(jǐ)千兵高冠陪辇(niǎn) 驱毂(gǔ)振缨世禄侈富 车驾肥轻 策功茂实 勒碑刻铭磻溪伊尹 佐时阿衡 奄(yǎn)宅曲阜 微旦孰营桓公匡合 济弱扶倾 绮回汉惠 说感武丁俊乂(yì)密勿 多士寔(shí)宁 晋楚更霸 赵魏困横假途灭虢(guó) 践土会盟 何遵约法 韩弊烦刑起翦颇牧 用军最精 宣威沙漠 驰誉丹青九州禹迹 百郡秦并 岳宗泰岱 禅主云亭雁门紫塞 鸡田赤城 昆池碣石 巨野洞庭旷远绵邈 岩岫(xiù)杳冥 治本于农 务兹稼穑(sè)俶(chù)载南亩 我艺黍(shǔ)稷税熟贡新 劝赏黜陟(chù zhì)孟轲敦素 史鱼秉直 庶几中庸 劳谦谨敕聆音察理 鉴貌辨色 贻厥嘉猷(yóu) 勉其祗植省躬讥诫 宠增抗极 殆辱近耻 林皋幸即两疏见机 解组谁逼 索居闲处 沉默寂寥求古寻论 散虑逍遥 欣奏累遣 戚谢欢招渠荷的(dì)历 园莽抽条 枇杷晚翠 梧桐蚤凋陈根委翳(yì) 落叶飘摇 游鹍(kūn)独运 凌摩绛霄耽(dān)读玩市 寓目囊箱易輶(yóu)攸畏 属耳垣(yuán)墙具膳餐饭 适口充肠 饱饫烹宰 饥厌糟糠亲戚故旧 老少异粮 妾御绩纺 侍巾帷房纨扇圆絜(jié) 银烛炜煌 昼眠夕寐 蓝笋象床弦歌酒宴 接杯举觞 矫手顿足 悦豫且康嫡后嗣续 祭祀烝尝 稽颡(sǎng)再拜 悚惧恐惶笺牒简要 顾答审详 骸垢想浴 执热愿凉驴骡犊特 骇跃超骧(xiāng) 诛斩贼盗 捕获叛亡布射僚丸 嵇琴阮啸 恬笔伦纸 钧巧任钓释纷利俗 竝(bìng)皆佳妙 毛施淑姿 工颦(pín)妍笑年矢每催 曦晖朗曜 璇玑悬斡 晦魄环照指薪修祜(hù) 永绥(suí)吉劭 矩步引领 俯仰廊庙束带矜(jīn)庄 徘徊瞻眺 孤陋寡闻 愚蒙等诮(qiào)谓语助者 焉哉乎也</div>]]></content>
<summary type="html"><div style="text-align:center; font-size: 22px;line-height:2;font-family:'楷体';color: #111;margin-top: -50px;">
天地玄黄 宇宙洪荒 日月盈昃(zè) 辰宿列张
寒来暑往 </summary>
<category term="练字" scheme="https://ochukai.github.io/tags/%E7%BB%83%E5%AD%97/"/>
<category term="千字文" scheme="https://ochukai.github.io/tags/%E5%8D%83%E5%AD%97%E6%96%87/"/>
</entry>
<entry>
<title>❤ 如何支持 MathJax~</title>
<link href="https://ochukai.github.io/mathjax-support-guide/"/>
<id>https://ochukai.github.io/mathjax-support-guide/</id>
<published>2019-04-22T07:49:39.000Z</published>
<updated>2023-07-16T03:46:17.423Z</updated>
<content type="html"><![CDATA[<p>好久好久之前就有一个 issue 提出来要支持 <strong>MathJax</strong>,结果到现在我都没有实现,直到昨天看到有人又要这个,所以我觉得还是写写吧,毕竟不是太复杂的东西。</p><p>是这个 <a href="https://github.com/mathjax/MathJax">MathJax</a>, 但是这个 repo clone 到本地之后,我发现他有 50m + 的大小,于是找了一个 cdn:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML</span><br></pre></td></tr></table></figure><p>想要页面支持 MathJax,只要这个页面引入他的 js,然后按照 MathJax 的语法来写公式就 ok 了。</p><h2 id="mathjax-true"><a href="#mathjax-true" class="headerlink" title="mathjax: true"></a>mathjax: true</h2><p>当然作为一个主题,我就帮你们把 js 引入了,你们只要写公式就好了,但是因为 MathJax 的 js 还是挺大的,所以我在页头加了一个属性:<strong>mathjax</strong>,就是来标加,如果当前文章需要 MathJax 的支持,就把 <strong>mathjax</strong> 设置为 <strong>true</strong>。</p><p>就像这样:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">title: ❤ 如何支持 MathJax~</span><br><span class="line">tags:</span><br><span class="line"> - mathjax</span><br><span class="line">date: 2019-04-22 15:49:39</span><br><span class="line">mathjax: true</span><br><span class="line">---</span><br><span class="line"># 文章内容</span><br></pre></td></tr></table></figure><p>其他页面就不用添加这个属性了,自动就不会引入 MathJax 的 js。</p><h2 id="开始写公式"><a href="#开始写公式" class="headerlink" title="开始写公式"></a>开始写公式</h2><p>下面就是写公式了,之前我都没有接触过这个东西,所以随便从网上找了一个</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$$\sum_{i=0}^n i^2 = \frac{(n^2+n)(2n+1)}{6}$$</span><br></pre></td></tr></table></figure><blockquote><p>new post -> 复制代码 -> yarn start -> 打开 localhost:4000</p></blockquote><p>发现公式没有出来,于是我又去 bing 查了一下,原来还需要改一个东西,</p><p>大概就在 <code>~/node_modules/marked/lib/marked.js</code> 的第 464 行,如果找不到,就搜索 escape。</p><p><img src="/images/mathjax-marked.png" alt="修改代码"></p><p>然后照图,把 <strong>escape</strong>, <strong>em</strong> 修改为下面的值:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> inline = {</span><br><span class="line"> <span class="comment">// escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,</span></span><br><span class="line"> <span class="attr">escape</span>: <span class="regexp">/^\\([`*\[\]()# +\-.!_>])/</span>,</span><br><span class="line"> <span class="attr">autolink</span>: <span class="regexp">/^<(scheme:[^\s\x00-\x1f<>]*|email)>/</span>,</span><br><span class="line"> <span class="attr">url</span>: noop,</span><br><span class="line"> <span class="attr">tag</span>: <span class="regexp">/^<!--[\s\S]*?-->|^<\/?[a-zA-Z0-9\-]+(?:"[^"]*"|'[^']*'|\s[^<'">\/\s]*)*?\/?>/</span>,</span><br><span class="line"> <span class="attr">link</span>: <span class="regexp">/^!?\[(inside)\]\(href\)/</span>,</span><br><span class="line"> <span class="attr">reflink</span>: <span class="regexp">/^!?\[(inside)\]\s*\[([^\]]*)\]/</span>,</span><br><span class="line"> <span class="attr">nolink</span>: <span class="regexp">/^!?\[((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\]/</span>,</span><br><span class="line"> <span class="attr">strong</span>: <span class="regexp">/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/</span>,</span><br><span class="line"> <span class="comment">// em: /^_([^\s_](?:[^_]|__)+?[^\s_])_\b|^\*((?:\*\*|[^*])+?)\*(?!\*)/,</span></span><br><span class="line"> <span class="attr">em</span>:<span class="regexp">/^\*((?:\*\*|[\s\S])+?)\*(?!\*)/</span>,</span><br><span class="line"> <span class="attr">code</span>: <span class="regexp">/^(`+)\s*([\s\S]*?[^`]?)\s*\1(?!`)/</span>,</span><br><span class="line"> <span class="attr">br</span>: <span class="regexp">/^ {2,}\n(?!\s*$)/</span>,</span><br><span class="line"> <span class="attr">del</span>: noop,</span><br><span class="line"> <span class="attr">text</span>: <span class="regexp">/^[\s\S]+?(?=[\\<!\[`*]|\b_| {2,}\n|$)/</span></span><br><span class="line">};</span><br></pre></td></tr></table></figure><p>然后再次 yarn start,发现公式出来了~</p><p>$$\sum_{i=0}^n i^2 = \frac{(n^2+n)(2n+1)}{6}$$</p>]]></content>
<summary type="html"><p>好久好久之前就有一个 issue 提出来要支持 <strong>MathJax</strong>,结果到现在我都没有实现,直到昨天看到有人又要这个,所以我觉得还是写写吧,毕竟不是太复杂的东西。</p>
<p>是这个 <a href="https://github.com/m</summary>
<category term="mathjax" scheme="https://ochukai.github.io/tags/mathjax/"/>
</entry>
<entry>
<title>Mathjax Test</title>
<link href="https://ochukai.github.io/mathjax-test/"/>
<id>https://ochukai.github.io/mathjax-test/</id>
<published>2019-04-22T06:41:27.000Z</published>
<updated>2023-07-16T03:46:17.423Z</updated>
<content type="html"><![CDATA[<blockquote><p><a href="https://math.meta.stackexchange.com/questions/5020/mathjax-basic-tutorial-and-quick-reference">MathJax basic tutorial and quick reference</a></p></blockquote><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">$$</span><br><span class="line">f(n) =</span><br><span class="line">\begin{cases}</span><br><span class="line">n/2, & \text{if $n$ is even} \\</span><br><span class="line">3n+1, & \text{if $n$ is odd}</span><br><span class="line">\end{cases}</span><br><span class="line">$$</span><br></pre></td></tr></table></figure><p>$$<br>f(n) =<br>\begin{cases}<br>n/2, & \text{if $n$ is even} \<br>3n+1, & \text{if $n$ is odd}<br>\end{cases}<br>$$</p><h2 id="行内公式"><a href="#行内公式" class="headerlink" title="行内公式"></a>行内公式</h2><p><code>$x_mu$</code> $x_mu$</p><p><code>$\sigma$</code> $\sigma$</p><p><code>$x_mu$</code> $x_mu$</p><p><code>$y=ax+b$</code> $y=ax+b$</p><h2 id="行间公式"><a href="#行间公式" class="headerlink" title="行间公式"></a>行间公式</h2><p><code>$$\cos 2\theta = \cos^2 \theta - \sin^2 \theta = 2 \cos^2 \theta$$</code><br>$$\cos 2\theta = \cos^2 \theta - \sin^2 \theta = 2 \cos^2 \theta$$</p><p><code>$$M(\beta^{\ast}(D),D) \subseteq C$$</code><br>$$M(\beta^{\ast}(D),D) \subseteq C$$</p><hr><p>$$ \sum_{i=0}^n i^2 = \frac{(n^2+n)(2n+1)}{6} $$</p><p>$$ x = \dfrac{-b \pm \sqrt{b^2 - 4ac}}{2a} $$</p><h2 id="自动编号"><a href="#自动编号" class="headerlink" title="自动编号"></a>自动编号</h2><p>$$<br>\begin{equation}<br>\sum_{i=0}^n F_i \cdot \phi (H, p_i) - \sum_{i=1}^n a_i \cdot ( \tilde{x_i}, \tilde{y_i}) + b_i \cdot ( \tilde{x_i}^2 , \tilde{y_i}^2 )<br>\end{equation}<br>$$</p><p>$$<br>\begin{equation}<br>\beta^*(D) = \mathop{argmin} \limits_{\beta} \lambda {||\beta||}^2 + \sum_{i=1}^n max(0, 1 - y_i f_{\beta}(x_i))<br>\end{equation}<br>$$</p>]]></content>
<summary type="html"><blockquote>
<p><a href="https://math.meta.stackexchange.com/questions/5020/mathjax-basic-tutorial-and-quick-reference">MathJax basic tutori</summary>
<category term="mathjax" scheme="https://ochukai.github.io/tags/mathjax/"/>
</entry>
<entry>
<title>🐷用 js 判断某元素进入视窗区域以及图片的懒加载~</title>
<link href="https://ochukai.github.io/js-is-in-sight/"/>
<id>https://ochukai.github.io/js-is-in-sight/</id>
<published>2019-04-18T01:43:00.000Z</published>
<updated>2023-07-16T03:46:17.423Z</updated>
<content type="html"><![CDATA[<p>一直很想写这个的,一直很想些 html 的某个元素滚动到视窗的判断,感觉还是很有用的。前段时间在写一个企业 IM,要写用户已读了某条信息的操作,如果加上这个进入视窗的判断,就会很准确的知道了用户看消息的过程,但是之前没有判断,只要用户打开这个聊天窗口,我就默认他把所有未读信息全读了,哪怕有四百条未读信息,看吧,那个人有超能力~</p><h2 id="getBoundingClientRect"><a href="#getBoundingClientRect" class="headerlink" title="getBoundingClientRect"></a>getBoundingClientRect</h2><p><a href="https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getBoundingClientRect">getBoundingClientRect</a> 这个方法可以获取元素的大小以及相对于视窗的位置,于是我们可以用。</p><p>拿我的博客里面的评论框来举例子,输出结果在下面:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">> $(<span class="string">'.comment_trigger'</span>)[0].getBoundingClientRect()</span><br><span class="line">> DOMRect {x: 179.5, y: 745, width: 664, height: 114, top: 745, …}</span><br><span class="line"> bottom: 859</span><br><span class="line"> height: 114</span><br><span class="line"> left: 179.5</span><br><span class="line"> right: 843.5</span><br><span class="line"> top: 745</span><br><span class="line"> width: 664</span><br><span class="line"> x: 179.5</span><br><span class="line"> y: 745</span><br><span class="line"> __proto__: DOMRect</span><br></pre></td></tr></table></figure><p><code>getBoundingClientRect</code> 返回了一个 <code>DOMRect</code> 这个东西,我也不知道是啥,但是里面的几个属性还是很容易懂的,其中,</p><ul><li>top 是元素距离窗口顶端的距离</li><li>bottom 是元素距离窗口底端的距离</li><li>left 是元素距离窗口左侧的距离</li><li>right 是元素距离窗口右侧的距离</li></ul><p>于是用这个方法来判断是否进入视窗的写法,大概像这样</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">isInSight</span>(<span class="params">el</span>) {</span><br><span class="line"> <span class="keyword">const</span> $el = <span class="keyword">typeof</span> el === <span class="string">'string'</span></span><br><span class="line"> ? <span class="variable language_">document</span>.<span class="title function_">querySelector</span>(el)</span><br><span class="line"> : el;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// left, top, right, bottom</span></span><br><span class="line"> <span class="keyword">const</span> rect = $el.<span class="title function_">getBoundingClientRect</span>();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> !(</span><br><span class="line"> rect.<span class="property">top</span> > <span class="variable language_">window</span>.<span class="property">innerHeight</span> <span class="comment">// top 不在视窗</span></span><br><span class="line"> || rect.<span class="property">bottom</span> < <span class="number">0</span> <span class="comment">// bottom 也不在</span></span><br><span class="line"> || rect.<span class="property">left</span> > <span class="variable language_">window</span>.<span class="property">innerWidth</span> <span class="comment">// 同理</span></span><br><span class="line"> || rect.<span class="property">right</span> < <span class="number">0</span></span><br><span class="line"> );</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>到这里我们可以判断页面上任意一个元素在不在当前的视窗了,前提是它静止不动的时候,要动起来的话,比如滚动的时候,我们就要添加一些事件来触发这个判断,然后再做一些操作。</p><h2 id="lazyload"><a href="#lazyload" class="headerlink" title="lazyload"></a>lazyload</h2><p>页面中所有的图片,我们滚动它的位置的时候再去加载它,可以提高页面的加载速度吧。</p><p>下面的 loadImg 是概念方法,具体实现怎么都可以咯~</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">window</span>.<span class="title function_">addEventListener</span>(<span class="string">"scroll"</span>, <span class="function">() =></span> {</span><br><span class="line"> <span class="variable language_">document</span>.<span class="title function_">querySelectorAll</span>(<span class="string">"img"</span>).<span class="title function_">forEach</span>(<span class="function"><span class="params">img</span> =></span> {</span><br><span class="line"> <span class="keyword">if</span> (<span class="title function_">isInSight</span>(img)) {</span><br><span class="line"> <span class="title function_">loadImg</span>(img);</span><br><span class="line"> }</span><br><span class="line"> }))</span><br><span class="line">});</span><br></pre></td></tr></table></figure><p>就像这样,滚动窗口的时候遇到图片就会加载了,但是效果可能不是那么好看,要处理一下的话,可以在进入页面的时候,把所有图片的 src 都暂存到 data-src 上面,然后给每个图片的 src 都设置同一个路径,比如’loading.png’, 这样就会好看很多了。</p><p>当然最重要的是,isInSight 方法已经实现了。</p>]]></content>
<summary type="html"><p>一直很想写这个的,一直很想些 html 的某个元素滚动到视窗的判断,感觉还是很有用的。前段时间在写一个企业 IM,要写用户已读了某条信息的操作,如果加上这个进入视窗的判断,就会很准确的知道了用户看消息的过程,但是之前没有判断,只要用户打开这个聊天窗口,我就默认他把所有未读信</summary>
<category term="js" scheme="https://ochukai.github.io/tags/js/"/>
<category term="lazyload" scheme="https://ochukai.github.io/tags/lazyload/"/>
<category term="inSight" scheme="https://ochukai.github.io/tags/insight/"/>
</entry>
<entry>
<title>我的第二个纹身 - 键盘 🎹</title>
<link href="https://ochukai.github.io/my-second-tattoo/"/>
<id>https://ochukai.github.io/my-second-tattoo/</id>
<published>2019-03-23T05:05:03.000Z</published>
<updated>2023-07-16T03:46:17.423Z</updated>
<content type="html"><![CDATA[<p>第二个纹身,这次是在左侧的肚子上,也是巨疼。</p><p>师傅问我为什么总是选肚子,我笑笑不说话,因为我也不知道~</p><p>这次看起来很简单的图案,耗时三个半小时,受罪俩小时。简直生不如死,但是好像我没叫出声~</p><blockquote><p>纹身师傅的手稿</p></blockquote><p><img src="/../images/tattoo-keyboard.jpg" alt="纹身师傅的手稿"></p><p>这次还是不放文完之后的图了,肚子太大,影响视觉效果。</p><p>持续健身中。。。。</p>]]></content>
<summary type="html"><p>第二个纹身,这次是在左侧的肚子上,也是巨疼。</p>
<p>师傅问我为什么总是选肚子,我笑笑不说话,因为我也不知道~</p>
<p>这次看起来很简单的图案,耗时三个半小时,受罪俩小时。简直生不如死,但是好像我没叫出声~</p>
<blockquote>
<p>纹身师傅的手稿</summary>
<category term="TATTOO" scheme="https://ochukai.github.io/tags/tattoo/"/>
<category term="纹身" scheme="https://ochukai.github.io/tags/%E7%BA%B9%E8%BA%AB/"/>
<category term="键盘" scheme="https://ochukai.github.io/tags/%E9%94%AE%E7%9B%98/"/>
</entry>
<entry>
<title>使用 SVN 的 branch 功能 😂</title>
<link href="https://ochukai.github.io/svn-branch/"/>
<id>https://ochukai.github.io/svn-branch/</id>
<published>2018-12-14T09:18:08.000Z</published>
<updated>2023-07-16T03:46:17.424Z</updated>
<content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>来到目前这个公司就一直再用 svn,工作之余可能会用 git 管理一些自己的项目。</p><p>目前这个项目写了一年,基本都是流水线似的开发,写完一个功能发布一个功能,一共两个人,就做在一起,沟通基本靠吼。</p><p>现在项目基本稳定了,但是要解决一些小 bug 之类的,解决之后当天直接就打包上线了,于是矛盾就出现了,功能稳定了,之前立下的 flag 要开始实现了,“发布之后这个就升级一下” 之类的话,现在要开始做了。</p><p>所以呢,如果在主分支上面升级新功能,当天解决的 bug 要打包就不愉快了,因为新代码把之前的代码搞乱了。</p><p>现在就需要分支了,其实早就需要分支了。</p><p>前几天我还在用 git 做分支,改 bug 的话, 就切换到 master,改完 bug svn 提交,打包。之后再 切回之前的 git 分支,但是 git 和 svn 的合作并不是特别融洽,麻烦。</p><p>所以今天学了一下 svn 的分支,真的,自从我听说 svn,就从来没用过他的分支功能,想来也不会太好用。</p><h2 id="开始学习-svn-的分支之前"><a href="#开始学习-svn-的分支之前" class="headerlink" title="开始学习 svn 的分支之前"></a>开始学习 svn 的分支之前</h2><p>这些知识是我看到 svn 的 branch 之后才知道的,但是要写在前面,我也不知道为啥,就写在这里吧。</p><h3 id="svn-的目录结构"><a href="#svn-的目录结构" class="headerlink" title="svn 的目录结构"></a>svn 的目录结构</h3><p>在 svn server 的管理界面创建新的 repo 的时候,会有两种选项</p><ol><li>empty repo</li><li>trunk,branches,tags</li></ol><p>第二种的意思是,创建一个 repo 文件夹,并且新建 trunk(主分支),branches(分支),tags(标签) 这三个文件夹。</p><p>第二种应该算是标准的 svn 项目结构,服务器使用 trunk 部署,平时开发在各自的分支上面做开发,做好了合并到 trunk。</p><h2 id="创建分支"><a href="#创建分支" class="headerlink" title="创建分支"></a>创建分支</h2><p>svn 创建分支的命令是 <strong>copy</strong>,是不是很神奇。</p><p>svn 创建分支的意思大概是,把这个文件夹复制到别的地方,你随便搞吧。因为是两个文件夹,所以肯定没关系。</p><p>所以要创建分支,可以直接执行, svn copy trunk/ branches/branch_name, svn 会原封不动的 把 trunk 文件夹的内容复制到 branches 下面的 branch_name 文件夹,真的一模一样。</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">ochukai@DESKTOP-IMK2E44 MINGW64 /e/dev/svn/***-pc</span><br><span class="line">$ <span class="built_in">ls</span></span><br><span class="line">branches tags trunk</span><br><span class="line"></span><br><span class="line">ochukai@DESKTOP-IMK2E44 MINGW64 /e/dev/svn/***-pc</span><br><span class="line">$ svn copy trunk/ branches/branch_name</span><br><span class="line">A branches/branch_name</span><br><span class="line"><span class="comment"># 提交</span></span><br><span class="line">ochukai@DESKTOP-IMK2E44 MINGW64 /e/dev/svn/***-pc</span><br><span class="line">$ svn commit -m <span class="string">"add branch_name"</span></span><br></pre></td></tr></table></figure><h2 id="切换分支"><a href="#切换分支" class="headerlink" title="切换分支"></a>切换分支</h2><p>切换分支就是打开文件夹, <strong>cd branches/branch_name</strong></p><h2 id="合并"><a href="#合并" class="headerlink" title="合并"></a>合并</h2><p>跟 git 差不多。</p><p><strong>svn merge ../branches/branch_name/</strong></p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">ochukai@DESKTOP-IMK2E44 MINGW64 /e/dev/svn/***-pc/trunk</span><br><span class="line">$ svn merge ../branches/branch_name/</span><br><span class="line"><span class="comment"># ...</span></span><br><span class="line"></span><br><span class="line">ochukai@DESKTOP-IMK2E44 MINGW64 /e/dev/svn/***-pc</span><br><span class="line">$ svn commit -m <span class="string">"merge"</span></span><br></pre></td></tr></table></figure><p>好了。</p>]]></content>
<summary type="html"><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>来到目前这个公司就一直再用 svn,工作之余可能会用 git 管理一些自己的项目。</p>
<p>目前这个项目写了一年,基本都是流水线似的开</summary>
<category term="svn" scheme="https://ochukai.github.io/tags/svn/"/>
<category term="branch" scheme="https://ochukai.github.io/tags/branch/"/>
</entry>
<entry>
<title>《心经》</title>
<link href="https://ochukai.github.io/the-hrdaya/"/>
<id>https://ochukai.github.io/the-hrdaya/</id>
<published>2018-12-14T06:52:16.000Z</published>
<updated>2023-07-16T03:46:17.424Z</updated>
<content type="html"><![CDATA[<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>其实我不是复制过来直接就发布了,最近我写代码之余,慢慢开始抄经了~</p><p>字虽不好看,但是在坚持,今年喜欢上了钢笔,买了几只网红笔,像贵妃,78G 之类便宜好用极具性价比的。</p><p>没想到,上一篇文章发布在去年九月,那个时候刚刚开始写现在的一个用 electron 包裹的前端小程序,也不算小,但是持续到今天十一月,好像很大了。</p><p>就是这个不大不小的程序,整整一年零三个月,我没有写过文章了,手生,脑也生,我是不是要组织一下代码,哦不,我要组织一下语言。</p><p>本年度第一篇文章就在这个凄凄惨惨的下午诞生了,这一篇更像是一篇总结,前一段事件我发现,我的网站访问不了了,可能是因为一年多没有提交代码,所以 git 把我的 page 服务停了吧,同样是上个月,我收到了阿里云给我的信息,ochukai.me 要续费了,这个域名已经三年了,但是因为去年一年的懒惰,这里变得极为萧条,ochuunn 这个主题的星星数量一直在 120 附近徘徊,看了十分心痛,可我又抽不出时间来完善升级一下。</p><p>说到抽不出时间,年初我两次阿里云的电话面试没过。因为他们问我业余时间做什么,我说我没有业余时间。</p><p>我想起,四个月前,我卸载了王者农药,真的是农药,七个赛季王者也玩腻了,加上越来越大的肚腩,于是狠心,卸载。顺便开始撸铁,睡觉时间也在慢慢变长,从日均 5.7,到现在 7.5 了,肩膀不怎么疼了,胳膊也粗了,腹肌正在酝酿中,已经可以摸到了,很开心,找到了人生的一大毒瘤,并把它消灭的成就感促使我开心。</p><p>我买了好多自动铅笔,买了一个二手画板,有事没事画一幅,很丑,但是我很善良,哈哈。</p><hr><h3 id="简介《般若经》"><a href="#简介《般若经》" class="headerlink" title="简介《般若经》"></a>简介《般若经》</h3><p>《般若经》共有九部: 《放光般若》、《光明般若》、《道行般若》、《胜天般若》、《胜天王般若》、《文殊问般若》、《金刚般若》、《大品般若》、《小品般若》</p><blockquote><p>玄奘版 《般若波罗蜜多心经》</p></blockquote><p><img src="/../assets/hrdaya.png" alt="《般若波罗蜜多心经》"></p><p>观自在菩萨,行深般若波罗蜜多时。照见五蕴皆空,度一切苦厄。</p><p>舍利子,色不异空,空不异色,色即是空,空即是色,受想行识,亦复如是。舍利子,是诸法空相,不生不灭,不垢不净,不增不减。</p><p>是故空中无色,无受想行识,无眼耳鼻舌身意,无色声香味触法,无眼界,乃至无意识界。无无明,亦无无明尽,乃至无老死,亦无老死尽。无苦集灭道,无智亦无得,以无所得故。菩提萨埵,依般若波罗蜜多故,心无挂碍,无挂碍故,无有恐怖,远离颠倒梦想,究竟涅槃。三世诸佛,依般若波罗蜜多故,得阿耨多罗三藐三菩提。</p><p>故知般若波罗蜜多,是大神咒,是大明咒,是无上咒,是无等等咒,能除一切苦,真实不虚。</p><p>故说般若波罗蜜多咒,即说咒曰:揭谛揭谛,波罗揭谛,波罗僧揭谛,菩提萨婆诃。</p><blockquote><p>鸠摩罗什版 《摩诃般若波罗蜜大明咒经》</p></blockquote><p>观世音菩萨,行深般若波罗蜜时,照见五阴空,度一切苦厄。</p><p>舍利弗,色空,故无恼坏相;受空,故无受相;想空,故无知相;行空,故无作相;识空,故无觉相。何以故?</p><p>舍利弗,非色异空,非空异色,色即是空,空即是色,受、想、行、识,亦如是。</p><p>舍利弗,是诸法空相,不生不灭,不垢不净,不增不减。是空法,非过去、非未来、非现在。</p><p>是故空中无色,无受、想、行、识,无眼、耳、鼻、舌、身、意,无色、声、香、味、触、法,无眼界,乃至无意识界;无无明,亦无无明尽;乃至无老死,亦无老死尽;无苦集灭道,无智亦无得,以无所得故。</p><p>菩萨依般若波罗蜜故,心无挂碍。无挂碍故,无有恐怖,离颠倒梦想苦恼,究竟涅盘。三世诸佛,依般若波罗蜜故。得阿耨多罗三藐三菩提。故知般若波罗蜜是大明咒、无上明咒、无等等明咒,能除一切苦,真实不虚。</p><p>故说般若波罗蜜咒。即说咒曰:“竭帝竭帝 波罗竭帝波 罗僧竭帝 菩提僧莎呵。”</p><blockquote><p>回向偈</p></blockquote><p>愿以此功德。庄严佛净土。</p><p>上报四重恩。下济三途苦。</p><p>若有见闻者。悉发菩提心。</p><p>尽此一报身。同生极乐国。</p>]]></content>
<summary type="html"><h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>其实我不是复制过来直接就发布了,最近我写代码之余,慢慢开始抄经了~</p>
<p>字虽不好看,但是在坚持,今年喜欢上了钢笔,买了几只网红笔,</summary>
<category term="佛" scheme="https://ochukai.github.io/tags/%E4%BD%9B/"/>
<category term="佛经" scheme="https://ochukai.github.io/tags/%E4%BD%9B%E7%BB%8F/"/>
</entry>
<entry>
<title>我的第一个纹身 - 鲸鱼 🐬</title>
<link href="https://ochukai.github.io/my-first-tattoo/"/>
<id>https://ochukai.github.io/my-first-tattoo/</id>
<published>2018-11-03T09:49:00.000Z</published>
<updated>2023-07-16T03:46:17.423Z</updated>
<content type="html"><![CDATA[<p>在我跟她预约的时候就说了: 头不能太尖,不能太圆,身子要立体,皮肤要有质感。</p><p>除此之外,没有别的要求了。</p><p>为什么我觉得这个纹身师牛逼呢,因为她给我画的图让我很满意~</p><blockquote><p>纹身师傅的手稿</p></blockquote><p><img src="/../images/tattoo-whale.jpg" alt="纹身师傅的手稿"></p><p>纹身之后的图片就不发了,身材不好。</p><p>纹在左侧肋骨胸下,巨疼,我是男的~</p>]]></content>
<summary type="html"><p>在我跟她预约的时候就说了: 头不能太尖,不能太圆,身子要立体,皮肤要有质感。</p>
<p>除此之外,没有别的要求了。</p>
<p>为什么我觉得这个纹身师牛逼呢,因为她给我画的图让我很满意~</p>
<blockquote>
<p>纹身师傅的手稿</p>
</blockq</summary>
<category term="TATTOO" scheme="https://ochukai.github.io/tags/tattoo/"/>
<category term="纹身" scheme="https://ochukai.github.io/tags/%E7%BA%B9%E8%BA%AB/"/>
<category term="鲸鱼" scheme="https://ochukai.github.io/tags/%E9%B2%B8%E9%B1%BC/"/>
</entry>
<entry>
<title>SVN 的备份与还原</title>
<link href="https://ochukai.github.io/svn-backup-and-restore/"/>
<id>https://ochukai.github.io/svn-backup-and-restore/</id>
<published>2017-09-06T03:09:56.000Z</published>
<updated>2023-07-16T03:46:17.424Z</updated>
<content type="html"><![CDATA[<p>其实很早之前就做了这个,但是最近公司要搬家所以又重新整理了一下 准备拿出来用上的,不过要用的那一天内网突然断了,所以也没有正式用,但是测试表明,十几个 svn 库,总体积三个多 g 备份的时候,只需要五分钟,超级快,保存了所有的提交记录。</p><figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><span class="line">@<span class="built_in">echo</span> off</span><br><span class="line"><span class="built_in">title</span> SVN Backup by oli</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">:: ---------------------------------------</span><br><span class="line">:: ---------------------------------------</span><br><span class="line">:: ---------------------------------------</span><br><span class="line"></span><br><span class="line"><span class="built_in">set</span> SVN_HOME="C:\Program Files\VisualSVN Server"</span><br><span class="line">:: 设置根目录</span><br><span class="line"><span class="built_in">set</span> SVN_ROOT=C:\Repositories</span><br><span class="line">:: 设置要备份到的位置</span><br><span class="line"><span class="built_in">set</span> SVN_BACKUP_ROOT=C:\Backup</span><br><span class="line"></span><br><span class="line"><span class="built_in">set</span> TIME_DIR=<span class="variable">%date:~,4%</span><span class="variable">%date:~5,2%</span><span class="variable">%date:~8,2%</span>_<span class="variable">%time:~,2%</span><span class="variable">%time:~3,2%</span><span class="variable">%time:~6,2%</span><span class="variable">%time:~9,2%</span></span><br><span class="line"><span class="built_in">set</span> BACKUP_DIRECTORY=<span class="variable">%SVN_BACKUP_ROOT%</span>\<span class="variable">%TIME_DIR%</span></span><br><span class="line"><span class="built_in">set</span> LOG=<span class="variable">%BACKUP_DIRECTORY%</span>\backup.log</span><br><span class="line"></span><br><span class="line">:: ---------------------------------------</span><br><span class="line">:: ---------------------------------------</span><br><span class="line">:: ---------------------------------------</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> <span class="keyword">not</span> <span class="keyword">exist</span> <span class="variable">%SVN_HOME%</span> <span class="keyword">goto</span> error</span><br><span class="line"></span><br><span class="line"><span class="keyword">goto</span> <span class="built_in">start</span></span><br><span class="line"></span><br><span class="line">:<span class="built_in">start</span></span><br><span class="line"><span class="keyword">for</span> /r <span class="variable">%SVN_BACKUP_ROOT%</span> <span class="variable">%%I</span> <span class="keyword">in</span> (backup.log) <span class="keyword">do</span> (</span><br><span class="line"> <span class="keyword">if</span> <span class="variable">%%~</span>zI <span class="keyword">GEQ</span> <span class="number">1048576</span> <span class="built_in">ren</span> <span class="variable">%LOG%</span> backup_<span class="variable">%TIME%</span>.log</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="built_in">mkdir</span> <span class="variable">%BACKUP_DIRECTORY%</span></span><br><span class="line">@<span class="built_in">echo</span> [info] create new directory: <span class="variable">%BACKUP_DIRECTORY%</span></span><br><span class="line"></span><br><span class="line">@<span class="built_in">echo</span> [info] <span class="variable">%date:~,10%</span> <span class="variable">%time:~,2%</span>:<span class="variable">%time:~3,2%</span>:<span class="variable">%time:~6,2%</span> create backup category: <span class="variable">%BACKUP_DIRECTORY%</span> >><span class="variable">%LOG%</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> /d <span class="variable">%%i</span> <span class="keyword">in</span> (<span class="variable">%SVN_ROOT%</span>\*) <span class="keyword">do</span> (</span><br><span class="line"> @<span class="built_in">echo</span> [info] backup <span class="variable">%%~</span>ni >><span class="variable">%LOG%</span></span><br><span class="line"> @<span class="built_in">echo</span> [info] backup <span class="variable">%%~</span>ni</span><br><span class="line"></span><br><span class="line"> :: --incremental</span><br><span class="line"> <span class="variable">%SVN_HOME%</span>\bin\svnadmin dump <span class="variable">%SVN_ROOT%</span>\<span class="variable">%%~</span>ni > <span class="variable">%BACKUP_DIRECTORY%</span>\<span class="variable">%%~</span>ni.dmp <span class="number">2</span>>><span class="variable">%LOG%</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">@<span class="built_in">echo</span> [info] <span class="variable">%date:~,10%</span> <span class="variable">%time:~,2%</span>:<span class="variable">%time:~3,2%</span>:<span class="variable">%time:~6,2%</span> finish: <span class="variable">%errorlevel%</span></span><br><span class="line">@<span class="built_in">echo</span> [info] <span class="variable">%date:~,10%</span> <span class="variable">%time:~,2%</span>:<span class="variable">%time:~3,2%</span>:<span class="variable">%time:~6,2%</span> finish: <span class="variable">%errorlevel%</span> >><span class="variable">%LOG%</span></span><br><span class="line"></span><br><span class="line">:error</span><br><span class="line"><span class="built_in">echo</span> [error] <span class="variable">%date:~,10%</span> <span class="variable">%time:~,2%</span>:<span class="variable">%time:~3,2%</span>:<span class="variable">%time:~6,2%</span> directory <span class="keyword">not</span> <span class="keyword">exist</span>,please check: <span class="variable">%SVN_HOME%</span>>><span class="variable">%LOG%</span></span><br><span class="line"><span class="keyword">goto</span> end</span><br><span class="line"></span><br><span class="line">:end</span><br><span class="line">@<span class="built_in">echo</span>. >><span class="variable">%LOG%</span></span><br><span class="line">:: <span class="keyword">exit</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">PAUSE</span></span><br></pre></td></tr></table></figure><p>下面这一段是还原,就是把备份好的 dmp 文件,还原成文件夹。</p><p>还原的时候要根据自己是不是全新还原来考虑是否注释掉代码中的那一行~</p><figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">echo</span> off</span><br><span class="line"></span><br><span class="line"><span class="built_in">title</span> SVN Backup by oli</span><br><span class="line"></span><br><span class="line">:: ---------------------------------------</span><br><span class="line">:: ---------------------------------------</span><br><span class="line">:: ---------------------------------------</span><br><span class="line"></span><br><span class="line"><span class="built_in">set</span> SVN_HOME="C:\Program Files\VisualSVN Server"</span><br><span class="line"></span><br><span class="line">:: 要还原到的目录</span><br><span class="line"><span class="built_in">set</span> SVN_ROOT=C:\testLoad</span><br><span class="line"></span><br><span class="line">:: 之前备份的目录</span><br><span class="line"><span class="built_in">set</span> SVN_BACKUP_DIR=C:\Backup\<span class="number">20170831</span>_11282822</span><br><span class="line"></span><br><span class="line">:: ---------------------------------------</span><br><span class="line">:: ---------------------------------------</span><br><span class="line">:: ---------------------------------------</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> <span class="keyword">not</span> <span class="keyword">exist</span> <span class="variable">%SVN_HOME%</span> <span class="keyword">goto</span> error</span><br><span class="line"></span><br><span class="line"><span class="keyword">goto</span> <span class="built_in">start</span></span><br><span class="line"></span><br><span class="line">:<span class="built_in">start</span></span><br><span class="line"><span class="keyword">for</span> <span class="variable">%%i</span> <span class="keyword">in</span> (<span class="variable">%SVN_BACKUP_DIR%</span>\*.dmp) <span class="keyword">do</span> (</span><br><span class="line"> @<span class="built_in">echo</span> [info] backup <span class="variable">%%~</span>ni >><span class="variable">%LOG%</span></span><br><span class="line"> @<span class="built_in">echo</span> [info] backup <span class="variable">%%~</span>ni</span><br><span class="line"></span><br><span class="line"> :: 目录不存在就新建一个否则会报错的,</span><br><span class="line"> :: 如果全新还原这个目录必须新建,否则可以注释这一行</span><br><span class="line"> <span class="variable">%SVN_HOME%</span>\bin\svnadmin create <span class="variable">%SVN_ROOT%</span>\<span class="variable">%%~</span>ni</span><br><span class="line"> :: --incremental</span><br><span class="line"> <span class="variable">%SVN_HOME%</span>\bin\svnadmin load <span class="variable">%SVN_ROOT%</span>\<span class="variable">%%~</span>ni < <span class="variable">%SVN_BACKUP_DIR%</span>\<span class="variable">%%~</span>ni.dmp</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">@<span class="built_in">echo</span> [info] <span class="variable">%date:~,10%</span> <span class="variable">%time:~,2%</span>:<span class="variable">%time:~3,2%</span>:<span class="variable">%time:~6,2%</span> finish: <span class="variable">%errorlevel%</span></span><br><span class="line">@<span class="built_in">echo</span> [info] <span class="variable">%date:~,10%</span> <span class="variable">%time:~,2%</span>:<span class="variable">%time:~3,2%</span>:<span class="variable">%time:~6,2%</span> finish: <span class="variable">%errorlevel%</span> >><span class="variable">%LOG%</span></span><br><span class="line"></span><br><span class="line">:error</span><br><span class="line"><span class="built_in">echo</span> [error] <span class="variable">%date:~,10%</span> <span class="variable">%time:~,2%</span>:<span class="variable">%time:~3,2%</span>:<span class="variable">%time:~6,2%</span> SVNADMIN <span class="keyword">not</span> <span class="keyword">exist</span>, lease check: <span class="variable">%SVN_HOME%</span>>><span class="variable">%LOG%</span></span><br><span class="line"><span class="keyword">goto</span> end</span><br><span class="line"></span><br><span class="line">:end</span><br><span class="line">@<span class="built_in">echo</span>. >><span class="variable">%LOG%</span></span><br><span class="line">:: <span class="keyword">exit</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">PAUSE</span></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><p>其实很早之前就做了这个,但是最近公司要搬家所以又重新整理了一下 准备拿出来用上的,不过要用的那一天内网突然断了,所以也没有正式用,但是测试表明,十几个 svn 库,总体积三个多 g 备份的时候,只需要五分钟,超级快,保存了所有的提交记录。</p>
<figure class</summary>
<category term="svn" scheme="https://ochukai.github.io/tags/svn/"/>
<category term="svn backup" scheme="https://ochukai.github.io/tags/svn-backup/"/>
<category term="svn 备份" scheme="https://ochukai.github.io/tags/svn-%E5%A4%87%E4%BB%BD/"/>
<category term="svn 还原" scheme="https://ochukai.github.io/tags/svn-%E8%BF%98%E5%8E%9F/"/>
</entry>
<entry>
<title>flex shrink 的用处</title>
<link href="https://ochukai.github.io/flex-shrink/"/>
<id>https://ochukai.github.io/flex-shrink/</id>
<published>2017-08-08T07:38:17.000Z</published>
<updated>2023-07-16T03:46:17.422Z</updated>
<content type="html"><![CDATA[<p>flex grow 和 shrink 这两兄弟我经常遇见,不过目前为止,grow 还没有帮过我什么忙, shrink 很不错,帮过我几次了。</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">flex-shrink</span>: <span class="number">0</span></span><br></pre></td></tr></table></figure><p>每当别的元素位置不够了,要来挤压我的空间时, flex-shrink 就会帮我把别的元素挡在门外,是一个很有原则的人。</p><blockquote><p>flex-shrink 定义收缩比率。不允许负值</p></blockquote>]]></content>
<summary type="html"><p>flex grow 和 shrink 这两兄弟我经常遇见,不过目前为止,grow 还没有帮过我什么忙, shrink 很不错,帮过我几次了。</p>
<figure class="highlight css"><table><tr><td class="gutter"><p</summary>
<category term="flex" scheme="https://ochukai.github.io/tags/flex/"/>
<category term="flex shrink" scheme="https://ochukai.github.io/tags/flex-shrink/"/>
</entry>
<entry>
<title>Django 项目部署在 nginx + uwsgi</title>
<link href="https://ochukai.github.io/nginx-uwsgi-django/"/>
<id>https://ochukai.github.io/nginx-uwsgi-django/</id>
<published>2017-06-27T06:28:31.000Z</published>
<updated>2023-07-16T03:46:17.423Z</updated>
<content type="html"><![CDATA[<p>好久不写博客了,最近一直在忙一个私活,一个问卷类的项目,用 django 写的,说实话,之前除了在公司厘米用,都没有用过 python,还好我有一些好同事,有问题可以直接问,方便了很多。</p><p>为了避免长时间不写文章的尴尬,我急匆匆的新键了一个 md,开始写。</p><p>一般来说,本地运行 django 项目是很简单,</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python manage.py runserver</span><br></pre></td></tr></table></figure><h2 id="UWSGI"><a href="#UWSGI" class="headerlink" title="UWSGI"></a>UWSGI</h2><p>总感觉这个单词全部大写的话,很别扭,使用 uwsgi 启动项目的话也不是太难,</p><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># docon.ini</span></span><br><span class="line"><span class="comment"># uwsgi abc.ini</span></span><br><span class="line"><span class="comment"># uwsgi --reload /tmp/***.pid</span></span><br><span class="line"><span class="comment"># uwsgi --stop /tmp/***.pid</span></span><br><span class="line"></span><br><span class="line"><span class="section">[uwsgi]</span></span><br><span class="line"><span class="attr">chdir</span>=/home/docon</span><br><span class="line"><span class="attr">module</span>=docon.wsgi:application</span><br><span class="line"><span class="attr">master</span>=<span class="literal">True</span></span><br><span class="line"><span class="attr">processes</span>=<span class="number">2</span></span><br><span class="line"><span class="attr">threads</span>=<span class="number">2</span></span><br><span class="line"><span class="attr">socket</span>=:<span class="number">8000</span></span><br><span class="line"><span class="comment"># http=:80</span></span><br><span class="line"><span class="attr">daemonize</span>=/var/log/uwsgi-docon.log</span><br><span class="line"><span class="attr">pidfile</span>=/tmp/docon.pid</span><br><span class="line"><span class="attr">vacuum</span>=<span class="literal">True</span></span><br></pre></td></tr></table></figure><p>有一点要注意的就是, 如果单独使用 uwsgi,需要写 <strong>http=:80</strong>, 如果配合 nginx 的话,就改成 <strong>socket=:8000</strong>, 8000 随便写。</p><h2 id="NGINX"><a href="#NGINX" class="headerlink" title="NGINX"></a>NGINX</h2><p>一般初装 ubuntu 的 nginx 之后,有一个默认的配置,在 <strong>/etc/nginx/sites-enabled/default</strong> 这个位置,需要修改成自己项目的配置。</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vi /etc/nginx/sites-enabled/default</span><br></pre></td></tr></table></figure><p>然后修改成自己的配置</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">server {</span><br><span class="line"> listen 80;</span><br><span class="line"> server_name ***.com;</span><br><span class="line"> charset utf-8;</span><br><span class="line"></span><br><span class="line"> client_max_body_size 75M;</span><br><span class="line"></span><br><span class="line"> location / {</span><br><span class="line"> include uwsgi_params;</span><br><span class="line"> uwsgi_pass localhost:8000;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> location /static/ {</span><br><span class="line"> alias /var/www/html/docon/static/;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>重启 nginx</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/etc/init.d/nginx restart </span><br></pre></td></tr></table></figure><p>哦,对了,在启动之前,要把静态文件,放到上面配置的 <strong>/var/www/html/docon/static</strong> 中去,这个路径是自己配置的,随便写吧,首先要在项目的 setting.py 里面设置 <strong>STATIC_ROOT</strong>, </p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">STATIC_ROOT = /var/www/html/docon/static</span><br></pre></td></tr></table></figure><p>然后在执行下面的命令,把所有的静态文件转移过去。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python manage.py collectstatic</span><br></pre></td></tr></table></figure><p>如果启动的过程中报错了, 查看占用的端口, 然后 kill 就好了。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">netstat -ntpl</span><br><span class="line">kill -9 ***</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><p>好久不写博客了,最近一直在忙一个私活,一个问卷类的项目,用 django 写的,说实话,之前除了在公司厘米用,都没有用过 python,还好我有一些好同事,有问题可以直接问,方便了很多。</p>
<p>为了避免长时间不写文章的尴尬,我急匆匆的新键了一个 md,开始写。</p</summary>
<category term="django" scheme="https://ochukai.github.io/tags/django/"/>
<category term="nginx" scheme="https://ochukai.github.io/tags/nginx/"/>
<category term="uwsgi" scheme="https://ochukai.github.io/tags/uwsgi/"/>
</entry>
<entry>
<title>直播写代码要去那个平台呢?</title>
<link href="https://ochukai.github.io/live-code/"/>
<id>https://ochukai.github.io/live-code/</id>
<published>2017-06-01T10:51:49.000Z</published>
<updated>2023-07-16T03:46:17.423Z</updated>
<content type="html"><![CDATA[<p>现在我在 <a href="http://www.huya.com/ochukai">虎牙-代码痴汉umi</a>, 有谁推荐新的直播平台吗 ?</p>]]></content>
<summary type="html"><p>现在我在 <a href="http://www.huya.com/ochukai">虎牙-代码痴汉umi</a>, 有谁推荐新的直播平台吗 ?</p>
</summary>
<category term="直播" scheme="https://ochukai.github.io/tags/%E7%9B%B4%E6%92%AD/"/>
<category term="直播写代码" scheme="https://ochukai.github.io/tags/%E7%9B%B4%E6%92%AD%E5%86%99%E4%BB%A3%E7%A0%81/"/>
</entry>
<entry>
<title>给 Git Bash 设置好看的配色~ 😜</title>
<link href="https://ochukai.github.io/beautiful-color-git-bash/"/>
<id>https://ochukai.github.io/beautiful-color-git-bash/</id>
<published>2017-05-31T22:06:06.000Z</published>
<updated>2023-07-16T03:46:17.421Z</updated>
<content type="html"><![CDATA[<p>window 上面的命令行一直都非常丑陋 (看我用词多么强烈)~</p><p>今天上午终于因为看 Git Bash 配色而双眼变得模糊了, 于是上网搜了一下有没有结局方案, 然后就发现了这个 <a href="https://github.com/mavnn/mintty-colors-solarized">github/mintty-colors-solarized</a>, 但这个项目是好几年前的了, 我还是怀着试试看的态度尝试了一下.</p><p>我发现了, 干程序员别的可能不行, 但是尝试的能力还是有的, 经常为了找一个新的框架, 或者要写一个组件而去把所有相关的项目全看一边, 然后才发现不行~</p><p>但是今天老天并没有调戏我, 先说一下修改的过程吧~ 在 Git Bash 里面输入,</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cd ~</span><br><span class="line">vi .minttyrc</span><br></pre></td></tr></table></figure><p>开始编辑它的配置文件, 不妨输入这些东西, 这些配色就是我从上面的项目里面找来的~</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">...</span><br><span class="line">Font=Consolas</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">后面是颜色的配置</span></span><br><span class="line">ForegroundColour=131,148,150</span><br><span class="line">BackgroundColour=0,43,54</span><br><span class="line">CursorColour=220,50,47</span><br><span class="line"></span><br><span class="line">Black=7,54,66</span><br><span class="line">BoldBlack=0,43,54</span><br><span class="line">Red=220,50,47</span><br><span class="line">BoldRed=203,75,22</span><br><span class="line">Green=133,153,0</span><br><span class="line">BoldGreen=88,110,117</span><br><span class="line">Yellow=181,137,0</span><br><span class="line">BoldYellow=101,123,131</span><br><span class="line">Blue=38,139,210</span><br><span class="line">BoldBlue=131,148,150</span><br><span class="line">Magenta=211,54,130</span><br><span class="line">BoldMagenta=108,113,196</span><br><span class="line">Cyan=42,161,152</span><br><span class="line">BoldCyan=147,161,161</span><br><span class="line">White=238,232,213</span><br><span class="line">BoldWhite=253,246,227</span><br></pre></td></tr></table></figure><p>保存之后, 重启一下, 效果就像下面这样了~</p><p><img src="/images/terminal.png" alt="非选中状态"></p><p><img src="/images/terminal-selected.png" alt="选中状态"></p>]]></content>
<summary type="html"><p>window 上面的命令行一直都非常丑陋 (看我用词多么强烈)~</p>
<p>今天上午终于因为看 Git Bash 配色而双眼变得模糊了, 于是上网搜了一下有没有结局方案, 然后就发现了这个 <a href="https://github.com/mavnn/mintty</summary>
<category term="git bash" scheme="https://ochukai.github.io/tags/git-bash/"/>
<category term="terminal" scheme="https://ochukai.github.io/tags/terminal/"/>
<category term="配色" scheme="https://ochukai.github.io/tags/%E9%85%8D%E8%89%B2/"/>
</entry>
<entry>
<title>写了一个 Vue 的图片预览插件~😜</title>
<link href="https://ochukai.github.io/vue-image-preview/"/>
<id>https://ochukai.github.io/vue-image-preview/</id>
<published>2017-05-31T22:01:01.000Z</published>
<updated>2023-07-16T03:46:17.425Z</updated>
<content type="html"><![CDATA[<p>最近的项目里面需要一个图片点击放大预览的插件~ 项目是 vue 写的 SPA ~</p><p>找了好久,没有现成的,有一个,但是写的我很不喜欢,需要手动传入图片地址,宽度和高度,都这样了,还写什么程序~</p><p>然后我打算自己写一个~</p><h2 id="思路"><a href="#思路" class="headerlink" title="思路"></a>思路</h2><p>基本思路的话,就是点击图片的时候,产生一个遮罩层(或者遮罩层本来就有),然后在遮罩层添加一个图片,居中什么的样式到时随便了。点击事件很简单, <code>@click</code> 就好了,点击图片之后可以获取到图片的路径,因为点击的是已经显示出来的图片,所以当前图片的 meta 信息肯定包含了该图片的长和宽。</p><p>生成一个遮罩层也很简单,然后根据图片的长宽和屏幕的长宽(或者浏览窗口的大小)可以计算图片的居中位置。</p><p>然后添加到 body 上面就好了,但是添加的话,因为 vue 有自己的生命周期,<code>document.body.appendChild()</code> 的话事件都不能用 vue 的了,于是如果 **append 一个 vue 的插件到 dom **算是第一个问题。</p><p>简单的思路就这样,只要实现了动态添加 vue 组件到 body,那么这个插件就可以实现了。</p><h2 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h2><p>我先去看了一个 element-ui 的代码,好复杂,有一个很大的 mixin, 看来看去没明白,后来我想起之前看到的那个图片预览的插件,<a href="https://github.com/xiecg/vue-fancybox">github/vue-fancybox</a>,顺便帮作者宣传一下吧,虽然不符合我的价值观~ </p><p>这个插件有一个插入的操作,大概是这么写的,</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title class_">FancyBoxConstructor</span> = <span class="title class_">Vue</span>.<span class="title function_">extend</span>(fancyBox);</span><br><span class="line"><span class="keyword">let</span> instance = <span class="keyword">new</span> <span class="title class_">FancyBoxConstructor</span>({</span><br><span class="line"> <span class="attr">el</span>: <span class="variable language_">document</span>.<span class="title function_">createElement</span>(<span class="string">'div'</span>)</span><br><span class="line">});</span><br><span class="line"></span><br><span class="line"><span class="variable language_">document</span>.<span class="property">body</span>.<span class="title function_">appendChild</span>(instance.<span class="property">$el</span>);</span><br></pre></td></tr></table></figure><p>他还写了好多别的代码,但是主要逻辑应该是这个,首先初始化组件之后,再 append 到 body,不错。</p><p>然后我就借用了,</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title class_">ImagePreviewConstructor</span> = <span class="title class_">Vue</span>.<span class="title function_">extend</span>(<span class="title class_">ImagePreview</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> (el) => {</span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> instance = <span class="keyword">new</span> <span class="title class_">ImagePreviewConstructor</span>({</span><br><span class="line"> <span class="attr">el</span>: <span class="variable language_">document</span>.<span class="title function_">createElement</span>(<span class="string">'div'</span>),</span><br><span class="line"> <span class="attr">data</span>: {</span><br><span class="line"> <span class="attr">img</span>: el,</span><br><span class="line"> <span class="attr">imgSrc</span>: el.<span class="property">src</span></span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line"> <span class="variable language_">document</span>.<span class="property">body</span>.<span class="title function_">appendChild</span>(instance.<span class="property">$el</span>);</span><br><span class="line"></span><br><span class="line">};</span><br></pre></td></tr></table></figure><p>初始化的时候顺便传入 <strong>props</strong>, 这个文件算是组件的入口文件了,调用这个组件的方式是这样的:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">handleContentClick</span>(<span class="params">e</span>) {</span><br><span class="line"> <span class="keyword">const</span> el = e.<span class="property">target</span>;</span><br><span class="line"> <span class="keyword">if</span> (el.<span class="property">localName</span> === <span class="string">'img'</span>) {</span><br><span class="line"> e.<span class="title function_">preventDefault</span>();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> imageSrc = el.<span class="property">src</span>;</span><br><span class="line"> <span class="keyword">if</span> (imageSrc) {</span><br><span class="line"> <span class="title function_">showImagePreview</span>(el);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>这样的话,组件便可以开始了,或者说已经结束了,因为只要在 template 里面写个 div, 再写个 img 就好了, 剩下的就是样式问题:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">template</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">transition</span> <span class="attr">name</span>=<span class="string">"image-fade"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"image-preview__wrapper"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">style</span>=<span class="string">"z-index: 2003;"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">ref</span>=<span class="string">"wrapper"</span></span></span><br><span class="line"><span class="tag"> @<span class="attr">click.self</span>=<span class="string">"handleClick"</span></span></span><br><span class="line"><span class="tag"> @<span class="attr">mousewheel.stop</span>=<span class="string">"handleMouseWheel"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">v-if</span>=<span class="string">"imgSrc"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">:src</span>=<span class="string">"imgSrc"</span>/></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"toolbar"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-button</span> <span class="attr">icon</span>=<span class="string">"minus"</span> @<span class="attr">click</span>=<span class="string">"handleZoomIn"</span>></span>缩小<span class="tag"></<span class="name">el-button</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-button</span> <span class="attr">icon</span>=<span class="string">"plus"</span> @<span class="attr">click</span>=<span class="string">"handleZoomOut"</span>></span>放大<span class="tag"></<span class="name">el-button</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">el-button</span> <span class="attr">icon</span>=<span class="string">"close"</span> @<span class="attr">click</span>=<span class="string">"handleClose"</span>></span>关闭<span class="tag"></<span class="name">el-button</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><span class="line"> <span class="tag"></<span class="name">transition</span>></span></span><br><span class="line"><span class="tag"></<span class="name">template</span>></span></span><br></pre></td></tr></table></figure><p>这里我加了一个 <code>transition</code> 标签,是 vue 里面很方便写出入场动画的标签,文档在这里<a href="http://cn.vuejs.org/v2/guide/transitions.html">vue/transition</a>, 里面就是 div 和 img,或许这样的结构有点简陋,但是能用啊,而且公司不给太多时间(咦,这个心态不对呀~)</p><p>组件 mounted 之后,要初始化图片的位置和事件,</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">mounted</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="variable language_">document</span>.<span class="title function_">querySelector</span>(<span class="string">'html'</span>).<span class="property">style</span>.<span class="property">overflow</span> = <span class="string">'hidden'</span>;</span><br><span class="line"></span><br><span class="line"> <span class="title class_">Vue</span>.<span class="title function_">nextTick</span>(<span class="function">() =></span> {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="title function_">initImagePosition</span>();</span><br><span class="line"> <span class="variable language_">this</span>.<span class="title function_">initHammer</span>();</span><br><span class="line"> });</span><br><span class="line">},</span><br></pre></td></tr></table></figure><p>哦对了,图片的手势处理,拖拽我用的 hammerjs 来做的。</p><p>然后就是 <strong>handleClick</strong>,点击图片之后的操作了,加了 <code>.self</code> 是为了事件只在 div 标签触发,用过 vue 的人都知道,好用~</p><p>效果是这样的~</p><p><img src="/images/vue-image-preview.jpg"></p>]]></content>
<summary type="html"><p>最近的项目里面需要一个图片点击放大预览的插件~ 项目是 vue 写的 SPA ~</p>
<p>找了好久,没有现成的,有一个,但是写的我很不喜欢,需要手动传入图片地址,宽度和高度,都这样了,还写什么程序~</p>
<p>然后我打算自己写一个~</p>
<h2 id="思路"</summary>
<category term="vue" scheme="https://ochukai.github.io/tags/vue/"/>
<category term="image-preview" scheme="https://ochukai.github.io/tags/image-preview/"/>
</entry>
<entry>
<title>VUE 总结一下~</title>
<link href="https://ochukai.github.io/vue-summary/"/>
<id>https://ochukai.github.io/vue-summary/</id>
<published>2017-05-24T03:27:55.000Z</published>
<updated>2023-07-16T03:46:17.425Z</updated>
<content type="html"><![CDATA[<p>最近开始接触 vue, 写了一个算是前端小论坛的公司内部项目, 算是一个知识库, 可添加一些常见的问题供别人查阅~</p><p>现在做个总结吧, 项目写完一个多星期, 现在想想差不多都忘记了~ 真是老了~</p><h2 id="生命周期"><a href="#生命周期" class="headerlink" title="生命周期"></a>生命周期</h2><p><img src="/images/vue-lifecycle.png"></p><p>其中 created 和 mounted 的顺序要确定好~ 比较重要的就像下面这三个吧, 其他的像是 <code>updated</code>, <code>beforeUpdate</code> 我几乎没有用过, 暂时不说~ </p><h3 id="created"><a href="#created" class="headerlink" title="created"></a>created</h3><p>实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。</p><h3 id="mounted"><a href="#mounted" class="headerlink" title="mounted"></a>mounted</h3><p>el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。<br>这个时候可以获取到 template 里面的标签元素了, 如果要修改大小样式之类的在这里面写~</p><h3 id="destroyed"><a href="#destroyed" class="headerlink" title="destroyed"></a>destroyed</h3><p>Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。 该钩子在服务器端渲染期间不被调用。</p><h2 id="动画"><a href="#动画" class="headerlink" title="动画"></a>动画</h2><p>使用过 vue 的 transition 标签之后最大的感慨便是, 做动画比 react 简单好多啊, 可能是我之前用 react 并没有写过动画的缘故吧, 但不可否认 vue 的动画很简单~</p><p>我之前写的一个小组件</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">template</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">transition</span> <span class="attr">name</span>=<span class="string">"back-top-fade"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">v-if</span>=<span class="string">"show"</span> <span class="attr">class</span>=<span class="string">"back-to-top hidden-xs"</span> @<span class="attr">click</span>=<span class="string">"handleBackTopClick"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">i</span> <span class="attr">class</span>=<span class="string">"el-icon-caret-top"</span>></span><span class="tag"></<span class="name">i</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">transition</span>></span></span><br><span class="line"><span class="tag"></<span class="name">template</span>></span></span><br></pre></td></tr></table></figure><p>这是一个简单的返回顶部的按钮, 当页面滚动到 一定距离的时候 <strong>show</strong> 变为 true, (对了, 为什么我的网址没有返回顶部的按钮呢~ 打开控制台就知道了~)</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">handleScroll</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">let</span> scrollTop = <span class="title function_">getScrollTop</span>();</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">show</span> = scrollTop > <span class="number">400</span>;</span><br><span class="line">},</span><br></pre></td></tr></table></figure><p>transition 下面的元素通过 <strong>v-if</strong> <strong>v-show</strong> 来控制隐藏和消失~ 然后会有几个状态类~</p><ol><li><strong>v-enter</strong>: 定义进入过渡的开始状态。在元素被插入时生效,在下一个帧移除。</li><li><strong>v-enter-active</strong>: 定义进入过渡的结束状态。在元素被插入时生效,在 transition/animation 完成之后移除。</li><li><strong>v-leave</strong>: 定义离开过渡的开始状态。在离开过渡被触发时生效,在下一个帧移除。</li><li><strong>v-leave-active</strong>: 定义离开过渡的结束状态。在离开过渡被触发时生效,在 transition/animation 完成之后移除。</li></ol><p>我只写了一个样式, 这样的话 按钮进出场的效果都是一样的~</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.back-top-fade-enter</span>,</span><br><span class="line"><span class="selector-class">.back-top-fade-leave-active</span> {</span><br><span class="line"> <span class="attribute">transform</span>: <span class="built_in">translateY</span>(-<span class="number">30px</span>);</span><br><span class="line"> <span class="attribute">opacity</span>: <span class="number">0</span></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>普通的 @click 事件</li><li>@click.self 这样很有用, 只是点击自己的时候有用</li><li>@click.stop 阻止单击事件冒泡</li><li>@click.prevent 阻止默认行为</li></ul><h2 id="Vue-Router"><a href="#Vue-Router" class="headerlink" title="Vue Router"></a>Vue Router</h2><p><strong>beforeRouteUpdate</strong> 这个方法很好用</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">beforeRouteEnter (to, <span class="keyword">from</span>, next) {</span><br><span class="line"> <span class="comment">// 在渲染该组件的对应路由被 confirm 前调用</span></span><br><span class="line"> <span class="comment">// 不!能!获取组件实例 `this`</span></span><br><span class="line"> <span class="comment">// 因为当钩子执行前,组件实例还没被创建</span></span><br><span class="line">},</span><br><span class="line"></span><br><span class="line">beforeRouteUpdate (to, <span class="keyword">from</span>, next) {</span><br><span class="line"> <span class="comment">// 在当前路由改变,但是该组件被复用时调用</span></span><br><span class="line"> <span class="comment">// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,</span></span><br><span class="line"> <span class="comment">// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。</span></span><br><span class="line"> <span class="comment">// 可以访问组件实例 `this`</span></span><br><span class="line">},</span><br><span class="line"></span><br><span class="line">beforeRouteLeave (to, <span class="keyword">from</span>, next) {</span><br><span class="line"> <span class="comment">// 导航离开该组件的对应路由时调用</span></span><br><span class="line"> <span class="comment">// 可以访问组件实例 `this`</span></span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>还有一个就是</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"><!-- 命名的路由 --></span></span><br><span class="line"><span class="tag"><<span class="name">router-link</span> <span class="attr">:to</span>=<span class="string">"{ name: 'user', params: { userId: 123 }}"</span>></span>User<span class="tag"></<span class="name">router-link</span>></span></span><br></pre></td></tr></table></figure><h2 id="watch"><a href="#watch" class="headerlink" title="watch"></a>watch</h2><p>watch 很好用~</p>]]></content>
<summary type="html"><p>最近开始接触 vue, 写了一个算是前端小论坛的公司内部项目, 算是一个知识库, 可添加一些常见的问题供别人查阅~</p>
<p>现在做个总结吧, 项目写完一个多星期, 现在想想差不多都忘记了~ 真是老了~</p>
<h2 id="生命周期"><a href="#生命周期"</summary>
<category term="vue" scheme="https://ochukai.github.io/tags/vue/"/>
<category term="image-preview" scheme="https://ochukai.github.io/tags/image-preview/"/>
</entry>
<entry>
<title>升级到 React 15.5.0 之后遇到的问题。</title>
<link href="https://ochukai.github.io/react-15-5-0/"/>
<id>https://ochukai.github.io/react-15-5-0/</id>
<published>2017-04-17T08:43:52.000Z</published>
<updated>2023-07-16T03:46:17.424Z</updated>
<content type="html"><![CDATA[<p>propTypes 被从 react 包里面分离出来了,如果要用到 <strong>propTypes</strong>, 则必须要自己安装 <code>prop-types</code></p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install prop-types --save</span><br></pre></td></tr></table></figure><p>那么,对于之前项目里面已经存在的 <strong>propTypes</strong> 呢,可以使用 facebook 的这个工具 jscodeshift<a href="%5Bgithub/jscodeshift%5D(https://github.com/facebook/jscodeshift)">^1</a> 和 codemod<a href="%5Bgithub/react-codemod%5D(https://github.com/reactjs/react-codemod)">^2</a>, 其中 codemod 最好 clone 在当前项目文件夹。</p><p>用法像这样:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">jscodeshift </span><br><span class="line"> --extensions=js,jsx </span><br><span class="line"> -t ./react-codemod/transforms/React-PropTypes-to-prop-types.js </span><br><span class="line"> src</span><br><span class="line"></span><br><span class="line">Processing 310 files...</span><br><span class="line">Spawning 3 workers...</span><br><span class="line">Sending 50 files to free worker...</span><br><span class="line">Sending 50 files to free worker...</span><br><span class="line">Sending 50 files to free worker...</span><br><span class="line">Sending 50 files to free worker...</span><br><span class="line">Sending 50 files to free worker...</span><br><span class="line">Sending 50 files to free worker...</span><br><span class="line">Sending 10 files to free worker...</span><br><span class="line">All done.</span><br><span class="line">Results:</span><br><span class="line"> 0 errors</span><br><span class="line"> 0 unmodified</span><br><span class="line"> 310 skipped</span><br><span class="line"> 0 ok</span><br><span class="line">Time elapsed: 4.758seconds</span><br></pre></td></tr></table></figure><p>执行完之后,代码会变成这样:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line marked"><span class="keyword">import</span> <span class="title class_">PropTypes</span> <span class="keyword">from</span> <span class="string">'prop-types'</span>;</span><br><span class="line"><span class="keyword">import</span> <span class="title class_">React</span> <span class="keyword">from</span> <span class="string">'react'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">Form</span>, <span class="title class_">Card</span>, <span class="title class_">Modal</span>, <span class="title class_">Spin</span> } <span class="keyword">from</span> <span class="string">'antd'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// ...</span></span><br><span class="line"></span><br><span class="line"><span class="title class_">UserAnswerModal</span>.<span class="property">propTypes</span> = {</span><br><span class="line marked"> <span class="attr">item</span>: <span class="title class_">PropTypes</span>.<span class="property">object</span>,</span><br><span class="line marked"> <span class="attr">visible</span>: <span class="title class_">PropTypes</span>.<span class="property">bool</span>,</span><br><span class="line marked"> <span class="attr">loading</span>: <span class="title class_">PropTypes</span>.<span class="property">bool</span>,</span><br><span class="line marked"> <span class="attr">type</span>: <span class="title class_">PropTypes</span>.<span class="property">string</span>,</span><br><span class="line marked"> <span class="attr">form</span>: <span class="title class_">PropTypes</span>.<span class="property">object</span>,</span><br><span class="line marked"> <span class="attr">onOk</span>: <span class="title class_">PropTypes</span>.<span class="property">func</span>,</span><br><span class="line marked"> <span class="attr">onCancel</span>: <span class="title class_">PropTypes</span>.<span class="property">func</span>,</span><br><span class="line">};</span><br></pre></td></tr></table></figure><p>于是问题就解决了,但是因为你引用的包可能会有这个问题,所以 warning 应该不会消失。</p>]]></content>
<summary type="html"><p>propTypes 被从 react 包里面分离出来了,如果要用到 <strong>propTypes</strong>, 则必须要自己安装 <code>prop-types</code></p>
<figure class="highlight sh"><table><t</summary>
<category term="react" scheme="https://ochukai.github.io/tags/react/"/>
<category term="jscodeshift" scheme="https://ochukai.github.io/tags/jscodeshift/"/>
<category term="proptypes" scheme="https://ochukai.github.io/tags/proptypes/"/>
<category term="react-codemod" scheme="https://ochukai.github.io/tags/react-codemod/"/>
</entry>
<entry>
<title>详解 Promise</title>
<link href="https://ochukai.github.io/promise-in-action/"/>
<id>https://ochukai.github.io/promise-in-action/</id>
<published>2017-03-08T08:54:54.000Z</published>
<updated>2023-07-16T03:46:17.424Z</updated>
<content type="html"><![CDATA[<p>偶然看到一篇介绍 Promise 的文章,这个概念也出现好久了,之前一直用着 <a href="https://github.com/cujojs/when">whenjs</a>, 但是一直没有时间自己写一个。</p><p>于是下定决心,自己写一个吧~ 毕竟别人都能写出来的东西,而且工作的时候都是在写一些业务型的代码,感觉非常没有创造性~</p><hr><p>Promise 用起来挺简单的,可以很好的解决 js callback 多的时候,缩进很烦的问题。而且线性的写代码也更容易理解~</p><p>现在写这篇文章,就是高中的时候写作文一样,看到题目就开始辗转反侧,脑子里面想好多内容,理清了思路,但是拿起笔就全忘了。</p><p>今天在开始写之前我也下了好大的决心,在代码上面写了大片的注释,感觉写这一篇应该会很顺利吧,结果还是事与愿违,写了些乱七八糟的东西。</p><p>这篇文章主要是介绍 Promise 的用法以及我是怎么实现这么一个库的,但是该怎么开始写呢?于是我列了几个要点,概念,原理,实现,感觉填充起来会比较容易吧,嗯,就这么办吧~</p><h2 id="规范"><a href="#规范" class="headerlink" title="规范"></a>规范</h2><p><a href="https://promisesaplus.com/">Promise/A+ 规范</a><br><a href="https://tc39.github.io/ecma262/#sec-promise-objects">ES6 Promise</a> — 加载比较慢~ 想看就耐心等~</p><p>两个规范在这了,其实现在用的多的是 Promise/A+ 规范,看起来还是很简单的。</p><h2 id="概念"><a href="#概念" class="headerlink" title="概念"></a>概念</h2><p>Promise 就是承诺,会按照 then 的顺序做些事情,出了问题会在 catch 里面。像这样:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> p =</span><br><span class="line"> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="keyword">function</span> (<span class="params">resolve</span>) {</span><br><span class="line"> <span class="built_in">setTimeout</span>(<span class="keyword">function</span> (<span class="params"></span>) {</span><br><span class="line"> <span class="title function_">resolve</span>(<span class="literal">true</span>);</span><br><span class="line"> }, <span class="number">1000</span>);</span><br><span class="line"> })</span><br><span class="line"> .<span class="title function_">then</span>(<span class="keyword">function</span> (<span class="params">result</span>) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">'result:'</span>, result);</span><br><span class="line"> })</span><br><span class="line"> .<span class="title function_">catch</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">'error:'</span>, err);</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>要说 Promise 的原理,我就假设大家都会用了,要不然看这个干什么~ 当然每个人的想法是不一样的,我开始了~</p><p>以前面试的时候经常会被问到这个问题,你知道 Promise 是怎么实现的吗? 我说不知道,大概就是有一个数组,for 循环执行吧。2333333333333~</p><p>现在看来是不能用 for 循环来实现 Promise 了,假如好多 Promise 都是耗时间的操作,每个 Promise 的结束时间就不能控制,要等到前一个 Promise 结束之后,主动通知下一个 Promise 执行。所以就要求 Promise 里要保存下一个 Promise 的引用,方便在执行完当前 Promise 的时候调用下一个。</p><p>什么时候才是 Promise 执行结束的标志呢?就是在 then 的回调函数里面调用了 resolve(value) 或者 reject(err)的时候。所以调用下一个 Promise 的地方就在这两个方法里面。</p><p>这样看起来,Promise 的调用过程,一个结束调用另外一个,有点像链表~</p><p><img src="/../images/promise-1.png"></p><h2 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h2><h3 id="链式调用"><a href="#链式调用" class="headerlink" title="链式调用"></a>链式调用</h3><p>首先考虑两种 Promise 的调用方式</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 1.chain</span></span><br><span class="line"><span class="keyword">new</span> <span class="title class_">Promise</span>(noop)</span><br><span class="line"> .<span class="title function_">then</span>(<span class="keyword">function</span> <span class="title function_">fn1</span>(<span class="params"></span>) {})</span><br><span class="line"> .<span class="title function_">then</span>(<span class="keyword">function</span> <span class="title function_">fn2</span>(<span class="params"></span>) {})</span><br><span class="line"> .<span class="title function_">then</span>(<span class="keyword">function</span> <span class="title function_">fn3</span>(<span class="params"></span>) {});</span><br><span class="line"></span><br><span class="line"><span class="comment">// 2.</span></span><br><span class="line"><span class="keyword">var</span> p = <span class="keyword">new</span> <span class="title class_">Promise</span>(noop);</span><br><span class="line">p.<span class="title function_">then</span>(<span class="keyword">function</span> <span class="title function_">fn1</span>(<span class="params"></span>) {});</span><br><span class="line">p.<span class="title function_">then</span>(<span class="keyword">function</span> <span class="title function_">fn2</span>(<span class="params"></span>) {});</span><br><span class="line">p.<span class="title function_">then</span>(<span class="keyword">function</span> <span class="title function_">fn3</span>(<span class="params"></span>) {});</span><br></pre></td></tr></table></figure><p>第一种链式的调用方法是按照顺序执行 fn1, fn2, fn3 的意思~ (then 方法会返回新的 Promise 对象,这句话放在这里好像很奇怪~),每一次 .then 都像是连接着一个新的 Promise。</p><p>而第二种写法,fn1, fn2, fn3 是同时开始执行的~ 一个 Promise 连着三个不同的 Promise 形成了三条 Promise 调用链~</p><h3 id="构造函数"><a href="#构造函数" class="headerlink" title="构造函数"></a>构造函数</h3><p>然后说到构造函数,毕竟初始化 Promise 是在这里面进行的。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">Promise</span>(<span class="params">resolver</span>) {</span><br><span class="line"> <span class="keyword">if</span> (!util.<span class="title function_">isFunction</span>(resolver)) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">TypeError</span>(<span class="string">'resolver must be a function'</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 默认是 pending 状态</span></span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">state</span> = <span class="variable constant_">PENDING</span>;</span><br><span class="line"> <span class="comment">// resolve 的值</span></span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">value</span> = <span class="number">0</span>;</span><br><span class="line"> <span class="comment">// 保存接下来要执行的 promise 的数组,数组里面的元素是 Executor,</span></span><br><span class="line"> <span class="comment">// 包装了 Promise 及其onReject, onResolve 方法</span></span><br><span class="line"> <span class="comment">// then 方法可能会添加 Executor 到这个数组,也只有 then 方法会添加元素到这个数组</span></span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">queue</span> = [];</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (resolver !== util.<span class="property">noop</span>) {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="title function_">__callThen</span>(resolver); <span class="comment">// call thenable.</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="title class_">Promise</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">then</span> = <span class="keyword">function</span> (<span class="params">onResolved, onRejected</span>) { ... }</span><br><span class="line"><span class="title class_">Promise</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">catch</span> = <span class="keyword">function</span> (<span class="params">onResolved, onRejected</span>) { ... }</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 上面提到的 Executor</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">Executor</span>(<span class="params">promise, onResolved, onRejected</span>) {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">promise</span> = promise;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">onRejected</span> = onRejected;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">onResolved</span> = onResolved;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>Promise 大概是这三个函数使用的比较多,当然还有几个静态方法,或者 delay 方法 。</p><p>这里应该写点什么呢,代码里面稍微有点注释,Promise 的数据结构就像构造函数里面写的,初始化 Promise 的函数 <code>function (onResolved, onReject) {}</code> 与 then 方法的参数 <code>function (onResolved, onReject) {}</code> 形式是一样的,被称为 <strong>thenable</strong></p><p>参数被传递进构造函数之后,稍做休息,便直接开始执行了(放在 timeout 里面执行,还是要稍等一下的)。就是在 <code>__callThen</code> 方法里面执行,这个方法也很重要,就是对 thenable 函数 try-catch 一下~ 出现异常当然要拒绝。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 调用 then 方法,同时会 try catch 一下,</span></span><br><span class="line"><span class="comment"> * 如果出错,就 doReject(err)</span></span><br><span class="line"><span class="comment"> * 如果没错,就 doResolve(value)</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="title class_">Promise</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">__callThen</span> = <span class="keyword">function</span> (<span class="params">then</span>) {</span><br><span class="line"> <span class="keyword">var</span> called = <span class="literal">false</span>;</span><br><span class="line"> <span class="keyword">var</span> self = <span class="variable language_">this</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">function</span> <span class="title function_">resolve</span>(<span class="params">value</span>) {</span><br><span class="line"> <span class="keyword">if</span> (!called) {</span><br><span class="line"> called = <span class="literal">true</span>;</span><br><span class="line"> self.<span class="title function_">doResolve</span>(value);</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_">reject</span>(<span class="params">e</span>) {</span><br><span class="line"> <span class="keyword">if</span> (!called) {</span><br><span class="line"> called = <span class="literal">true</span>;</span><br><span class="line"> self.<span class="title function_">doReject</span>(e);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="title function_">then</span>(resolve, reject);</span><br><span class="line"> } <span class="keyword">catch</span> (e) {</span><br><span class="line"> <span class="keyword">if</span> (!called) {</span><br><span class="line"> called = <span class="literal">true</span>;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="title function_">doReject</span>(e);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">};</span><br></pre></td></tr></table></figure><p>好了,到现在为止,then 方法之前的内容就会执行到这里。</p><p>这一段的 主要内容就是,够造了一个 Promise(会执行传入的 thenable 函数), 还没有涉及到 then。</p><h3 id="Then-函数"><a href="#Then-函数" class="headerlink" title="Then 函数"></a>Then 函数</h3><p>在 then 方法里面,queue 数组终于派上了用场,因为可能会添加 Executor 到 queue 里面去,当构造 Promise 的 thenable 执行很慢的话~ </p><p>如果当前 promise 已经被 RESOLVED 或者 REJECTED,那就直接执行 onResolved 或者 onRejected。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Promise</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">then</span> = <span class="keyword">function</span> (<span class="params">onResolved, onRejected</span>) {</span><br><span class="line"> <span class="keyword">var</span> promise2 = <span class="keyword">new</span> <span class="title class_">Promise</span>(util.<span class="property">noop</span>);</span><br><span class="line"> </span><br><span class="line"> <span class="comment">// state 默认就是 PENDING,如果完成 或者失败会改变</span></span><br><span class="line"> <span class="comment">// 如果在 then 方法里面还是 PENDING 的话,说明前一个过程还没有结束</span></span><br><span class="line"> <span class="keyword">if</span> (<span class="variable language_">this</span>.<span class="property">state</span> !== <span class="variable constant_">PENDING</span>) {</span><br><span class="line"> <span class="keyword">var</span> dummy = <span class="variable language_">this</span>.<span class="property">state</span> === <span class="variable constant_">FULFILLED</span></span><br><span class="line"> ? onResolved</span><br><span class="line"> : onRejected;</span><br><span class="line"> promise2.<span class="title function_">__runInOrder</span>(dummy, <span class="variable language_">this</span>.<span class="property">value</span>);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">queue</span>.<span class="title function_">push</span>(<span class="keyword">new</span> <span class="title class_">Executor</span>(promise2, onResolved, onRejected));</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> promise2;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="comment">// 为什么叫 run in order 呢,我实在是词穷,不过 fn 传递到此函数之后,</span></span><br><span class="line"><span class="comment">// 会在下一个 tick 按顺序执行,仅此而已~</span></span><br><span class="line"><span class="title class_">Promise</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">__runInOrder</span> = <span class="keyword">function</span> (<span class="params">fn, value</span>) {</span><br><span class="line"> <span class="keyword">var</span> self = <span class="variable language_">this</span>;</span><br><span class="line"> <span class="built_in">setTimeout</span>(<span class="keyword">function</span> (<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">var</span> ret;</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> ret = <span class="title function_">fn</span>(value);</span><br><span class="line"> } <span class="keyword">catch</span> (e) {</span><br><span class="line"> <span class="keyword">return</span> self.<span class="title function_">doReject</span>(e);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (ret === self) {</span><br><span class="line"> self.<span class="title function_">doReject</span>(<span class="keyword">new</span> <span class="title class_">TypeError</span>(<span class="string">'Cannot resolve promise with itself.'</span>));</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> self.<span class="title function_">doResolve</span>(ret);</span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line">};</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>接下来的两个方法比较最重要,上面可能看到过很多次他们的身影,但我都没有说过,最开始的时候我说前一个 promise 完成的时候要通知下一个 promise,这个通知的过程就在这两个方法里进行的。</p><p>有一点不同的是:doResolve 方法要检查前一个 promise 返回的值,如果前一个 promise 完成时返回了一个新的 promise,那么肯定要等这个返回的 promise 执行完成之后再 doResolve,而 doReject 就很直截了当了,反正你出错了,不要再执行了,然后就报错了~</p><h3 id="doResolve"><a href="#doResolve" class="headerlink" title="doResolve"></a>doResolve</h3><p>前面说了太多这里没什么好写的了,看看代码吧~</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Promise</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">doResolve</span> = <span class="keyword">function</span> (<span class="params">value</span>) {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">var</span> then = util.<span class="title function_">getThen</span>(value);</span><br><span class="line"> <span class="keyword">if</span> (then) {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="title function_">__callThen</span>(then);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">state</span> = <span class="variable constant_">FULFILLED</span>;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">value</span> = value;</span><br><span class="line"> <span class="comment">// Executor 的 doResolve</span></span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">queue</span>.<span class="title function_">forEach</span>(<span class="keyword">function</span> (<span class="params">item</span>) {</span><br><span class="line"> item.<span class="title function_">doResolve</span>(value);</span><br><span class="line"> });</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>;</span><br><span class="line"> } <span class="keyword">catch</span> (e) {</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="title function_">doReject</span>(e);</span><br><span class="line"> }</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="comment">// 如果 onResolved 不是函数就继续执行下一个 promise, 这是规定~</span></span><br><span class="line"><span class="title class_">Executor</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">doResolve</span> = <span class="keyword">function</span> (<span class="params">value</span>) {</span><br><span class="line"> <span class="keyword">if</span> (util.<span class="title function_">isFunction</span>(<span class="variable language_">this</span>.<span class="property">onResolved</span>)) {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">promise</span>.<span class="title function_">__runInOrder</span>(<span class="variable language_">this</span>.<span class="property">onResolved</span>, value);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">promise</span>.<span class="title function_">doResolve</span>(value);</span><br><span class="line"> }</span><br><span class="line">};</span><br></pre></td></tr></table></figure><h3 id="doReject"><a href="#doReject" class="headerlink" title="doReject"></a>doReject</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Promise</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">doReject</span> = <span class="keyword">function</span> (<span class="params">err</span>) {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">state</span> = <span class="variable constant_">REJECTED</span>;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">value</span> = err;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">queue</span>.<span class="title function_">forEach</span>(<span class="keyword">function</span> (<span class="params">item</span>) {</span><br><span class="line"> item.<span class="title function_">doReject</span>(err);</span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</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="title class_">Executor</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">doReject</span> = <span class="keyword">function</span> (<span class="params">err</span>) {</span><br><span class="line"> <span class="keyword">if</span> (util.<span class="title function_">isFunction</span>(<span class="variable language_">this</span>.<span class="property">onRejected</span>)) {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">promise</span>.<span class="title function_">__runInOrder</span>(<span class="variable language_">this</span>.<span class="property">onRejected</span>, err);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">promise</span>.<span class="title function_">doReject</span>(err);</span><br><span class="line"> }</span><br><span class="line">};</span><br></pre></td></tr></table></figure><p>好像概念都写完了。</p><p>Github: <a href="https://github.com/ochukai/promise">ochukai/promise</a></p>]]></content>
<summary type="html"><p>偶然看到一篇介绍 Promise 的文章,这个概念也出现好久了,之前一直用着 <a href="https://github.com/cujojs/when">whenjs</a>, 但是一直没有时间自己写一个。</p>
<p>于是下定决心,自己写一个吧~ 毕竟别人都能写出</summary>
<category term="js" scheme="https://ochukai.github.io/tags/js/"/>
<category term="promise" scheme="https://ochukai.github.io/tags/promise/"/>
</entry>
<entry>
<title>(**) 的 IE 👽</title>
<link href="https://ochukai.github.io/ie-css-hack/"/>
<id>https://ochukai.github.io/ie-css-hack/</id>
<published>2017-02-17T08:17:14.000Z</published>
<updated>2023-07-16T03:46:17.422Z</updated>
<content type="html"><![CDATA[<blockquote><p>以前都说前端坑,或者前端入坑了,为什么呢? 因为 IE 啊。</p></blockquote><p>我做前端以来,一直都是很幸福的,因为还几乎咩有处理过 ie 的兼容问题。</p><p>但是最近要处理,以前应付面试背过的兼容方案都忘掉了,所以还是要查。</p><p>忽略 IE6,IE7 的情况下,规则就这几条:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">\9 IE6/IE7/IE8/IE9/IE10都生效 </span><br><span class="line">\0 IE8/IE9/IE10都生效</span><br><span class="line">\9\0 只对IE9/IE10生效</span><br></pre></td></tr></table></figure><p>当然还有这个东西</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"><!--[if lt IE 9]><![endif]--></span></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><blockquote>
<p>以前都说前端坑,或者前端入坑了,为什么呢? 因为 IE 啊。</p>
</blockquote>
<p>我做前端以来,一直都是很幸福的,因为还几乎咩有处理过 ie 的兼容问题。</p>
<p>但是最近要处理,以前应付面试背过的兼容方案都忘掉了,所以</summary>
<category term="IE" scheme="https://ochukai.github.io/categories/ie/"/>
<category term="ie" scheme="https://ochukai.github.io/tags/ie/"/>
<category term="css hack" scheme="https://ochukai.github.io/tags/css-hack/"/>
</entry>
</feed>