AlloyTeam

AlloyTeam

Copyright © Tencent AlloyTeam. All Rights Reserved.
AlloyTeam 腾讯全端 AlloyTeam 团队 Blog
  • 首页
  • Web 开发
    • 前端资讯
    • HTML5
    • CSS3
    • JavaScript
    • Node.js
    • 移动 Web 开发
    • 用户体验设计
    • Web 前端优化
    • 资源工具
  • 移动开发
    • Android 开发
    • iOS 开发
    • 移动 Web 开发
  • Alloy 实验室
    • 作品
    • HTML5 游戏
  • 关于
    • 团队
    • Github
    • 留言
    • 友情链接
  • RSS
  • sublime 的 colorscheme
    In Web开发 on 2015年05月07日 by TAT.jerojiang view: 978
    0

    想让 markdown 高亮,找了点插件,比如

    https://github.com/jonschlinkert/sublime-markdown-extended

    可以让代码块高亮。但没有达到我想要的效果,我想让 markdown 的每个部分高亮,比如 # 标题 高亮。

    然后找到了

    sublime-monokai-extended

    这个达到了我的效果,但是将整个的 color scheme 都改了,自然不行。

    现在的问题是——

    在当前的 color scheme 高亮 markdown

    继续寻找,然后找了这个

    markdown.xml

    按照上面说的,将代码复制到我的 Obsidian.tmTheme ,成功了。在现有 color scheme 上高亮了 markdown 。

    但是头疼的是,我不喜欢他的 标题 颜色,想改。看了代码,摘录一段:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <dict>
      <key>name</key>
      <string>Markup: Underline</string>
      <key>scope</key>
      <string>markup.underline</string>
      <key>settings</key>
      <dict>
          <key>fontStyle</key>
          <string>underline</string>
          <key>foreground</key>
          <string><span class="comment">#839496</string></span>
      </dict>
    </dict>
     

    一头雾水,完全不知道 how does it working ,也就无从改起。

    没有解决不了的问题,找了半天,这篇博客

    Tips For Creating Sublime Text Color Schemes

    解决了我的问题。其中的 tip1 尤其好——

    Sublime text color schemes work by defining colors for scopes. A syntax definition matches the different parts of the file’s text (e.g. functions, classes, keywords, etc.) and maps them to a named scope. Then the color scheme specifies what colors to use for what scopes.
    The hard part comes when you see a particular piece of syntax you want to style a specific way, but you do not know what scope it is. I did a lot of guess work until I discovered the ScopeHunter plugin.
    The ScopeHunter plugin allows you to select some text and it tells you what scope it matches. This removes the guess work and allows you to quickly color the pieces you want to.

    sublime text 的 color scheme 是通过 scopes 来定义 color 的,我们可以安装插件 ScopeHunter 来查看光标出的 scopes ,从而可以自定义颜色。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <dict>
      <key>name</key>
      <string>Markup: Underline</string>
      <key>scope</key>  <!-- 这里就是 scope,知道了这个,其他就好办 -->
      <string>markup.underline</string>
      <key>settings</key>
      <dict>
          <key>fontStyle</key>
          <string>underline</string>
          <key>foreground</key>
          <string><span class="comment">#839496</string></span>
      </dict>
    </dict>
     

    至此,已经可以修改 markdown 到我想要的状态了。但是我又想,能不能把 markdown.md 的背景也改了,
    甚至模仿 github 的样式。

    少说多做,幸福一生。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <dict>
        <key>name</key>
        <string>Markdown</string>
        <key>scope</key>
        <string>text.html.markdown</string>
        <key>settings</key>
        <dict>
            <key>background</key>
            <string><span class="comment">#ffffff</string></span>
            <key>foreground</key>
            <string><span class="comment">#666666</string></span>
        </dict>
    </dict>
     

    马上把上面的代码加入 color scheme,有效果,嗯,现在比较大的问题是 lineHighlight(鼠标所在行高亮)比较突兀。

    是个问题,并且 lineHighlight 没有 scope ,蛋疼了。

    解决方式是调整全局 lineHighlight 的值,使其用透明度达到效果。

    Perfect!

    参考:

    http://stackoverflow.com/questions/10636410/modifying-sublime-text-2-for-js

    附上我的 color scheme Obsidian.tmTheme :

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    575
    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    590
    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    607
    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    622
    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
    642
    643
    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    660
    661
    662
    663
    664
    665
    666
    667
    668
    669
    670
    671
    672
    673
    674
    675
    676
    677
    678
    679
    680
    681
    682
    683
    684
    685
    686
    687
    688
    689
    690
    691
    692
    693
    694
    695
    696
    697
    698
    699
    700
    701
    702
    703
    704
    705
    706
    707
    708
    709
    710
    711
    712
    713
    714
    715
    716
    717
    718
    719
    720
    721
    722
    723
    724
    725
    726
    727
    728
    729
    730
    731
    732
    733
    734
    735
    736
    737
    738
    739
    740
    741
    742
    743
    744
    745
    746
    747
    748
    749
    750
    751
    752
    753
    754
    755
    756
    757
    758
    759
    760
    761
    762
    763
    764
    765
    766
    767
    768
    769
    770
    771
    772
    773
    774
    775
    776
    777
    778
    779
    780
    781
    782
    783
    784
    785
    786
    787
    788
    789
    790
    791
    792
    793
    794
    795
    796
    797
    798
    799
    800
    801
    802
    803
    804
    805
    806
    807
    808
    809
    810
    811
    812
    813
    814
    815
    816
    817
    818
    819
    820
    821
    822
    823
    824
    825
    826
    827
    828
    829
    830
    831
    832
    833
    834
    835
    836
    837
    838
    839
    840
    841
    842
    843
    844
    845
    846
    847
    848
    849
    850
    851
    852
    853
    854
    855
    856
    857
    858
    859
    860
    861
    862
    863
    864
    865
    866
    867
    868
    869
    870
    871
    872
    873
    874
    875
    876
    877
    878
    879
    880
    881
    882
    883
    884
    885
    886
    887
    888
    889
    890
    891
    892
    893
    894
    895
    896
    897
    898
    899
    900
    901
    902
    903
    904
    905
    906
    907
    908
    909
    910
    911
    912
    913
    914
    915
    916
    917
    918
    919
    920
    921
    922
    923
    924
    925
    926
    927
    928
    929
    930
    931
    932
    933
    934
    935
    936
    937
    938
    939
    940
    941
    942
    943
    944
    945
    946
    947
    948
    949
    950
    951
    952
    953
    954
    955
    956
    957
    958
    959
    960
    961
    962
    963
    964
    965
    966
    967
    968
    969
    970
    971
    972
    973
    974
    975
    976
    977
    978
    <?xml version=<span class="string">"1.0"</span> encoding=<span class="string">"UTF-8"</span><span class="preprocessor">?></span>
    <!DOCTYPE plist <span class="keyword">PUBLIC</span> <span class="string">"-//Apple//DTD PLIST 1.0//EN"</span> <span class="string">"http://www.apple.com/DTDs/PropertyList-1.0.dtd"</span>>
    <plist version=<span class="string">"1.0"</span>>
    <dict>
        <key>author</key>
        <string>Marcus Ekwall</string>
        <key>modify</key>
        <string>jerry</string>
        <key>name</key>
        <string>Obsidian</string>
        <key>version</key>
        <string><span class="number">0.1</span></string>
        <key>settings</key>
        <<span class="keyword">array</span>>
            <!-- <span class="keyword">global</span> -->
            <dict>
                <key>settings</key>
                <dict>
                    <key>background</key>
                    <string><span class="comment">#293134</string></span>
                    <key>caret</key>
                    <string><span class="comment">#E0E2E4</string></span>
                    <key>foreground</key>
                    <string><span class="comment">#81969A</string></span>
                    <key>invisibles</key>
                    <string><span class="comment">#BFBFBF</string></span>
                    <key>lineHighlight</key>
                    <string><span class="comment">#E5E5E520</string></span>
                    <key>selection</key>
                    <string><span class="comment">#0D0F0F</string></span>
                </dict>
            </dict>
            <dict>
              <key>name</key>
              <string>Text base</string>
              <key>scope</key>
              <string>text</string>
              <key>settings</key>
              <dict>
                <key>background</key>
                <string><span class="comment">#293134</string></span>
                <key>foreground</key>
                <string><span class="comment">#E0E2E4</string></span>
              </dict>
            </dict>
            <dict>
              <key>name</key>
              <string>Source base</string>
              <key>scope</key>
              <string>source</string>
              <key>settings</key>
              <dict>
                <key>background</key>
                <string><span class="comment">#293134</string></span>
                <key>foreground</key>
                <string><span class="comment">#E0E2E4</string></span>
              </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Comment</string>
                <key>scope</key>
                <string>comment</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                    <key>foreground</key>
                    <string><span class="comment">#66747B</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Comment Block</string>
                <key>scope</key>
                <string>comment.block</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string>italic</string>
                    <key>foreground</key>
                    <string><span class="comment">#66747B</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Comment Doc</string>
                <key>scope</key>
                <string>comment.documentation</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                    <key>foreground</key>
                    <string><span class="comment">#66747B</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>String</string>
                <key>scope</key>
                <string>string</string>
                <key>settings</key>
                <dict>
                    <key>foreground</key>
                    <string><span class="comment">#EC7600</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Number</string>
                <key>scope</key>
                <string>constant.numeric</string>
                <key>settings</key>
                <dict>
                    <key>foreground</key>
                    <string><span class="comment">#FFCD22</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Built-in constant</string>
                <key>scope</key>
                <string>constant.language</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string>bold</string>
                    <key>foreground</key>
                    <string><span class="comment">#93C763</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>User-defined constant</string>
                <key>scope</key>
                <string>constant.character, constant.other</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Variable</string>
                <key>scope</key>
                <string>variable.language, variable.other</string>
                <key>settings</key>
                <dict>
                    <key>foreground</key>
                    <string><span class="comment">#678CB1</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>JavaScript: Variable</string>
                <key>scope</key>
                <string>variable.language.js</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string>bold</string>
                    <key>foreground</key>
                    <string><span class="comment">#93C763</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Keyword</string>
                <key>scope</key>
                <string>keyword</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string>bold</string>
                    <key>foreground</key>
                    <string><span class="comment">#93C763</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Operator</string>
                <key>scope</key>
                <string>keyword.operator</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                    <key>foreground</key>
                    <string><span class="comment">#E0E2E4</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Storage</string>
                <key>scope</key>
                <string>storage</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string>bold</string>
                    <key>foreground</key>
                    <string><span class="comment">#93C763</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string><span class="keyword">Class</span> name</string>
                <key>scope</key>
                <string>entity.name.<span class="keyword">class</span></string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Inherited <span class="keyword">class</span></string>
                <key>scope</key>
                <string>entity.other.inherited-<span class="keyword">class</span></string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string><span class="keyword">Function</span> name</string>
                <key>scope</key>
                <string>entity.name.<span class="keyword">function</span></string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string>bold</string>
                    <key>foreground</key>
                    <string><span class="comment">#678CB1</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string><span class="keyword">Function</span> argument</string>
                <key>scope</key>
                <string>variable.parameter</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Tag name</string>
                <key>scope</key>
                <string>entity.name.tag</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string>bold</string>
                    <key>foreground</key>
                    <string><span class="comment">#408080</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Tag attribute</string>
                <key>scope</key>
                <string>entity.other.attribute-name</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string>bold</string>
                    <key>foreground</key>
                    <string><span class="comment">#808040</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Library <span class="keyword">function</span></string>
                <key>scope</key>
                <string>support.<span class="keyword">function</span></string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Library constant</string>
                <key>scope</key>
                <string>support.constant</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Library <span class="keyword">class</span>/type</string>
                <key>scope</key>
                <string>support.type, support.<span class="keyword">class</span></string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Library variable</string>
                <key>scope</key>
                <string>support.other.variable</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Invalid</string>
                <key>scope</key>
                <string>invalid</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Embedded section</string>
                <key>scope</key>
                <string>punctuation.section.embedded</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string>bold</string>
                    <key>foreground</key>
                    <string><span class="comment">#D955C1</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Keyword Operator <span class="keyword">Class</span></string>
                <key>scope</key>
                <string>keyword.operator.<span class="keyword">class</span></string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                    <key>foreground</key>
                    <string><span class="comment">#96989A</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Delimiter</string>
                <key>scope</key>
                <string>meta.delimiter</string>
                <key>settings</key>
                <dict>
                    <key>foreground</key>
                    <string><span class="comment">#96979A</string></span>
                </dict>
            </dict>
            <dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Round brace</string>
                <key>scope</key>
                <string>meta.brace</string>
                <key>settings</key>
                <dict>
                    <key>foreground</key>
                    <string><span class="comment">#E8E2B7</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Curly brace</string>
                <key>scope</key>
                <string>meta.brace.curly</string>
                <key>settings</key>
                <dict>
                    <key>foreground</key>
                    <string><span class="comment">#96979A</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>JavaScript: Embedded</string>
                <key>scope</key>
                <string>source.js.embedded</string>
                <key>settings</key>
                <dict>
                    <key>background</key>
                    <string><span class="comment">#262C2F</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>JavaScript: Variable</string>
                <key>scope</key>
                <string>variable.language.js</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string>bold</string>
                    <key>foreground</key>
                    <string><span class="comment">#93C763</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>JavaScript: <span class="keyword">Function</span> name</string>
                <key>scope</key>
                <string>entity.name.<span class="keyword">function</span>.js</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                    <key>foreground</key>
                    <string><span class="comment">#E0E2E4</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>JavaScript: Instance</string>
                <key>scope</key>
                <string>entity.name.type.instance.js</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string>underline, bold</string>
                    <key>foreground</key>
                    <string><span class="comment">#AFC0E5</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>JavaScript: <span class="keyword">Class</span></string>
                <key>scope</key>
                <string>support.<span class="keyword">class</span>.js</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                    <key>foreground</key>
                    <string><span class="comment">#78D023</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>JavaScript: Modifier</string>
                <key>scope</key>
                <string>storage.modifier.js</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                    <key>foreground</key>
                    <string><span class="comment">#78D023</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>JavaScript: Constant</string>
                <key>scope</key>
                <string>support.constant.js, support.constant.dom.js</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                    <key>foreground</key>
                    <string><span class="comment">#78D023</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>JavaScript: Operator <span class="keyword">and</span> terminator</string>
                <key>scope</key>
                <string>keyword.operator.js, punctuation.terminator.statement.js</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                    <key>foreground</key>
                    <string><span class="comment">#E0E2E4</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>JavaScript: Console</string>
                <key>scope</key>
                <string>entity.name.type.object.js.firebug, keyword.other.js</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                    <key>foreground</key>
                    <string><span class="comment">#DA4236</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>CSS: Embedded</string>
                <key>scope</key>
                <string>source.css.embedded</string>
                <key>settings</key>
                <dict>
                    <key>background</key>
                    <string><span class="comment">#262C2F</string></span>
                    <key>foreground</key>
                    <string><span class="comment">#E0E2E4</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>CSS: Directive</string>
                <key>scope</key>
                <string>keyword.control.at-rule.import.css</string>
                <key>settings</key>
                <dict>
                    <key>foreground</key>
                    <string><span class="comment">#A082BD</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>CSS: <span class="keyword">Class</span></string>
                <key>scope</key>
                <string>entity.other.attribute-name.<span class="keyword">class</span>.css</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                    <key>foreground</key>
                    <string><span class="comment">#93C763</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>CSS: Tag</string>
                <key>scope</key>
                <string>entity.name.tag.css</string>
                <key>settings</key>
                <dict>
                    <key>foreground</key>
                    <string><span class="comment">#B3B689</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>CSS: Property</string>
                <key>scope</key>
                <string>support.type.property-name.css, meta.property-name.css</string>
                <key>settings</key>
                <dict>
                    <key>foreground</key>
                    <string><span class="comment">#678CB1</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>CSS: Unit</string>
                <key>scope</key>
                <string>keyword.other.unit.css</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                    <key>foreground</key>
                    <string><span class="comment">#E0E2E4</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>CSS: Parameter</string>
                <key>scope</key>
                <string>variable.parameter.misc.css</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                    <key>foreground</key>
                    <string><span class="comment">#EC7600</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>CSS: ID</string>
                <key>scope</key>
                <string>entity.other.attribute-name.id.css</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                    <key>foreground</key>
                    <string><span class="comment">#D5AB55</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>CSS: Definition</string>
                <key>scope</key>
                <string>punctuation.definition.entity.css</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                    <key>foreground</key>
                    <string><span class="comment">#9CB4AA</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>HTML/XML: String</string>
                <key>scope</key>
                <string>string.quoted.double.html, string.quoted.single.html, string.quoted.double.xml, string.quoted.single.xml</string>
                <key>settings</key>
                <dict>
                    <key>foreground</key>
                    <string><span class="comment">#E1E2CF</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>HTML/XML: Definition</string>
                <key>scope</key>
                <string>punctuation.definition.tag.begin.html, punctuation.definition.tag.end.html, punctuation.definition.tag.html, punctuation.definition.tag.begin.xml, punctuation.definition.tag.end.xml, punctuation.definition.tag.xml, meta.tag.no-content</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                    <key>foreground</key>
                    <string><span class="comment">#557182</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>XML: Tag</string>
                <key>scope</key>
                <string>entity.name.tag.xml, entity.name.tag.localname.xml</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string>bold</string>
                    <key>foreground</key>
                    <string><span class="comment">#678CB1</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>XML: Definition</string>
                <key>scope</key>
                <string>meta.tag.preprocessor.xml punctuation.definition.tag.xml</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                    <key>foreground</key>
                    <string><span class="comment">#557182</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>XML: Value</string>
                <key>scope</key>
                <string>constant.other.name.xml, string.quoted.other.xml</string>
                <key>settings</key>
                <dict>
                    <key>foreground</key>
                    <string><span class="comment">#E0E2E4</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>DocType HTML: Tag</string>
                <key>scope</key>
                <string>meta.tag.sgml.doctype</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                    <key>foreground</key>
                    <string><span class="comment">#557182</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>DocType: Root</string>
                <key>scope</key>
                <string>meta.tag.sgml.doctype variable.documentroot.xml, meta.tag.sgml.doctype.html</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string></string>
                    <key>foreground</key>
                    <string><span class="comment">#D5AB55</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>DocType: Keyword</string>
                <key>scope</key>
                <string>keyword.doctype, entity.name.tag.doctype</string>
                <key>settings</key>
                <dict>
                    <key>foreground</key>
                    <string><span class="comment">#557182</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>DocType: Variable</string>
                <key>scope</key>
                <string>variable.documentroot</string>
                <key>settings</key>
                <dict>
                    <key>foreground</key>
                    <string><span class="comment">#E0E2E4</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>PHP: Embedded</string>
                <key>scope</key>
                <string>source.php.embedded</string>
                <key>settings</key>
                <dict>
                    <key>background</key>
                    <string><span class="comment">#252C30</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>PHP: Word</string>
                <key>scope</key>
                <string>support.<span class="keyword">function</span>.construct.php</string>
                <key>settings</key>
                <dict>
                    <key>foreground</key>
                    <string><span class="comment">#93C763</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>PHP: Constant</string>
                <key>scope</key>
                <string>constant.other.php</string>
                <key>settings</key>
                <dict>
                    <key>foreground</key>
                    <string><span class="comment">#D39745</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>PHP: Operator</string>
                <key>scope</key>
                <string>keyword.operator.string.php, keyword.operator.<span class="keyword">class</span>.php, keyword.operator.comparison.php, punctuation.definition.<span class="keyword">array</span>.begin.php, punctuation.definition.<span class="keyword">array</span>.end.php, punctuation.terminator.expression.php</string>
                <key>settings</key>
                <dict>
                    <key>foreground</key>
                    <string><span class="comment">#E8E2B7</string></span>
                </dict>
            </dict>
     
            <!-- markdown -->
            <dict>
                <key>name</key>
                <string>diff: deleted</string>
                <key>scope</key>
                <string>markup.deleted</string>
                <key>settings</key>
                <dict>
                    <key>background</key>
                    <string><span class="comment">#EAE3CA</string></span>
                    <key>fontStyle</key>
                    <string></string>
                    <key>foreground</key>
                    <string><span class="comment">#D3201F</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>diff: changed</string>
                <key>scope</key>
                <string>markup.changed</string>
                <key>settings</key>
                <dict>
                    <key>background</key>
                    <string><span class="comment">#EAE3CA</string></span>
                    <key>fontStyle</key>
                    <string></string>
                    <key>foreground</key>
                    <string><span class="comment">#BF3904</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>diff: inserted</string>
                <key>scope</key>
                <string>markup.inserted</string>
                <key>settings</key>
                <dict>
                    <key>background</key>
                    <string><span class="comment">#EAE3CA</string></span>
                    <key>foreground</key>
                    <string><span class="comment">#219186</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Markdown</string>
                <key>scope</key>
                <string>text.html.markdown</string>
                <key>settings</key>
                <dict>
                    <key>background</key>
                    <string><span class="comment">#ffffff</string></span>
                    <key>foreground</key>
                    <string><span class="comment">#666666</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Markdown</string>
                <key>scope</key>
                <string>text.html.markdown</string>
                <key>settings</key>
                <dict>
                    <key>background</key>
                    <string><span class="comment">#ffffff</string></span>
                    <key>foreground</key>
                    <string><span class="comment">#666666</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Markdown: Linebreak</string>
                <key>scope</key>
                <string>text.html.markdown meta.dummy.line-<span class="keyword">break</span></string>
                <key>settings</key>
                <dict>
                    <key>background</key>
                    <string><span class="comment">#A57706</string></span>
                    <key>foreground</key>
                    <string><span class="comment">#E0EDDD</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Markdown: Raw</string>
                <key>scope</key>
                <string>text.html.markdown markup.raw.inline</string>
                <key>settings</key>
                <dict>
                    <key>background</key>
                    <string><span class="comment">#F8F8F8</string></span>
                    <key>foreground</key>
                    <string><span class="comment">#269186</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Markup: Heading</string>
                <key>scope</key>
                <string>markup.heading</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string>bold</string>
                    <key>foreground</key>
                    <string><span class="comment">#000000</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Markup: Italic</string>
                <key>scope</key>
                <string>markup.italic</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string>italic</string>
                    <key>foreground</key>
                    <string><span class="comment">#839496</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Markup: Bold</string>
                <key>scope</key>
                <string>markup.bold</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string>bold</string>
                    <key>foreground</key>
                    <string><span class="comment">#ec7600</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Markup: Underline</string>
                <key>scope</key>
                <string>markup.underline</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string>underline</string>
                    <key>foreground</key>
                    <string><span class="comment">#839496</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Markup: Quote</string>
                <key>scope</key>
                <string>markup.quote</string>
                <key>settings</key>
                <dict>
                    <key>fontStyle</key>
                    <string>italic</string>
                    <key>foreground</key>
                    <string><span class="comment">#268bd2</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Markup: <span class="keyword">List</span></string>
                <key>scope</key>
                <string>markup.<span class="keyword">list</span></string>
                <key>settings</key>
                <dict>
                    <key>foreground</key>
                    <string><span class="comment">#afc0e5</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Markup: Raw</string>
                <key>scope</key>
                <string>markup.raw</string>
                <key>settings</key>
                <dict>
                    <key>foreground</key>
                    <string><span class="comment">#b58900</string></span>
                </dict>
            </dict>
            <dict>
                <key>name</key>
                <string>Markup: Separator</string>
                <key>scope</key>
                <string>meta.separator</string>
                <key>settings</key>
                <dict>
                    <key>background</key>
                    <string><span class="comment">#eee8d5</string></span>
                    <key>fontStyle</key>
                    <string>bold</string>
                    <key>foreground</key>
                    <string><span class="comment">#268bd2</string></span>
                </dict>
            </dict>
        </<span class="keyword">array</span>>
        <key>uuid</key>
        <string><span class="number">70442</span>A54-<span class="number">7505</span>-<span class="number">46</span>E2-AAD8-<span class="number">44691</span>BBC53DF</string>
    </dict>
    </plist>
     

    继续阅读

  • TAT.dnt 强大的 observejs
    In Web开发 on 2015年05月07日 by TAT.dnt view: 2,421
    6

    写在前面

    各大 MVVM 框架的双向绑定太难以观察,很难直观地从业务代码里知道发生了什么,我不是双向绑定的反对者,只是认为双向绑定不应该糅合进底层框架,而应该出现在业务代码中,或者是业务和框架之间的代码上,由开发者实现,由开发者决定观察什么,决定响应什么。
    以及 Object.observe 的支持度不够好(http://caniuse.com/#search=observe),再者 Object.observe 的功能太弱(如对象内数组的变化无法监听)。
    所以就有了 observejs。

    继续阅读

  • 测试工具 mocha 用法小结
    In Web开发 on 2015年05月06日 by TAT.vienwu view: 1,983
    0

    这篇是前段时间总结给自己备忘的,要用到的工具实在太多,没法一一记住。

    个人感觉,作为一个测试的工具,只要会用就好了。

    所以这里稍微做了一些修改,简单介绍一下常用的写法和命令,其次将之前的一些示例改成 javascript 版本,方便没有 coffee 基础的同学浏览。

    介绍

    mocha 是一个拥有丰富功能的 javascript 测试框架,可以用于 nodejs 和浏览器。支持同步/异步测试用例,有多种报告形式。

    官网介绍了很多的特性,个人感觉实用的就几点:

    一个是 nodejs 和浏览器都可以用,不用再记那么多奇怪的 api 和写法了。

    其次是编写同步/异步测试用例非常简单。

    安装

    1
    2
    $ npm install mocha -g
     

    成功安装后就可以使用 mocha 命令了。

    使用

    运行./test/目录所有 js

    1
    2
    $ mocha
     

    指定 js 文件

    1
    2
    $ mocha xxx.js
     

    监听文件变化

    1
    2
    $ mocha xxx.js -w
     

    指定 coffee 编译

    for coffescript 1.6

    1
    2
    $ mocha --compilers coffee:coffee-script test.coffee
     

    for coffeescript 1.7+

    1
    2
    $ mocha --compilers coffee:coffee-script/register test.coffee
     

    浏览器的使用

    1
    2
    $ mocha init <path>
     

    指定一个目录,初始化一个用于浏览器的测试目录。执行后会在该目录生成 index.html、mocha.js、mocha.css 和一个空白的 test.js,可以直接在 test.js 中添加测试用例。

    当然,也可以不敲命令直接复制引用 mocha.js 到 html。

    编写用例

    常用的断言库都可以运行的很好。以下列出几个:

    • should.js BDD style shown throughout these docs.
    • chai expect() assert() and should style assertions
    • expect.js expect() style assertions
    • better-assert c-style self.documenting assert()

    个人一般用 nodejs 自带的 assert(方便不用安装)和 should.js(功能强大很好用)

    同步代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <span class="keyword">require</span>(<span class="string">'should'</span>);
    describe(<span class="string">'测试数组Array'</span>,<span class="keyword">function</span>(){
        describe(<span class="string">'测试#indexOf方法'</span>,<span class="keyword">function</span>(){
            it(<span class="string">'不存在的元素会返回-1'</span>,<span class="keyword">function</span>(){
                [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>].indexOf(<span class="number">5</span>).should.equal(-<span class="number">1</span>);
                [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>].indexOf(<span class="number">0</span>).should.equal(-<span class="number">1</span>);
            });
        });
    });
     

    异步代码

    写法和同步代码类似,只是在 it()的第二个参数的函数参数中传入一个 done 函数,用于控制异步函数的结束。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    describe(<span class="string">'测试User模块'</span>,<span class="keyword">function</span>(){
        describe(<span class="string">'测试#save()方法'</span>,<span class="keyword">function</span>(){
            it(<span class="string">'此处不应出错'</span>,<span class="keyword">function</span>(done){
                <span class="keyword">var</span> user = <span class="keyword">new</span> User({name:<span class="string">'董小姐'</span>});
                user.save(<span class="keyword">function</span>(err){
                    assert.ifError(err);
                    done();
                });
            });
        });
    });
     

    其中,done()函数也可以接受一个 error 作为参数,所以上面其实可以简化为:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    describe(<span class="string">'测试User模块'</span>,<span class="keyword">function</span>(){
        describe(<span class="string">'测试#save()方法'</span>,<span class="keyword">function</span>(){
            it(<span class="string">'此处不应出错'</span>,<span class="keyword">function</span>(done){
                <span class="keyword">var</span> user = <span class="keyword">new</span> User({name:<span class="string">'董大爷'</span>});
                user.save(done);
            });
        });
    });
     

    hooks

    mocha 支持多种体位的 hook,用法做一些或者干掉一些东东。如下:

    • before() 开始前 1 次
    • after() 结束后做 1 次
    • beforeEach() 开始前每次都做
    • afterEach() 每次结束后都做

    所有的 hooks 都可以接收 done()参数用于异步结束。甚至可以不使用 done 参数,而是直接返回一个 promise 对象,例如:

    1
    2
    3
    4
    5
    6
    beforeEach(<span class="keyword">function</span>(){
      <span class="keyword">return</span> db.clear().then(<span class="keyword">function</span>() {
        <span class="keyword">return</span> db.save([tobi, loki, jane]);
      });
    });
     

    不过建议还是加上 done 参数,看起来清晰,习惯统一。

    BDD 和 TDD

    现在一般都用 BDD。

    BDD interface 提供了 describe(),context(),it(),before(),after(),beforeEach(),afterEach()。

    context() 和 describe() 没区别。

    TDD interface 提供了 suite(),test(),suiteSetup(),suiteTeardown(),setup(),teardown()

    其他常用

    -b 参数 只显示第一个异常

    一般测试用例多的时候非常有用,不然某个接口变化全屏报错就悲剧了

    -t 参数 指定单个测试用例的超时时间

    默认单个测试用例超时时间为 2000ms。

    命令行中添加为全局的设置,也可以在测试用例内部调用 timeout()方法单独控制。

    ok,介绍到此就结束了,最后附上其他命令速查

    其他命令行

    • -h,—help
    • -V,—version
    • -A,—async-only 强制为异步模式,即所有测试必须包含一个 done() 回调。
    • -c,—colors
    • -C,—no-colors
    • -G,—growl
    • -O,—reporter-options
    • -R,—reporter
    • -S,—sort
    • -b,—bail
    • -d,—debug
    • -g,—grep
    • -f,—fgrep
    • -gc,—expose-gc
    • -i,—invert
    • -r,—require
    • -s,—slow
    • -t,—timeout 设置超时,默认为 2000ms,如果是长时间运算需要设置。
    • -u,—ui
    • -w,—watch 监视文件变化
    • —check-leaks
    • —compilers :,… 使用指定模块编译文件,经常会用到编译 coffee
    • —debug-brak
    • —globals
    • —inline-diffs
    • —interfaces
    • —no-deprecation
    • —no-exit
    • —no-timeouts
    • —opts
    • —prof
    • —recursive
    • —reporters
    • —throw-deprecation
    • —trace
    • —trace-deprecation
    • —watch-extensions ,…
    • —delay

    继续阅读

  • React 直出实现与原理
    In Web开发 on 2015年05月04日 by TAT.donaldyang view: 2,449
    1

    前一篇文章我们介绍了虚拟 DOM 的实现与原理,这篇文章我们来讲讲 React 的直出。
    比起 MVVM,React 比较容易实现直出,那么 React 的直出是如何实现,有什么值得我们学习的呢?

    为什么 MVVM 不能做直出?

    对于 MVVM,HTML 片段即为配置,而直出后的 HTML 无法还原配置,所以问题不是 MVVM 能否直出,而是在于直出后的片段能否还原原来的配置。下面是一个简单的例子:

    1
    2
    <sapn>Hello {name}!</span>
     

    上面这段 HTML 配置和数据在一起,直出后会变成:

    1
    2
    <span>Hello world!</span>
     

    这时候当我们失去了 name 的值改变的时候会导致页面渲染这个细节。当然,如果为了实现 MVVM 直出我们可能有另外的方法来解决,例如直出结果变成这样:

    1
    2
    <span>Hello <span q-text="name">world</span>!</span>
     

    这时候我们是可以把丢失的信息找回来的,当然结构可能和我们想象的有些差别。当然还有其他问题,例如直出 HTML 不一定能反向还原数据,由于篇幅问题,这里不展开讨论。

    React 如何直出?

    2

    如图:

    • React 的虚拟 DOM 的生成是可以在任何支持 Javascript 的环境生成的,所以可以在 NodeJS 或 Iojs 环境生成
    • 虚拟 DOM 可以直接转成 String
    • 然后插入到 html 文件中输出给浏览器便可

    具体例子可以参考,https://github.com/DavidWells/isomorphic-react-example/,下面是其渲染路由的写法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <span class="comment">// https://github.com/DavidWells/isomorphic-react-example/blob/master/app/routes/coreRoutes.js</span>
     
    <span class="keyword">var</span> React = <span class="keyword">require</span>(<span class="string">'react/addons'</span>);
    <span class="keyword">var</span> ReactApp = React.createFactory(<span class="keyword">require</span>(<span class="string">'../components/ReactApp'</span>).ReactApp);
     
    module.exports = <span class="keyword">function</span>(app) {
     
        app.get(<span class="string">'/'</span>, <span class="keyword">function</span>(req, res){
            <span class="comment">// React.renderToString takes your component</span>
            <span class="comment">// and generates the markup</span>
            <span class="keyword">var</span> reactHtml = React.renderToString(ReactApp({}));
            <span class="comment">// Output html rendered by react</span>
            <span class="comment">// console.log(myAppHtml);</span>
            res.render(<span class="string">'index.ejs'</span>, {reactOutput: reactHtml});
        });
     
    };
     

    OK,我们现在知道如何利用 React 实现直出,以及如何前后端代码复用。

    但还有下面几个问题有待解决:

    • 如何渲染文字节点,每个虚拟 DOM 节点是需要对应实际的节点,但无法通过 html 文件生成相邻的 Text Node,例如下面例子应当如何渲染:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    React.createClass({
        render: <span class="keyword">function</span> () {
            <span class="keyword">return</span> (
                <p>
                    Hello {name}!          
                </p>
            );
        }
    })
     

    • 如何避免直出的页面被 React 重新渲染一遍?或者直出的页面和前端的数据是不对应的怎么办?

    相邻的 Text Node,想多了相邻的 span 而已

    1

    通过一个简单的例子,我们可以发现,实际上 React 根本没用 Text Node,而是使用 span 来代替 Text Node,这样就可以实现虚拟 DOM 和直出 DOM 的一一映射关系。

    重复渲染?没门

    刚刚的例子,如果我们通过 React.renderToString 拿到<Test /> 可以发现是:

    1
    2
    <p data-reactid=".0" data-react-checksum="-793171045"><span data-reactid=".0.0">Hello </span><span data-reactid=".0.1">world</span><span data-reactid=".0.2">!</span></p>
     

    我们可以发现一个有趣的属性 data-react-checksum,这是啥?实际上这是上面这段 HTML 片段的 adler32 算法值。实际上调用 React.render(<MyComponent />, container); 时候做了下面一些事情:

    • 看看 container 是否为空,不为空则认为有可能是直出了结果。
    • 接下来第一个元素是否有 data-react-checksum 属性,如果有则通过 React.renderToString 拿到前端的,通过 adler32 算法得到的值和 data-react-checksum 对比,如果一致则表示,无需渲染,否则重新渲染,下面是 adler32 算法实现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <span class="keyword">var</span> MOD = <span class="number">65521</span>;
     
    <span class="comment">// This is a clean-room implementation of adler32 designed for detecting</span>
    <span class="comment">// if markup is not what we expect it to be. It does not need to be</span>
    <span class="comment">// cryptographically strong, only reasonably good at detecting if markup</span>
    <span class="comment">// generated on the server is different than that on the client.</span>
    <span class="keyword">function</span> adler32(data) {
      <span class="keyword">var</span> a = <span class="number">1</span>;
      <span class="keyword">var</span> b = <span class="number">0</span>;
      <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i < data.length; i++) {
        a = (a + data.charCodeAt(i)) % MOD;
        b = (b + a) % MOD;
      }
      <span class="keyword">return</span> a | (b << <span class="number">16</span>);
    }
     

    • 如果需要重新渲染,先通过下面简单的差异算法找到差异在哪里,打印出错误:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <span class="comment">/**
    * Finds the index of the first character
    * that's not common between the two given strings.
    *
    *<span class="phpdoc"> @return</span> {number} the index of the character where the strings diverge
    */</span>
    <span class="keyword">function</span> firstDifferenceIndex(string1, string2) {
      <span class="keyword">var</span> minLen = Math.min(string1.length, string2.length);
      <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i < minLen; i++) {
        <span class="keyword">if</span> (string1.charAt(i) !== string2.charAt(i)) {
          <span class="keyword">return</span> i;
        }
      }
      <span class="keyword">return</span> string1.length === string2.length ? -<span class="number">1</span> : minLen;
    }
     

    下面是首屏渲染时的主要逻辑,可以发现 React 对首屏实际上也是通过 innerHTML 来渲染的:

    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
    _mountImageIntoNode: <span class="keyword">function</span>(markup, container, shouldReuseMarkup) {
        (<span class="string">"production"</span> !== process.env.NODE_ENV ? invariant(
          container && (
            (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE)
          ),
          <span class="string">'mountComponentIntoNode(...): Target container is not valid.'</span>
        ) : invariant(container && (
          (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE)
        )));
     
        <span class="keyword">if</span> (shouldReuseMarkup) {
          <span class="keyword">var</span> rootElement = getReactRootElementInContainer(container);
          <span class="keyword">if</span> (ReactMarkupChecksum.canReuseMarkup(markup, rootElement)) {
            <span class="keyword">return</span>;
          } <span class="keyword">else</span> {
            <span class="keyword">var</span> checksum = rootElement.getAttribute(
              ReactMarkupChecksum.CHECKSUM_ATTR_NAME
            );
            rootElement.removeAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME);
     
            <span class="keyword">var</span> rootMarkup = rootElement.outerHTML;
            rootElement.setAttribute(
              ReactMarkupChecksum.CHECKSUM_ATTR_NAME,
              checksum
            );
     
            <span class="keyword">var</span> diffIndex = firstDifferenceIndex(markup, rootMarkup);
            <span class="keyword">var</span> difference = <span class="string">' (client) '</span> +
              markup.substring(diffIndex - <span class="number">20</span>, diffIndex + <span class="number">20</span>) +
              <span class="string">'n (server) '</span> + rootMarkup.substring(diffIndex - <span class="number">20</span>, diffIndex + <span class="number">20</span>);
     
            (<span class="string">"production"</span> !== process.env.NODE_ENV ? invariant(
              container.nodeType !== DOC_NODE_TYPE,
              <span class="string">'You're trying to render a component to the document using '</span> +
              <span class="string">'server rendering but the checksum was invalid. This usually '</span> +
              <span class="string">'means you rendered a different component type or props on '</span> +
              <span class="string">'the client from the one on the server, or your render() '</span> +
              <span class="string">'methods are impure. React cannot handle this case due to '</span> +
              <span class="string">'cross-browser quirks by rendering at the document root. You '</span> +
              <span class="string">'should look for environment dependent code in your components '</span> +
              <span class="string">'and ensure the props are the same client and server side:n%s'</span>,
              difference
            ) : invariant(container.nodeType !== DOC_NODE_TYPE));
     
            <span class="keyword">if</span> (<span class="string">"production"</span> !== process.env.NODE_ENV) {
              (<span class="string">"production"</span> !== process.env.NODE_ENV ? warning(
                <span class="keyword">false</span>,
                <span class="string">'React attempted to reuse markup in a container but the '</span> +
                <span class="string">'checksum was invalid. This generally means that you are '</span> +
                <span class="string">'using server rendering and the markup generated on the '</span> +
                <span class="string">'server was not what the client was expecting. React injected '</span> +
                <span class="string">'new markup to compensate which works but you have lost many '</span> +
                <span class="string">'of the benefits of server rendering. Instead, figure out '</span> +
                <span class="string">'why the markup being generated is different on the client '</span> +
                <span class="string">'or server:n%s'</span>,
                difference
              ) : <span class="keyword">null</span>);
            }
          }
        }
     
        (<span class="string">"production"</span> !== process.env.NODE_ENV ? invariant(
          container.nodeType !== DOC_NODE_TYPE,
          <span class="string">'You're trying to render a component to the document but '</span> +
            <span class="string">'you didn't use server rendering. We can't do this '</span> +
            <span class="string">'without using server rendering due to cross-browser quirks. '</span> +
            <span class="string">'See React.renderToString() for server rendering.'</span>
        ) : invariant(container.nodeType !== DOC_NODE_TYPE));
     
        setInnerHTML(container, markup);
      }
     

    最后

    尝试一下下面的代码,想想 React 为啥认为这是错误的?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <span class="keyword">var</span> Test = React.createClass({
      getInitialState: <span class="keyword">function</span>() {
        <span class="keyword">return</span> {name: <span class="string">'world'</span>};
      },
      render: <span class="keyword">function</span>() {
        <span class="keyword">return</span> (
            <p>Hello</p>
            <p>
                Hello {<span class="keyword">this</span>.state.name}!
            </p>
        );
      }
    });
     
    React.render(
      <Test />,
      document.getElementById(<span class="string">'content'</span>)
    );
     
     

    继续阅读

  • TAT.tennylv 网页性能之 HTML,CSS,JavaScript
    In Web 前端优化,Web开发 on 2015年05月04日 by TAT.tennylv view: 10,457
    27

    前言

    html css javascript 可以算是前端必须掌握的东西了,但是我们的浏览器是怎样解析这些东西的呢 我们如何处理 html css javascript 这些东西来让我们的网页更加合理,在我这里做了一些实验,总结起来给大家看看。

    继续阅读

  • TAT.svenzeng 新书《JavaScript 设计模式与开发实践》即将出版
    In Web开发,作品 on 2015年04月30日 by TAT.svenzeng view: 6,088
    18

    HI

    经过 2 年准备,7 个月写作,8 个月修改,《JavaScript 设计模式与开发实践》即将出版(5 月 20 号左右)。

    预售地址将于 51 假期过后放出,感兴趣的同学可以关注。:)

    封面

     

    继续阅读

  • TAT.heyli koa + socket.io 制作简易聊天室
    In Web开发 on 2015年04月29日 by TAT.heyli view: 10,203
    1

    前言

     

    上期,本菜在 《前端抢后端饭碗 — Node.js + Socket.io 制作简易聊天室》一文中谈到如何用 node.js 中的 express 框架。如要阅读此文,请先阅读前文。

     

    虽然时至今日, express 框架依然是时下 node.js 网页开发的主流,但后起之秀 koa 大有赶超之势。他融合了 ES6 的一些新特性,列如 generator, promise 等。利用这些新特性能很好地解决传统 javascript 中的多层回调噩梦。

     

    我们 AlloyTeam 旗下iPresst会在 5 月底 6 月初的版本中发布用 koa 重构的版本,敬请期待!

     

    继续阅读

  • RosinVSJSConsole
    In Web开发 on 2015年04月29日 by TAT.helondeng view: 765
    0

    Rosin 是一个 Fiddler 插件,协助开发者进行移动端页面开发调试。

    特性
    • 可配置的页面匹配规则
    • 拦截 console
    • 日志内容的存储,展示,过滤
    • 脚本运行错误捕获
    原理
    • 首先在 fiddler 里面配置了匹配规则
    • 访问的页面进过 fiddler 之后,匹配规则会生效,如命中,则在返回的内容中注入脚本。
    • 脚本重写了 console 的各种方式(也监听了 onerror 事件)
    • 将 console 打出的各种消息 push 到消息队列
    • 队列达到阈值或者间隔的时间到,就将消息通过 xhr 发送到 http://__rosin__.qq.com
    • rosin 插件在 fiddler 中捕获上面的请求(并且隐藏了,所以看不到这个请求),将请求的 body 部分显示到面板上面
    • 将 log 存储到本地 D:Program Files (x86)Fiddler2ScriptsRosinLog

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
                add: <span class="keyword">function</span>() {
                <span class="keyword">Array</span>.prototype.push.apply(<span class="keyword">this</span>._queueArr, arguments);
                <span class="comment">// 定时发送消息</span>
                clock.start();
     
                <span class="comment">//队列达到阈值就触发上传</span>
                <span class="keyword">if</span> (<span class="keyword">this</span>._queueArr.length >= THRESHOLD) {
                    <span class="keyword">this</span>._post(<span class="keyword">this</span>._queueArr.splice(<span class="number">0</span>, <span class="keyword">this</span>._queueArr.length));
                    <span class="keyword">return</span>;
                }
            }
     

    Log 格式:

    log

    JSConsole

    JSConsole 是一个 JS 命令行调试工具。

    如何使用
    • 在 http://jsconsole.com/中输入:listen 创建一个 session(主要是生成一个 GUID)
    • 在页面中引入脚本

    1
    2
        <script src="http://jsconsole.com/remote.js?FAE031CD-74A0-46D3-AE36-757BAB262BEA"></script>
     

    原理
    • 引入的 remote.js 脚本创建一个隐藏的 iframe,Url 指向了 http://jsconsole.com/remote.html,并且把上面的 GUID 带上
    • 重写 console 中的方法,这里的问题是:如何把消息 push 到 jsconsole.com?
    • 页面调用 console 等方法时,实际通过 postMessage 是向 iframe 发送了一条消息。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
            log: <span class="keyword">function</span> () {
             <span class="keyword">var</span> argsObj = stringify(arguments.length == <span class="number">1</span> ?
                      arguments[<span class="number">0</span>] : [].slice.call(arguments, <span class="number">0</span>));
            ar response = [];
            [].<span class="keyword">forEach</span>.call(arguments, <span class="keyword">function</span> (args) {
                response.push(stringify(args, <span class="keyword">true</span>));
            });
     
            <span class="keyword">var</span> msg = JSON.stringify({ response: response,
                  cmd: <span class="string">'remote console.log'</span>, type: msgType });
     
            <span class="keyword">if</span> (remoteWindow) {
            remoteWindow.postMessage(msg, origin);
            } <span class="keyword">else</span> {
                queue.push(msg);
            }    
            msgType = <span class="string">''</span>;
            }
     

    • iframe 中内嵌的页面收到消息后,通过 EventSource 向 server 发送信息内容(类似于 socket)
    • 日志显示在 jsconsole.com 上面

    继续阅读

  • TAT.dorsywang 详解 NodeJs 的 VM 模块
    In Web开发 on 2015年04月29日 by TAT.dorsywang view: 12,043
    3

    什么是 VM?

    VM 模块是 NodeJS 里面的核心模块,支撑了 require 方法和 NodeJS 的运行机制,我们有些时候可能也要用到 VM 模板来做一些特殊的事情。
    通过 VM,JS 可以被编译后立即执行或者编译保存下来稍后执行(JavaScript code can be compiled and run immediately or compiled, saved, and run later.)
    VM 模块包含了三个常用的方法,用于创建独立运行的沙箱体制,如下三个方法

    继续阅读

  • TAT.dnt 为 React 扩展 jsReady
    In Web开发 on 2015年04月29日 by TAT.dnt view: 2,105
    2

    写在前面

    因为用 React 就会需要写jsx。
    React 会将 jsx 编译成 js。然后 append 到 head 当中。从 fiddler 的请求和 JSXTransformer 源码来看,当在页面使用下面的 html 时候:

    1
    <script type="text/jsx"  src="js/react_test.js"></script>

    会发送两次请求 react_test.js 文件,一次是 JSXTransformer 发送的,一次是浏览器识别 script 标签自动发送的。
    上面的 react_test.js 里面全是jsx语法,和 javascript 有点像,如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    var Timer = React.createClass({
        getInitialState: function() {
            return {secondsElapsed: 0};
        },
        tick: function() {
            this.setState({secondsElapsed: this.state.secondsElapsed + 1});
        },
        componentDidMount: function() {
            this.interval = setInterval(this.tick, 1000);
        },
        componentWillUnmount: function() {
            clearInterval(this.interval);
        },
        render: function() {
            return (
                <div>Seconds Elapsed: {this.state.secondsElapsed}</div>
        );
    }
    });

    继续阅读

上页 1 ...29 30 31 32 33 34 35 36 37 38 ...61 下页
公众号:AlloyTeam
扫码关注
公众号:AlloyTeam
合作伙伴
HTML5梦工场
腾讯云
Coding
兄弟团队
  • 腾讯 ISUX
  • 腾讯 CDC
  • 腾讯游戏 TGideas
  • 百度前端 EFE
  • 百度前端 FEX
  • 淘宝前端团队 FED
友情链接
  • 印记中文
  • W3CTech
  • 前端观察
  • W3C Plus
  • Web 前端开发
  • V2EX
  • 蓝色理想
  • 云开发 CloudBase
  • HTML5中文学习网
  • 爱思资源网
  • 牛大拿_前端设计导航
  • 吕小鸣前端博客
  • 腾讯大学


Copyright ©  2011-2025 AlloyTeam. All Rights Reserved. Powered By WordPress
粤ICP备15071938号-2