├── .bundle └── install.log ├── .gitignore ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README.md ├── Rakefile ├── build.rb ├── build.sh ├── build ├── examples │ └── jquery_plugin │ │ ├── first │ │ └── jQuery.tab.html │ │ ├── lib │ │ └── jquery-1.10.2.min.js │ │ ├── plugin_first │ │ ├── jQuery.tab.html │ │ ├── jQuery.tab_more.html │ │ ├── tab.css │ │ └── tab.js │ │ ├── plugin_four │ │ ├── jQuery.tab.html │ │ ├── jQuery.tab_more.html │ │ ├── tab.css │ │ └── tab.js │ │ ├── plugin_grunt │ │ ├── .gitignore │ │ ├── .jshintrc │ │ ├── CONTRIBUTING.md │ │ ├── Gruntfile.js │ │ ├── LICENSE-MIT │ │ ├── README.md │ │ ├── dist │ │ │ ├── i5ting-mobile.js │ │ │ └── i5ting-mobile.min.js │ │ ├── i5ting-mobile.jquery.json │ │ ├── libs │ │ │ ├── jquery-loader.js │ │ │ ├── jquery │ │ │ │ └── jquery.js │ │ │ └── qunit │ │ │ │ ├── qunit.css │ │ │ │ └── qunit.js │ │ ├── package.json │ │ ├── src │ │ │ ├── .jshintrc │ │ │ └── i5ting-mobile.js │ │ └── test │ │ │ ├── .jshintrc │ │ │ ├── i5ting-mobile.html │ │ │ └── i5ting-mobile_test.js │ │ ├── plugin_second │ │ ├── jQuery.tab.html │ │ ├── jQuery.tab_more.html │ │ ├── tab.css │ │ └── tab.js │ │ ├── plugin_three │ │ ├── jQuery.tab.html │ │ ├── jQuery.tab_more.html │ │ ├── tab.css │ │ └── tab.js │ │ └── second │ │ ├── jQuery.tab.html │ │ ├── jQuery.tab_more.html │ │ ├── tab.css │ │ └── tab.js ├── images │ ├── jquery_plugin │ │ └── debug_with_callback.png │ └── tab.gif ├── jquery.plugin.html ├── js │ ├── jquery-1.10.2.min.js │ ├── jquery.ztree.all-3.5.js │ ├── jquery.ztree.all-3.5.min.js │ ├── jquery.ztree_toc.js │ └── jquery.ztree_toc.min.js └── style │ ├── Clearness Dark.css │ ├── Clearness.css │ ├── GitHub.css │ ├── GitHub2.css │ ├── demo.css │ ├── github-bf51422f4bb36427d391e4b75a1daa083c2d840e.css │ ├── github2-d731afd4f624c99a4b19ad69f3083cd6d02b81d5.css │ ├── makedownpad.css │ └── zTreeStyle │ ├── img │ ├── diy │ │ ├── 1_close.png │ │ ├── 1_open.png │ │ ├── 2.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ ├── 6.png │ │ ├── 7.png │ │ ├── 8.png │ │ └── 9.png │ ├── line_conn.gif │ ├── loading.gif │ ├── zTreeStandard.gif │ └── zTreeStandard.png │ └── zTreeStyle.css ├── examples └── jquery_plugin │ ├── first │ └── jQuery.tab.html │ ├── lib │ └── jquery-1.10.2.min.js │ ├── plugin_first │ ├── jQuery.tab.html │ ├── jQuery.tab_more.html │ ├── tab.css │ └── tab.js │ ├── plugin_four │ ├── jQuery.tab.html │ ├── jQuery.tab_more.html │ ├── tab.css │ └── tab.js │ ├── plugin_grunt │ ├── .gitignore │ ├── .jshintrc │ ├── CONTRIBUTING.md │ ├── Gruntfile.js │ ├── LICENSE-MIT │ ├── README.md │ ├── dist │ │ ├── i5ting-mobile.js │ │ └── i5ting-mobile.min.js │ ├── i5ting-mobile.jquery.json │ ├── libs │ │ ├── jquery-loader.js │ │ ├── jquery │ │ │ └── jquery.js │ │ └── qunit │ │ │ ├── qunit.css │ │ │ └── qunit.js │ ├── package.json │ ├── src │ │ ├── .jshintrc │ │ └── i5ting-mobile.js │ └── test │ │ ├── .jshintrc │ │ ├── i5ting-mobile.html │ │ └── i5ting-mobile_test.js │ ├── plugin_second │ ├── jQuery.tab.html │ ├── jQuery.tab_more.html │ ├── tab.css │ └── tab.js │ ├── plugin_three │ ├── jQuery.tab.html │ ├── jQuery.tab_more.html │ ├── tab.css │ └── tab.js │ └── second │ ├── jQuery.tab.html │ ├── jQuery.tab_more.html │ ├── tab.css │ └── tab.js └── src ├── .toc └── template.html ├── images ├── jquery_plugin │ └── debug_with_callback.png └── tab.gif └── jquery.plugin.md /.bundle/install.log: -------------------------------------------------------------------------------- 1 | # Logfile created on 2014-02-13 07:44:25 +0800 by logger.rb/44203 2 | I, [2014-02-13T07:44:25.976753 #11452] INFO -- : 0: posix-spawn (0.3.8) from /Users/sang/.rvm/gems/ruby-2.1.0@rails4.0/specifications/posix-spawn-0.3.8.gemspec 3 | I, [2014-02-13T07:44:25.977449 #11452] INFO -- : 0: yajl-ruby (1.1.0) from /Users/sang/.rvm/gems/ruby-2.1.0@rails4.0/specifications/yajl-ruby-1.1.0.gemspec 4 | I, [2014-02-13T07:44:25.983784 #11452] INFO -- : 0: pygments.rb (0.5.4) from /Users/sang/.rvm/gems/ruby-2.1.0@rails4.0/specifications/pygments.rb-0.5.4.gemspec 5 | I, [2014-02-13T07:44:25.984411 #11452] INFO -- : 0: redcarpet (3.0.0) from /Users/sang/.rvm/gems/ruby-2.1.0@rails4.0/specifications/redcarpet-3.0.0.gemspec 6 | I, [2014-02-13T07:44:25.984745 #11452] INFO -- : 0: bundler (1.5.1) from /Users/sang/.rvm/gems/ruby-2.1.0@global/specifications/bundler-1.5.1.gemspec 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build.zip 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | gem 'redcarpet' 2 | gem 'pygments.rb' 3 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | specs: 3 | posix-spawn (0.3.8) 4 | pygments.rb (0.5.4) 5 | posix-spawn (~> 0.3.6) 6 | yajl-ruby (~> 1.1.0) 7 | redcarpet (3.0.0) 8 | yajl-ruby (1.1.0) 9 | 10 | PLATFORMS 11 | ruby 12 | 13 | DEPENDENCIES 14 | pygments.rb 15 | redcarpet 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # How-to-write-jQuery-plugin ? 2 | 3 | 4 | 如何编写jQuery插件,以及代码重构过程 5 | 6 | 7 | ## 目录 8 | 9 | - src 源文件 10 | - examples 示例 11 | - build 指src里md文件build成pdf和epub之类格式的输出物的目录 12 | 13 | ## 教程 14 | 15 | - src/jquery.plugin.md 16 | 17 | 18 | 19 | ## 编译 20 | 21 | 22 | bundle install 23 | rake build 24 | 25 | 26 | then open build/jquery.plugin.html 27 | 28 | 29 | ## Contributing 30 | 31 | 1. Fork it 32 | 2. Create your feature branch (`git checkout -b my-new-feature`) 33 | 3. Commit your changes (`git commit -am 'Add some feature'`) 34 | 4. Push to the branch (`git push origin my-new-feature`) 35 | 5. Create new Pull Request 36 | 37 | 38 | ## 版本历史 39 | 40 | - v0.1.0 初始化版本 41 | 42 | 43 | ## 作者 44 | 45 | - alfred sang(shiren1118@126.com) 46 | 47 | 48 | ## License 49 | 50 | this project is released under the [MIT License](http://www.opensource.org/licenses/MIT). 51 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # rakefile 2 | 3 | desc 'test open' 4 | task :build do 5 | sh './build.sh' 6 | end 7 | 8 | task :push do 9 | sh "./build.sh && git pull && git commit -am 'build' && git push" 10 | end 11 | -------------------------------------------------------------------------------- /build.rb: -------------------------------------------------------------------------------- 1 | # mark to html 2 | 3 | require 'redcarpet' 4 | require 'pygments' 5 | 6 | require 'redcarpet' 7 | require 'rexml/document' 8 | module Redcarpet::Render 9 | class Custom < Base 10 | def header(title, level) 11 | @headers ||= [] 12 | 13 | title_elements = REXML::Document.new(title) 14 | flattened_title = title_elements.inject('') do |flattened, element| 15 | flattened += if element.respond_to?(:text) 16 | element.text 17 | else 18 | element.to_s 19 | end 20 | end 21 | permalink = flattened_title.downcase.gsub(/[^a-z\s]/, '').gsub(/\W+/, "-") 22 | 23 | # for extra credit: implement this as its own method 24 | if @headers.include?(permalink) 25 | permalink += "_1" 26 | # my brain hurts 27 | loop do 28 | break if !@headers.include?(permalink) 29 | # generate titles like foo-bar_1, foo-bar_2 30 | permalink.gsub!(/\_(\d+)$/, "_#{$1.to_i + 1}") 31 | end 32 | end 33 | @headers << permalink 34 | %(\n#{title}\n) 35 | end 36 | end 37 | end 38 | 39 | class HTMLwithPygments < Redcarpet::Render::HTML 40 | def doc_header() 41 | "" 42 | end 43 | 44 | def block_code(code, language) 45 | Pygments.highlight(code, :lexer => language, :options => {:encoding => 'utf-8'}) 46 | end 47 | end 48 | 49 | def build_with_dir(destiny_dir) 50 | Dir.foreach(destiny_dir) do |ff| 51 | # puts ff 52 | unless /^\./ =~ ff ||/^images/ =~ ff ||/^css/ =~ ff 53 | # get markdown text 54 | text = IO.read(destiny_dir + '/' + ff) 55 | 56 | # options = [:fenced_code,:generate_toc,:hard_wrap,:no_intraemphasis,:strikethrough,:gh_blockcode,:autolink,:xhtml,:tables] 57 | 58 | # convert to html 59 | markdown = Redcarpet::Markdown.new(HTMLwithPygments,:gh_blockcode=>true,:no_intra_emphasis=>true,:filter_html => true,:hard_wrap => true,:autolink => true, :space_after_headers => true,:fenced_code_blocks => true) 60 | parse_markdown = markdown.render(text) 61 | # parse_markdown = syntax_highlighter(parse_markdown) 62 | 63 | css_link = '' 64 | if destiny_dir.to_s.index('/') 65 | css_link = %Q{ 66 | 67 | 68 | } 69 | else 70 | css_link = %Q{ 71 | 72 | 73 | } 74 | end 75 | 76 | t = %Q{ 77 | 78 | 79 | 80 | #{ff.gsub('.md','')} 81 | #{css_link} 82 | 132 | 133 | 150 | 151 | 152 |
153 |
154 | 157 |
158 |
159 |
160 | #{parse_markdown} 161 |
162 |
163 |
164 | 165 | 166 | 167 | 177 | 178 | 179 | } 180 | 181 | if destiny_dir.to_s.index('/') 182 | p 'build src/' + destiny_dir.to_s.split('/')[1] + '/' + ff.gsub('.md','') + '.html' 183 | build_dir = 'build/' + destiny_dir.to_s.split('/')[1] + '/' 184 | IO.write(build_dir + ff.gsub('.md','') + '.html',t) # => 10 185 | else 186 | p 'build src/' + ff.gsub('.md','') + '.html' 187 | build_dir = 'build/' 188 | # write to html file 189 | IO.write(build_dir + ff.gsub('.md','') + '.html',t) # => 10 190 | end 191 | 192 | end 193 | end 194 | end 195 | 196 | build_with_dir('src') 197 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | rm -f build/*.html && cp -rf src/images build && cp -rf examples build/ 2 | 3 | ruby build.rb 4 | 5 | open build/jquery.plugin.html 6 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/first/jQuery.tab.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 34 | 35 | 36 |
37 | 42 | 43 |
我是第一个内容
44 |
我是第二个内容
45 |
我是第三个内容
46 |
47 | 48 | 57 | 58 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_first/jQuery.tab.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | second tab example 6 | 7 | 8 | 9 |
10 |
11 | 16 |
17 |
18 |
19 | 我是第一个内容 20 |
21 |
22 | 我是第二个内容 23 |
24 |
25 | 我是第三个内容 26 |
27 |
28 |
29 | 30 | 31 | 36 | 37 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_first/jQuery.tab_more.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | second tab example 6 | 7 | 8 | 9 |
10 |
11 | 16 |
17 |
18 |
19 | 我是第一个内容 20 |
21 |
22 | 我是第二个内容 23 |
24 |
25 | 我是第三个内容 26 |
27 |
28 |
29 | 30 |
31 |
32 | 37 |
38 |
39 |
40 | 我是第一个内容 41 |
42 |
43 | 我是第二个内容 44 |
45 |
46 | 我是第三个内容 47 |
48 |
49 |
50 | 51 | 52 | 53 | 58 | 59 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_first/tab.css: -------------------------------------------------------------------------------- 1 | *{ 2 | margin: 0; 3 | padding: 0; 4 | list-style: none; 5 | } 6 | #tab { 7 | width: 600px; 8 | height: 300px; 9 | border: 1px solid #ccc; 10 | } 11 | .tab_content > div{ 12 | display: none; 13 | } 14 | .tab_content .active{ 15 | display:block; 16 | } 17 | .tab_header ul{ 18 | height: 50px; 19 | line-height: 50px; 20 | border-bottom: 1px solid #ccc; 21 | } 22 | .tab_header li { 23 | float: left; 24 | width: 200px; 25 | text-align: center;; 26 | } 27 | .tab_header li.active{ 28 | background: #ccc; 29 | } -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_first/tab.js: -------------------------------------------------------------------------------- 1 | ;(function($) { 2 | 3 | $.fn.tab = function(options) { 4 | // 将defaults 和 options 参数合并到{} 5 | var opts = $.extend({},$.fn.tab.defaults,options); 6 | 7 | return this.each(function() { 8 | var obj = $(this); 9 | 10 | $(obj).find('.tab_header li').on('mouseover', function (){ 11 | $(obj).find('.tab_header li').removeClass('active'); 12 | $(this).addClass('active'); 13 | 14 | $(obj).find('.tab_content div').hide(); 15 | $(obj).find('.tab_content div').eq($(this).index()).show(); 16 | }) 17 | }); 18 | // each end 19 | } 20 | 21 | //定义默认 22 | $.fn.tab.defaults = { 23 | 24 | }; 25 | 26 | })(jQuery); -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_four/jQuery.tab.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | second tab example 6 | 7 | 8 | 9 |
10 |
11 | 16 |
17 |
18 |
19 | 我是第一个内容 20 |
21 |
22 | 我是第二个内容 23 |
24 |
25 | 我是第三个内容 26 |
27 |
28 |
29 | 30 | 31 | 36 | 37 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_four/jQuery.tab_more.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | second tab example 6 | 7 | 8 | 9 |
10 |
11 | 16 |
17 |
18 |
19 | 我是第一个内容 20 |
21 |
22 | 我是第二个内容 23 |
24 |
25 | 我是第三个内容 26 |
27 |
28 |
29 | 30 |
31 |
32 | 37 |
38 |
39 |
40 | 我是第一个内容 41 |
42 |
43 | 我是第二个内容 44 |
45 |
46 | 我是第三个内容 47 |
48 |
49 |
50 | 51 | 52 | 53 | 63 | 64 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_four/tab.css: -------------------------------------------------------------------------------- 1 | *{ 2 | margin: 0; 3 | padding: 0; 4 | list-style: none; 5 | } 6 | #tab { 7 | width: 600px; 8 | height: 300px; 9 | border: 1px solid #ccc; 10 | } 11 | .tab_content > div{ 12 | display: none; 13 | } 14 | .tab_content .active{ 15 | display:block; 16 | } 17 | .tab_header ul{ 18 | height: 50px; 19 | line-height: 50px; 20 | border-bottom: 1px solid #ccc; 21 | } 22 | .tab_header li { 23 | float: left; 24 | width: 200px; 25 | text-align: center;; 26 | } 27 | .tab_header li.active{ 28 | background: #ccc; 29 | } -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_four/tab.js: -------------------------------------------------------------------------------- 1 | ;(function($) { 2 | 3 | /** 4 | * 公共函数: 初始化tab出发事件 5 | */ 6 | function init_tab_trigger_event(container,opts) { 7 | $(container).find('.tab_header li').on(opts.trigger_event_type, function () { 8 | $(container).find('.tab_header li').removeClass('active'); 9 | $(this).addClass('active'); 10 | 11 | $(container).find('.tab_content div').hide(); 12 | $(container).find('.tab_content div').eq($(this).index()).show(); 13 | 14 | opts.change($(this).index()); 15 | }) 16 | } 17 | 18 | /** 19 | * 公共函数: 初始化tab出发事件 20 | */ 21 | function init_with_config(opts) { 22 | // 调用私有函数 23 | _init_aaa_with_config(opts); 24 | 25 | // 调用私有函数 26 | _init_bbb_with_config(opts); 27 | 28 | // 调用私有函数 29 | _init_ccc_with_config(opts); 30 | } 31 | 32 | /** 33 | * 私有函数 34 | */ 35 | function _init_aaa_with_config(opts) { 36 | 37 | } 38 | 39 | function _init_bbb_with_config(opts) { 40 | 41 | } 42 | 43 | function _init_ccc_with_config(opts) { 44 | 45 | } 46 | 47 | $.fn.tab = function(options) { 48 | // 将defaults 和 options 参数合并到{} 49 | var opts = $.extend({},$.fn.tab.defaults,options); 50 | 51 | return this.each(function() { 52 | var obj = $(this); 53 | 54 | // 根据配置进行初始化 55 | init_with_config(opts); 56 | 57 | // 初始化tab出发事件 58 | init_tab_trigger_event(obj,opts); 59 | }); 60 | // each end 61 | } 62 | 63 | //定义默认 64 | $.fn.tab.defaults = { 65 | trigger_event_type:'click', //mouseover | click 默认是click 66 | change: function(index) { 67 | console.log('current index = ' + index); 68 | } 69 | }; 70 | 71 | })(jQuery); -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_grunt/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_grunt/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "curly": true, 3 | "eqeqeq": true, 4 | "immed": true, 5 | "latedef": true, 6 | "newcap": true, 7 | "noarg": true, 8 | "sub": true, 9 | "undef": true, 10 | "unused": true, 11 | "boss": true, 12 | "eqnull": true, 13 | "node": true 14 | } 15 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_grunt/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ## Important notes 4 | Please don't edit files in the `dist` subdirectory as they are generated via Grunt. You'll find source code in the `src` subdirectory! 5 | 6 | ### Code style 7 | Regarding code style like indentation and whitespace, **follow the conventions you see used in the source already.** 8 | 9 | ### PhantomJS 10 | While Grunt can run the included unit tests via [PhantomJS](http://phantomjs.org/), this shouldn't be considered a substitute for the real thing. Please be sure to test the `test/*.html` unit test file(s) in _actual_ browsers. 11 | 12 | ## Modifying the code 13 | First, ensure that you have the latest [Node.js](http://nodejs.org/) and [npm](http://npmjs.org/) installed. 14 | 15 | Test that Grunt's CLI is installed by running `grunt --version`. If the command isn't found, run `npm install -g grunt-cli`. For more information about installing Grunt, see the [getting started guide](http://gruntjs.com/getting-started). 16 | 17 | 1. Fork and clone the repo. 18 | 1. Run `npm install` to install all dependencies (including Grunt). 19 | 1. Run `grunt` to grunt this project. 20 | 21 | Assuming that you don't see any red, you're ready to go. Just be sure to run `grunt` after making any changes, to ensure that nothing is broken. 22 | 23 | ## Submitting pull requests 24 | 25 | 1. Create a new branch, please don't work in your `master` branch directly. 26 | 1. Add failing tests for the change you want to make. Run `grunt` to see the tests fail. 27 | 1. Fix stuff. 28 | 1. Run `grunt` to see if the tests pass. Repeat steps 2-4 until done. 29 | 1. Open `test/*.html` unit test file(s) in actual browser to ensure tests pass everywhere. 30 | 1. Update the documentation to reflect any changes. 31 | 1. Push to your fork and submit a pull request. 32 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_grunt/Gruntfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(grunt) { 4 | 5 | // Project configuration. 6 | grunt.initConfig({ 7 | // Metadata. 8 | pkg: grunt.file.readJSON('i5ting-mobile.jquery.json'), 9 | banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' + 10 | '<%= grunt.template.today("yyyy-mm-dd") %>\n' + 11 | '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' + 12 | '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' + 13 | ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n', 14 | // Task configuration. 15 | clean: { 16 | files: ['dist'] 17 | }, 18 | concat: { 19 | options: { 20 | banner: '<%= banner %>', 21 | stripBanners: true 22 | }, 23 | dist: { 24 | src: ['src/<%= pkg.name %>.js'], 25 | dest: 'dist/<%= pkg.name %>.js' 26 | }, 27 | }, 28 | uglify: { 29 | options: { 30 | banner: '<%= banner %>' 31 | }, 32 | dist: { 33 | src: '<%= concat.dist.dest %>', 34 | dest: 'dist/<%= pkg.name %>.min.js' 35 | }, 36 | }, 37 | qunit: { 38 | files: ['test/**/*.html'] 39 | }, 40 | jshint: { 41 | gruntfile: { 42 | options: { 43 | jshintrc: '.jshintrc' 44 | }, 45 | src: 'Gruntfile.js' 46 | }, 47 | src: { 48 | options: { 49 | jshintrc: 'src/.jshintrc' 50 | }, 51 | src: ['src/**/*.js'] 52 | }, 53 | test: { 54 | options: { 55 | jshintrc: 'test/.jshintrc' 56 | }, 57 | src: ['test/**/*.js'] 58 | }, 59 | }, 60 | watch: { 61 | gruntfile: { 62 | files: '<%= jshint.gruntfile.src %>', 63 | tasks: ['jshint:gruntfile'] 64 | }, 65 | src: { 66 | files: '<%= jshint.src.src %>', 67 | tasks: ['jshint:src', 'qunit'] 68 | }, 69 | test: { 70 | files: '<%= jshint.test.src %>', 71 | tasks: ['jshint:test', 'qunit'] 72 | }, 73 | }, 74 | }); 75 | 76 | // These plugins provide necessary tasks. 77 | grunt.loadNpmTasks('grunt-contrib-clean'); 78 | grunt.loadNpmTasks('grunt-contrib-concat'); 79 | grunt.loadNpmTasks('grunt-contrib-uglify'); 80 | grunt.loadNpmTasks('grunt-contrib-qunit'); 81 | grunt.loadNpmTasks('grunt-contrib-jshint'); 82 | grunt.loadNpmTasks('grunt-contrib-watch'); 83 | 84 | // Default task. 85 | grunt.registerTask('default', ['jshint', 'qunit', 'clean', 'concat', 'uglify']); 86 | 87 | }; 88 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_grunt/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 i5ting 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_grunt/README.md: -------------------------------------------------------------------------------- 1 | # I5ting Mobile 2 | 3 | this is a test jq plugin 4 | 5 | ## Getting Started 6 | Download the [production version][min] or the [development version][max]. 7 | 8 | [min]: https://raw.github.com/i5ting/How-to-write-jQuery-plugin/master/dist/i5ting-mobile.min.js 9 | [max]: https://raw.github.com/i5ting/How-to-write-jQuery-plugin/master/dist/i5ting-mobile.js 10 | 11 | In your web page: 12 | 13 | ```html 14 | 15 | 16 | 21 | ``` 22 | 23 | ## Documentation 24 | _(Coming soon)_ 25 | 26 | ## Examples 27 | _(Coming soon)_ 28 | 29 | ## Release History 30 | _(Nothing yet)_ 31 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_grunt/dist/i5ting-mobile.js: -------------------------------------------------------------------------------- 1 | /*! I5ting Mobile - v0.1.0 - 2014-02-11 2 | * https://github.com/i5ting/How-to-write-jQuery-plugin 3 | * Copyright (c) 2014 i5ting; Licensed MIT */ 4 | (function($) { 5 | 6 | // Collection method. 7 | $.fn.awesome = function() { 8 | return this.each(function(i) { 9 | // Do something awesome to each selected element. 10 | $(this).html('awesome' + i); 11 | }); 12 | }; 13 | 14 | // Static method. 15 | $.awesome = function(options) { 16 | // Override default options with passed-in options. 17 | options = $.extend({}, $.awesome.options, options); 18 | // Return something awesome. 19 | return 'awesome' + options.punctuation; 20 | }; 21 | 22 | // Static method default options. 23 | $.awesome.options = { 24 | punctuation: '.' 25 | }; 26 | 27 | // Custom selector. 28 | $.expr[':'].awesome = function(elem) { 29 | // Is this element awesome? 30 | return $(elem).text().indexOf('awesome') !== -1; 31 | }; 32 | 33 | }(jQuery)); 34 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_grunt/dist/i5ting-mobile.min.js: -------------------------------------------------------------------------------- 1 | /*! I5ting Mobile - v0.1.0 - 2014-02-11 2 | * https://github.com/i5ting/How-to-write-jQuery-plugin 3 | * Copyright (c) 2014 i5ting; Licensed MIT */ 4 | !function(a){a.fn.awesome=function(){return this.each(function(b){a(this).html("awesome"+b)})},a.awesome=function(b){return b=a.extend({},a.awesome.options,b),"awesome"+b.punctuation},a.awesome.options={punctuation:"."},a.expr[":"].awesome=function(b){return-1!==a(b).text().indexOf("awesome")}}(jQuery); -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_grunt/i5ting-mobile.jquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "i5ting-mobile", 3 | "title": "I5ting Mobile", 4 | "description": "this is a test jq plugin", 5 | "version": "0.1.0", 6 | "homepage": "https://github.com/i5ting/How-to-write-jQuery-plugin", 7 | "author": { 8 | "name": "i5ting", 9 | "email": "i5ting@126.com" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git://github.com/i5ting/How-to-write-jQuery-plugin.git" 14 | }, 15 | "bugs": "https://github.com/i5ting/How-to-write-jQuery-plugin/issues", 16 | "licenses": [ 17 | { 18 | "type": "MIT", 19 | "url": "https://github.com/i5ting/How-to-write-jQuery-plugin/blob/master/LICENSE-MIT" 20 | } 21 | ], 22 | "dependencies": { 23 | "jquery": "*" 24 | }, 25 | "keywords": [] 26 | } -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_grunt/libs/jquery-loader.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | // Default to the local version. 3 | var path = '../libs/jquery/jquery.js'; 4 | // Get any jquery=___ param from the query string. 5 | var jqversion = location.search.match(/[?&]jquery=(.*?)(?=&|$)/); 6 | // If a version was specified, use that version from code.jquery.com. 7 | if (jqversion) { 8 | path = 'http://code.jquery.com/jquery-' + jqversion[1] + '.js'; 9 | } 10 | // This is the only time I'll ever use document.write, I promise! 11 | document.write(''); 12 | }()); 13 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_grunt/libs/qunit/qunit.css: -------------------------------------------------------------------------------- 1 | /** 2 | * QUnit v1.11.0 - A JavaScript Unit Testing Framework 3 | * 4 | * http://qunitjs.com 5 | * 6 | * Copyright 2012 jQuery Foundation and other contributors 7 | * Released under the MIT license. 8 | * http://jquery.org/license 9 | */ 10 | 11 | /** Font Family and Sizes */ 12 | 13 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { 14 | font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; 15 | } 16 | 17 | #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } 18 | #qunit-tests { font-size: smaller; } 19 | 20 | 21 | /** Resets */ 22 | 23 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter { 24 | margin: 0; 25 | padding: 0; 26 | } 27 | 28 | 29 | /** Header */ 30 | 31 | #qunit-header { 32 | padding: 0.5em 0 0.5em 1em; 33 | 34 | color: #8699a4; 35 | background-color: #0d3349; 36 | 37 | font-size: 1.5em; 38 | line-height: 1em; 39 | font-weight: normal; 40 | 41 | border-radius: 5px 5px 0 0; 42 | -moz-border-radius: 5px 5px 0 0; 43 | -webkit-border-top-right-radius: 5px; 44 | -webkit-border-top-left-radius: 5px; 45 | } 46 | 47 | #qunit-header a { 48 | text-decoration: none; 49 | color: #c2ccd1; 50 | } 51 | 52 | #qunit-header a:hover, 53 | #qunit-header a:focus { 54 | color: #fff; 55 | } 56 | 57 | #qunit-testrunner-toolbar label { 58 | display: inline-block; 59 | padding: 0 .5em 0 .1em; 60 | } 61 | 62 | #qunit-banner { 63 | height: 5px; 64 | } 65 | 66 | #qunit-testrunner-toolbar { 67 | padding: 0.5em 0 0.5em 2em; 68 | color: #5E740B; 69 | background-color: #eee; 70 | overflow: hidden; 71 | } 72 | 73 | #qunit-userAgent { 74 | padding: 0.5em 0 0.5em 2.5em; 75 | background-color: #2b81af; 76 | color: #fff; 77 | text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; 78 | } 79 | 80 | #qunit-modulefilter-container { 81 | float: right; 82 | } 83 | 84 | /** Tests: Pass/Fail */ 85 | 86 | #qunit-tests { 87 | list-style-position: inside; 88 | } 89 | 90 | #qunit-tests li { 91 | padding: 0.4em 0.5em 0.4em 2.5em; 92 | border-bottom: 1px solid #fff; 93 | list-style-position: inside; 94 | } 95 | 96 | #qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { 97 | display: none; 98 | } 99 | 100 | #qunit-tests li strong { 101 | cursor: pointer; 102 | } 103 | 104 | #qunit-tests li a { 105 | padding: 0.5em; 106 | color: #c2ccd1; 107 | text-decoration: none; 108 | } 109 | #qunit-tests li a:hover, 110 | #qunit-tests li a:focus { 111 | color: #000; 112 | } 113 | 114 | #qunit-tests li .runtime { 115 | float: right; 116 | font-size: smaller; 117 | } 118 | 119 | .qunit-assert-list { 120 | margin-top: 0.5em; 121 | padding: 0.5em; 122 | 123 | background-color: #fff; 124 | 125 | border-radius: 5px; 126 | -moz-border-radius: 5px; 127 | -webkit-border-radius: 5px; 128 | } 129 | 130 | .qunit-collapsed { 131 | display: none; 132 | } 133 | 134 | #qunit-tests table { 135 | border-collapse: collapse; 136 | margin-top: .2em; 137 | } 138 | 139 | #qunit-tests th { 140 | text-align: right; 141 | vertical-align: top; 142 | padding: 0 .5em 0 0; 143 | } 144 | 145 | #qunit-tests td { 146 | vertical-align: top; 147 | } 148 | 149 | #qunit-tests pre { 150 | margin: 0; 151 | white-space: pre-wrap; 152 | word-wrap: break-word; 153 | } 154 | 155 | #qunit-tests del { 156 | background-color: #e0f2be; 157 | color: #374e0c; 158 | text-decoration: none; 159 | } 160 | 161 | #qunit-tests ins { 162 | background-color: #ffcaca; 163 | color: #500; 164 | text-decoration: none; 165 | } 166 | 167 | /*** Test Counts */ 168 | 169 | #qunit-tests b.counts { color: black; } 170 | #qunit-tests b.passed { color: #5E740B; } 171 | #qunit-tests b.failed { color: #710909; } 172 | 173 | #qunit-tests li li { 174 | padding: 5px; 175 | background-color: #fff; 176 | border-bottom: none; 177 | list-style-position: inside; 178 | } 179 | 180 | /*** Passing Styles */ 181 | 182 | #qunit-tests li li.pass { 183 | color: #3c510c; 184 | background-color: #fff; 185 | border-left: 10px solid #C6E746; 186 | } 187 | 188 | #qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } 189 | #qunit-tests .pass .test-name { color: #366097; } 190 | 191 | #qunit-tests .pass .test-actual, 192 | #qunit-tests .pass .test-expected { color: #999999; } 193 | 194 | #qunit-banner.qunit-pass { background-color: #C6E746; } 195 | 196 | /*** Failing Styles */ 197 | 198 | #qunit-tests li li.fail { 199 | color: #710909; 200 | background-color: #fff; 201 | border-left: 10px solid #EE5757; 202 | white-space: pre; 203 | } 204 | 205 | #qunit-tests > li:last-child { 206 | border-radius: 0 0 5px 5px; 207 | -moz-border-radius: 0 0 5px 5px; 208 | -webkit-border-bottom-right-radius: 5px; 209 | -webkit-border-bottom-left-radius: 5px; 210 | } 211 | 212 | #qunit-tests .fail { color: #000000; background-color: #EE5757; } 213 | #qunit-tests .fail .test-name, 214 | #qunit-tests .fail .module-name { color: #000000; } 215 | 216 | #qunit-tests .fail .test-actual { color: #EE5757; } 217 | #qunit-tests .fail .test-expected { color: green; } 218 | 219 | #qunit-banner.qunit-fail { background-color: #EE5757; } 220 | 221 | 222 | /** Result */ 223 | 224 | #qunit-testresult { 225 | padding: 0.5em 0.5em 0.5em 2.5em; 226 | 227 | color: #2b81af; 228 | background-color: #D2E0E6; 229 | 230 | border-bottom: 1px solid white; 231 | } 232 | #qunit-testresult .module-name { 233 | font-weight: bold; 234 | } 235 | 236 | /** Fixture */ 237 | 238 | #qunit-fixture { 239 | position: absolute; 240 | top: -10000px; 241 | left: -10000px; 242 | width: 1000px; 243 | height: 1000px; 244 | } 245 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_grunt/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-plugin", 3 | "version": "0.0.0-ignored", 4 | "engines": { 5 | "node": ">= 0.8.0" 6 | }, 7 | "scripts": { 8 | "test": "grunt qunit" 9 | }, 10 | "devDependencies": { 11 | "grunt-contrib-jshint": "~0.6.0", 12 | "grunt-contrib-qunit": "~0.2.0", 13 | "grunt-contrib-concat": "~0.3.0", 14 | "grunt-contrib-uglify": "~0.2.0", 15 | "grunt-contrib-watch": "~0.4.0", 16 | "grunt-contrib-clean": "~0.4.0", 17 | "grunt": "~0.4.2" 18 | } 19 | } -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_grunt/src/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "curly": true, 3 | "eqeqeq": true, 4 | "immed": true, 5 | "latedef": true, 6 | "newcap": true, 7 | "noarg": true, 8 | "sub": true, 9 | "undef": true, 10 | "unused": true, 11 | "boss": true, 12 | "eqnull": true, 13 | "browser": true, 14 | "predef": ["jQuery"] 15 | } 16 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_grunt/src/i5ting-mobile.js: -------------------------------------------------------------------------------- 1 | /* 2 | * i5ting-mobile 3 | * https://github.com/i5ting/How-to-write-jQuery-plugin 4 | * 5 | * Copyright (c) 2014 i5ting 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | (function($) { 10 | 11 | // Collection method. 12 | $.fn.awesome = function() { 13 | return this.each(function(i) { 14 | // Do something awesome to each selected element. 15 | $(this).html('awesome' + i); 16 | }); 17 | }; 18 | 19 | // Static method. 20 | $.awesome = function(options) { 21 | // Override default options with passed-in options. 22 | options = $.extend({}, $.awesome.options, options); 23 | // Return something awesome. 24 | return 'awesome' + options.punctuation; 25 | }; 26 | 27 | // Static method default options. 28 | $.awesome.options = { 29 | punctuation: '.' 30 | }; 31 | 32 | // Custom selector. 33 | $.expr[':'].awesome = function(elem) { 34 | // Is this element awesome? 35 | return $(elem).text().indexOf('awesome') !== -1; 36 | }; 37 | 38 | }(jQuery)); 39 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_grunt/test/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "curly": true, 3 | "eqeqeq": true, 4 | "immed": true, 5 | "latedef": true, 6 | "newcap": true, 7 | "noarg": true, 8 | "sub": true, 9 | "undef": true, 10 | "unused": true, 11 | "boss": true, 12 | "eqnull": true, 13 | "browser": true, 14 | "predef": [ 15 | "jQuery", 16 | "QUnit", 17 | "module", 18 | "test", 19 | "asyncTest", 20 | "expect", 21 | "start", 22 | "stop", 23 | "ok", 24 | "equal", 25 | "notEqual", 26 | "deepEqual", 27 | "notDeepEqual", 28 | "strictEqual", 29 | "notStrictEqual", 30 | "throws" 31 | ] 32 | } -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_grunt/test/i5ting-mobile.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | I5ting Mobile Test Suite 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 |
21 |
22 | lame test markup 23 | normal test markup 24 | awesome test markup 25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_grunt/test/i5ting-mobile_test.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | /* 3 | ======== A Handy Little QUnit Reference ======== 4 | http://api.qunitjs.com/ 5 | 6 | Test methods: 7 | module(name, {[setup][ ,teardown]}) 8 | test(name, callback) 9 | expect(numberOfAssertions) 10 | stop(increment) 11 | start(decrement) 12 | Test assertions: 13 | ok(value, [message]) 14 | equal(actual, expected, [message]) 15 | notEqual(actual, expected, [message]) 16 | deepEqual(actual, expected, [message]) 17 | notDeepEqual(actual, expected, [message]) 18 | strictEqual(actual, expected, [message]) 19 | notStrictEqual(actual, expected, [message]) 20 | throws(block, [expected], [message]) 21 | */ 22 | 23 | module('jQuery#awesome', { 24 | // This will run before each test in this module. 25 | setup: function() { 26 | this.elems = $('#qunit-fixture').children(); 27 | } 28 | }); 29 | 30 | test('is chainable', function() { 31 | expect(1); 32 | // Not a bad test to run on collection methods. 33 | strictEqual(this.elems.awesome(), this.elems, 'should be chainable'); 34 | }); 35 | 36 | test('is awesome', function() { 37 | expect(1); 38 | strictEqual(this.elems.awesome().text(), 'awesome0awesome1awesome2', 'should be awesome'); 39 | }); 40 | 41 | module('jQuery.awesome'); 42 | 43 | test('is awesome', function() { 44 | expect(2); 45 | strictEqual($.awesome(), 'awesome.', 'should be awesome'); 46 | strictEqual($.awesome({punctuation: '!'}), 'awesome!', 'should be thoroughly awesome'); 47 | }); 48 | 49 | module(':awesome selector', { 50 | // This will run before each test in this module. 51 | setup: function() { 52 | this.elems = $('#qunit-fixture').children(); 53 | } 54 | }); 55 | 56 | test('is awesome', function() { 57 | expect(1); 58 | // Use deepEqual & .get() when comparing jQuery objects. 59 | deepEqual(this.elems.filter(':awesome').get(), this.elems.last().get(), 'knows awesome when it sees it'); 60 | }); 61 | 62 | }(jQuery)); 63 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_second/jQuery.tab.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | second tab example 6 | 7 | 8 | 9 |
10 |
11 | 16 |
17 |
18 |
19 | 我是第一个内容 20 |
21 |
22 | 我是第二个内容 23 |
24 |
25 | 我是第三个内容 26 |
27 |
28 |
29 | 30 | 31 | 36 | 37 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_second/jQuery.tab_more.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | second tab example 6 | 7 | 8 | 9 |
10 |
11 | 16 |
17 |
18 |
19 | 我是第一个内容 20 |
21 |
22 | 我是第二个内容 23 |
24 |
25 | 我是第三个内容 26 |
27 |
28 |
29 | 30 |
31 |
32 | 37 |
38 |
39 |
40 | 我是第一个内容 41 |
42 |
43 | 我是第二个内容 44 |
45 |
46 | 我是第三个内容 47 |
48 |
49 |
50 | 51 | 52 | 53 | 63 | 64 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_second/tab.css: -------------------------------------------------------------------------------- 1 | *{ 2 | margin: 0; 3 | padding: 0; 4 | list-style: none; 5 | } 6 | #tab { 7 | width: 600px; 8 | height: 300px; 9 | border: 1px solid #ccc; 10 | } 11 | .tab_content > div{ 12 | display: none; 13 | } 14 | .tab_content .active{ 15 | display:block; 16 | } 17 | .tab_header ul{ 18 | height: 50px; 19 | line-height: 50px; 20 | border-bottom: 1px solid #ccc; 21 | } 22 | .tab_header li { 23 | float: left; 24 | width: 200px; 25 | text-align: center;; 26 | } 27 | .tab_header li.active{ 28 | background: #ccc; 29 | } -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_second/tab.js: -------------------------------------------------------------------------------- 1 | ;(function($) { 2 | 3 | $.fn.tab = function(options) { 4 | // 将defaults 和 options 参数合并到{} 5 | var opts = $.extend({},$.fn.tab.defaults,options); 6 | 7 | return this.each(function() { 8 | var obj = $(this); 9 | 10 | $(obj).find('.tab_header li').on(opts.trigger_event_type, function (){ 11 | $(obj).find('.tab_header li').removeClass('active'); 12 | $(this).addClass('active'); 13 | 14 | $(obj).find('.tab_content div').hide(); 15 | $(obj).find('.tab_content div').eq($(this).index()).show(); 16 | }) 17 | }); 18 | // each end 19 | } 20 | 21 | //定义默认 22 | $.fn.tab.defaults = { 23 | trigger_event_type:'click', //mouseover | click 默认是click 24 | }; 25 | 26 | })(jQuery); -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_three/jQuery.tab.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | second tab example 6 | 7 | 8 | 9 |
10 |
11 | 16 |
17 |
18 |
19 | 我是第一个内容 20 |
21 |
22 | 我是第二个内容 23 |
24 |
25 | 我是第三个内容 26 |
27 |
28 |
29 | 30 | 31 | 36 | 37 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_three/jQuery.tab_more.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | second tab example 6 | 7 | 8 | 9 |
10 |
11 | 16 |
17 |
18 |
19 | 我是第一个内容 20 |
21 |
22 | 我是第二个内容 23 |
24 |
25 | 我是第三个内容 26 |
27 |
28 |
29 | 30 |
31 |
32 | 37 |
38 |
39 |
40 | 我是第一个内容 41 |
42 |
43 | 我是第二个内容 44 |
45 |
46 | 我是第三个内容 47 |
48 |
49 |
50 | 51 | 52 | 53 | 63 | 64 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_three/tab.css: -------------------------------------------------------------------------------- 1 | *{ 2 | margin: 0; 3 | padding: 0; 4 | list-style: none; 5 | } 6 | #tab { 7 | width: 600px; 8 | height: 300px; 9 | border: 1px solid #ccc; 10 | } 11 | .tab_content > div{ 12 | display: none; 13 | } 14 | .tab_content .active{ 15 | display:block; 16 | } 17 | .tab_header ul{ 18 | height: 50px; 19 | line-height: 50px; 20 | border-bottom: 1px solid #ccc; 21 | } 22 | .tab_header li { 23 | float: left; 24 | width: 200px; 25 | text-align: center;; 26 | } 27 | .tab_header li.active{ 28 | background: #ccc; 29 | } -------------------------------------------------------------------------------- /build/examples/jquery_plugin/plugin_three/tab.js: -------------------------------------------------------------------------------- 1 | ;(function($) { 2 | 3 | $.fn.tab = function(options) { 4 | // 将defaults 和 options 参数合并到{} 5 | var opts = $.extend({},$.fn.tab.defaults,options); 6 | 7 | return this.each(function() { 8 | var obj = $(this); 9 | 10 | $(obj).find('.tab_header li').on(opts.trigger_event_type, function (){ 11 | $(obj).find('.tab_header li').removeClass('active'); 12 | $(this).addClass('active'); 13 | 14 | $(obj).find('.tab_content div').hide(); 15 | $(obj).find('.tab_content div').eq($(this).index()).show(); 16 | 17 | opts.change($(this).index()); 18 | }) 19 | }); 20 | // each end 21 | } 22 | 23 | //定义默认 24 | $.fn.tab.defaults = { 25 | trigger_event_type:'click', //mouseover | click 默认是click 26 | change: function(index){ 27 | console.log('current index = ' + index); 28 | } 29 | }; 30 | 31 | })(jQuery); -------------------------------------------------------------------------------- /build/examples/jquery_plugin/second/jQuery.tab.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | second tab example 6 | 7 | 8 | 9 |
10 |
11 | 16 |
17 |
18 |
19 | 我是第一个内容 20 |
21 |
22 | 我是第二个内容 23 |
24 |
25 | 我是第三个内容 26 |
27 |
28 |
29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/second/jQuery.tab_more.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | second tab example 6 | 7 | 8 | 9 |
10 |
11 | 16 |
17 |
18 |
19 | 我是第一个内容 20 |
21 |
22 | 我是第二个内容 23 |
24 |
25 | 我是第三个内容 26 |
27 |
28 |
29 | 30 |
31 |
32 | 37 |
38 |
39 |
40 | 我是第一个内容 41 |
42 |
43 | 我是第二个内容 44 |
45 |
46 | 我是第三个内容 47 |
48 |
49 |
50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /build/examples/jquery_plugin/second/tab.css: -------------------------------------------------------------------------------- 1 | *{ 2 | margin: 0; 3 | padding: 0; 4 | list-style: none; 5 | } 6 | #tab { 7 | width: 600px; 8 | height: 300px; 9 | border: 1px solid #ccc; 10 | } 11 | .tab_content > div{ 12 | display: none; 13 | } 14 | .tab_content .active{ 15 | display:block; 16 | } 17 | .tab_header ul{ 18 | height: 50px; 19 | line-height: 50px; 20 | border-bottom: 1px solid #ccc; 21 | } 22 | .tab_header li { 23 | float: left; 24 | width: 200px; 25 | text-align: center;; 26 | } 27 | .tab_header li.active{ 28 | background: #ccc; 29 | } -------------------------------------------------------------------------------- /build/examples/jquery_plugin/second/tab.js: -------------------------------------------------------------------------------- 1 | ;$(function(){ 2 | $('.tab_header li').on('mouseover', function (){ 3 | $('.tab_header li').removeClass('active'); 4 | $(this).addClass('active'); 5 | 6 | $('.tab_content div').hide(); 7 | $('.tab_content div').eq($(this).index()).show(); 8 | }) 9 | }); -------------------------------------------------------------------------------- /build/images/jquery_plugin/debug_with_callback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i5ting/How-to-write-jQuery-plugin/8564fe9efeb4241b1c93bb1f9b4a27082b655b3d/build/images/jquery_plugin/debug_with_callback.png -------------------------------------------------------------------------------- /build/images/tab.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i5ting/How-to-write-jQuery-plugin/8564fe9efeb4241b1c93bb1f9b4a27082b655b3d/build/images/tab.gif -------------------------------------------------------------------------------- /build/js/jquery.ztree_toc.js: -------------------------------------------------------------------------------- 1 | /*! ztree_toc - v0.2.0 - 2014-02-05 2 | * https://github.com/i5ting/jQuery.zTree_Toc.js 3 | * Copyright (c) 2014 alfred.sang; Licensed MIT */ 4 | function encode_id_with_array(opts,arr) { 5 | var result = 0; 6 | for(var z = 0; z < arr.length; z++ ) { 7 | result += factor(opts, arr.length - z ,arr[z]); 8 | } 9 | 10 | return result; 11 | } 12 | 13 | 14 | /** 15 | * 1.1.1 = 1*100*100 + 1*100 + 1 16 | * 1.2.2 = 1*100*100 + 2*100 + 3 17 | * 18 | * 1 = 0*100 +1 19 | 20 | 1,1 = 100 21 | 22 | */ 23 | function get_parent_id_with_array(opts,arr) { 24 | var result_arr = []; 25 | 26 | for(var z = 0; z < arr.length; z++ ) { 27 | result_arr.push(arr[z]); 28 | } 29 | 30 | result_arr.pop(); 31 | 32 | var result = 0; 33 | for(var z = 0; z < result_arr.length; z++ ) { 34 | result += factor(opts,result_arr.length - z,result_arr[z]); 35 | } 36 | 37 | return result; 38 | } 39 | 40 | function factor(opts ,count,current) { 41 | if(1 == count) { 42 | return current; 43 | } 44 | 45 | var str = ''; 46 | for(var i = count - 1;i > 0; i-- ) { 47 | str += current * opts.step+'*'; 48 | } 49 | 50 | return eval( str + '1' ); 51 | } 52 | 53 | ;(function($) { 54 | /* 55 | * 根据header创建目录内容 56 | */ 57 | function create_toc(opts) { 58 | $(opts.documment_selector).find(':header').each(function() { 59 | var level = parseInt(this.nodeName.substring(1), 10); 60 | 61 | _rename_header_content(opts,this,level); 62 | 63 | _add_header_node(opts,$(this)); 64 | });//end each 65 | } 66 | 67 | /* 68 | * 渲染ztree 69 | */ 70 | function render_with_ztree(opts) { 71 | var t = $(opts._zTree); 72 | t = $.fn.zTree.init(t,opts.ztreeSetting,opts._header_nodes).expandAll(opts.is_expand_all); 73 | // alert(opts._headers * 88); 74 | // $(opts._zTree).height(opts._headers * 33 + 33); 75 | 76 | $(opts._zTree).css(opts.ztreeStyle); 77 | } 78 | 79 | /* 80 | * 将已有header编号,并重命名 81 | */ 82 | function _rename_header_content(opts ,header_obj ,level) { 83 | if(opts._headers.length == level) { 84 | opts._headers[level - 1]++; 85 | } else if(opts._headers.length > level) { 86 | opts._headers = opts._headers.slice(0, level); 87 | opts._headers[level - 1] ++; 88 | } else if(opts._headers.length < level) { 89 | for(var i = 0; i < (level - opts._headers.length); i++) { 90 | // console.log('push 1'); 91 | opts._headers.push(1); 92 | } 93 | } 94 | 95 | if(opts.is_auto_number == true) { 96 | $(header_obj).text(opts._headers.join('.') + '. ' + $(header_obj).text()); 97 | } 98 | } 99 | 100 | /* 101 | * 给ztree用的header_nodes增加数据 102 | */ 103 | function _add_header_node(opts ,header_obj) { 104 | var id = encode_id_with_array(opts,opts._headers); 105 | var pid = get_parent_id_with_array(opts,opts._headers); 106 | 107 | // 设置锚点id 108 | $(header_obj).attr('id',id); 109 | 110 | log($(header_obj).text()); 111 | 112 | opts._header_offsets.push($(header_obj).offset().top - opts.highlight_offset); 113 | 114 | log('h offset ='+( $(header_obj).offset().top - opts.highlight_offset ) ); 115 | 116 | opts._header_nodes.push({ 117 | id:id, 118 | pId:pid , 119 | name:$(header_obj).text()||'null', 120 | open:true, 121 | url:'#'+ id, 122 | target:'_self' 123 | }); 124 | } 125 | 126 | /* 127 | * 根据滚动确定当前位置,并更新ztree 128 | */ 129 | function bind_scroll_event_and_update_postion(opts) { 130 | var timeout; 131 | var highlight_on_scroll = function(e) { 132 | if (timeout) { 133 | clearTimeout(timeout); 134 | } 135 | 136 | timeout = setTimeout(function() { 137 | var top = $(window).scrollTop(),highlighted; 138 | 139 | if(opts.debug) console.log('top='+top); 140 | 141 | for (var i = 0, c = opts._header_offsets.length; i < c; i++) { 142 | // fixed: top+5防止点击ztree的时候,出现向上抖动的情况 143 | if (opts._header_offsets[i] >= (top + 5) ) { 144 | console.log('opts._header_offsets['+ i +'] = '+opts._header_offsets[i]); 145 | $('a').removeClass('curSelectedNode'); 146 | 147 | // 由于有root节点,所以i应该从1开始 148 | var obj = $('#tree_' + (i+1) + '_a').addClass('curSelectedNode'); 149 | break; 150 | } 151 | } 152 | }, opts.refresh_scroll_time); 153 | }; 154 | 155 | if (opts.highlight_on_scroll) { 156 | $(window).bind('scroll', highlight_on_scroll); 157 | highlight_on_scroll(); 158 | } 159 | } 160 | 161 | /* 162 | * 初始化 163 | */ 164 | function init_with_config(opts) { 165 | opts.highlight_offset = $(opts.documment_selector).offset().top; 166 | } 167 | 168 | /* 169 | * 日志 170 | */ 171 | function log(str) { 172 | return; 173 | if($.fn.ztree_toc.defaults.debug == true) { 174 | console.log(str); 175 | } 176 | } 177 | 178 | $.fn.ztree_toc = function(options) { 179 | // 将defaults 和 options 参数合并到{} 180 | var opts = $.extend({},$.fn.ztree_toc.defaults,options); 181 | 182 | return this.each(function() { 183 | opts._zTree = $(this); 184 | 185 | // 初始化 186 | init_with_config(opts); 187 | 188 | // 创建table of content,获取元数据_headers 189 | create_toc(opts); 190 | 191 | // 根据_headers生成ztree 192 | render_with_ztree(opts); 193 | 194 | // 根据滚动确定当前位置,并更新ztree 195 | bind_scroll_event_and_update_postion(opts); 196 | }); 197 | // each end 198 | } 199 | 200 | //定义默认 201 | $.fn.ztree_toc.defaults = { 202 | _zTree: null, 203 | _headers: [], 204 | _header_offsets: [], 205 | _header_nodes: [{ id:1, pId:0, name:"Table of Content",open:true}], 206 | debug: true, 207 | highlight_offset: 0, 208 | highlight_on_scroll: true, 209 | /* 210 | * 计算滚动判断当前位置的时间,默认是50毫秒 211 | */ 212 | refresh_scroll_time: 50, 213 | documment_selector: 'body', 214 | is_posion_top: false, 215 | /* 216 | * 默认是否显示header编号 217 | */ 218 | is_auto_number: false, 219 | /* 220 | * 默认是否展开全部 221 | */ 222 | is_expand_all: true, 223 | /* 224 | * 是否对选中行,显示高亮效果 225 | */ 226 | is_highlight_selected_line: true, 227 | step: 100, 228 | ztreeStyle: { 229 | width:'260px', 230 | overflow: 'auto', 231 | position: 'fixed', 232 | 'z-index': 2147483647, 233 | border: '0px none', 234 | left: '0px', 235 | bottom: '0px', 236 | // height:'100px' 237 | }, 238 | ztreeSetting: { 239 | view: { 240 | dblClickExpand: false, 241 | showLine: true, 242 | showIcon: false, 243 | selectedMulti: false 244 | }, 245 | data: { 246 | simpleData: { 247 | enable: true, 248 | idKey : "id", 249 | pIdKey: "pId", 250 | // rootPId: "0" 251 | } 252 | }, 253 | callback: { 254 | beforeClick: function(treeId, treeNode) { 255 | $('a').removeClass('curSelectedNode'); 256 | if(treeNode.id == 1){ 257 | // TODO: when click root node 258 | console.log('click root table of content'); 259 | } 260 | if($.fn.ztree_toc.defaults.is_highlight_selected_line == true) { 261 | $('#' + treeNode.id).css('color' ,'red').fadeOut("slow" ,function() { 262 | // Animation complete. 263 | $(this).show().css('color','black'); 264 | }); 265 | } 266 | } 267 | } 268 | } 269 | }; 270 | 271 | })(jQuery); -------------------------------------------------------------------------------- /build/js/jquery.ztree_toc.min.js: -------------------------------------------------------------------------------- 1 | /*! ztree_toc - v0.2.0 - 2014-02-05 2 | * https://github.com/i5ting/jQuery.zTree_Toc.js 3 | * Copyright (c) 2014 alfred.sang; Licensed MIT */ 4 | function encode_id_with_array(a,b){for(var c=0,d=0;d0;i--)str+=current*opts.step+"*";return eval(str+"1")}!function(a){function b(b){a(b.documment_selector).find(":header").each(function(){var c=parseInt(this.nodeName.substring(1),10);d(b,this,c),e(b,a(this))})}function c(b){var c=a(b._zTree);c=a.fn.zTree.init(c,b.ztreeSetting,b._header_nodes).expandAll(b.is_expand_all),a(b._zTree).css(b.ztreeStyle)}function d(b,c,d){if(b._headers.length==d)b._headers[d-1]++;else if(b._headers.length>d)b._headers=b._headers.slice(0,d),b._headers[d-1]++;else if(b._headers.lengthd;d++)if(b._header_offsets[d]>=c+5){console.log("opts._header_offsets["+d+"] = "+b._header_offsets[d]),a("a").removeClass("curSelectedNode"),a("#tree_"+(d+1)+"_a").addClass("curSelectedNode");break}},b.refresh_scroll_time)};b.highlight_on_scroll&&(a(window).bind("scroll",d),d())}function g(b){b.highlight_offset=a(b.documment_selector).offset().top}function h(a){}a.fn.ztree_toc=function(d){var e=a.extend({},a.fn.ztree_toc.defaults,d);return this.each(function(){e._zTree=a(this),g(e),b(e),c(e),f(e)})},a.fn.ztree_toc.defaults={_zTree:null,_headers:[],_header_offsets:[],_header_nodes:[{id:1,pId:0,name:"Table of Content",open:!0}],debug:!0,highlight_offset:0,highlight_on_scroll:!0,refresh_scroll_time:50,documment_selector:"body",is_posion_top:!1,is_auto_number:!1,is_expand_all:!0,is_highlight_selected_line:!0,step:100,ztreeStyle:{width:"260px",overflow:"auto",position:"fixed","z-index":2147483647,border:"0px none",left:"0px",bottom:"0px"},ztreeSetting:{view:{dblClickExpand:!1,showLine:!0,showIcon:!1,selectedMulti:!1},data:{simpleData:{enable:!0,idKey:"id",pIdKey:"pId"}},callback:{beforeClick:function(b,c){a("a").removeClass("curSelectedNode"),1==c.id&&console.log("click root table of content"),1==a.fn.ztree_toc.defaults.is_highlight_selected_line&&a("#"+c.id).css("color","red").fadeOut("slow",function(){a(this).show().css("color","black")})}}}}}(jQuery); -------------------------------------------------------------------------------- /build/style/Clearness Dark.css: -------------------------------------------------------------------------------- 1 | h1, 2 | h2, 3 | h3, 4 | h4, 5 | h5, 6 | h6, 7 | p, 8 | blockquote { 9 | margin: 0; 10 | padding: 0; 11 | } 12 | body { 13 | font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", Arial, sans-serif; 14 | font-size: 13px; 15 | line-height: 18px; 16 | color: #fff; 17 | background-color: #282a36; 18 | margin: 10px 13px 10px 13px; 19 | } 20 | table { 21 | margin: 10px 0 15px 0; 22 | border-collapse: collapse; 23 | } 24 | td,th { 25 | border: 1px solid #ddd; 26 | padding: 3px 10px; 27 | } 28 | th { 29 | padding: 5px 10px; 30 | } 31 | a { 32 | color: #59acf3; 33 | } 34 | a:hover { 35 | color: #a7d8ff; 36 | text-decoration: none; 37 | } 38 | a img { 39 | border: none; 40 | } 41 | p { 42 | margin-bottom: 9px; 43 | } 44 | h1, 45 | h2, 46 | h3, 47 | h4, 48 | h5, 49 | h6 { 50 | color: #fff; 51 | line-height: 36px; 52 | } 53 | h1 { 54 | margin-bottom: 18px; 55 | font-size: 30px; 56 | } 57 | h2 { 58 | font-size: 24px; 59 | } 60 | h3 { 61 | font-size: 18px; 62 | } 63 | h4 { 64 | font-size: 16px; 65 | } 66 | h5 { 67 | font-size: 14px; 68 | } 69 | h6 { 70 | font-size: 13px; 71 | } 72 | hr { 73 | margin: 0 0 19px; 74 | border: 0; 75 | border-bottom: 1px solid #ccc; 76 | } 77 | blockquote { 78 | padding: 13px 13px 21px 15px; 79 | margin-bottom: 18px; 80 | font-family:georgia,serif; 81 | font-style: italic; 82 | } 83 | blockquote:before { 84 | content:"\201C"; 85 | font-size:40px; 86 | margin-left:-10px; 87 | font-family:georgia,serif; 88 | color:#eee; 89 | } 90 | blockquote p { 91 | font-size: 14px; 92 | font-weight: 300; 93 | line-height: 18px; 94 | margin-bottom: 0; 95 | font-style: italic; 96 | } 97 | code, pre { 98 | font-family: Monaco, Andale Mono, Courier New, monospace; 99 | } 100 | code { 101 | color: #ff4a14; 102 | padding: 1px 3px; 103 | font-size: 12px; 104 | -webkit-border-radius: 3px; 105 | -moz-border-radius: 3px; 106 | border-radius: 3px; 107 | } 108 | pre { 109 | display: block; 110 | padding: 14px; 111 | margin: 0 0 18px; 112 | line-height: 16px; 113 | font-size: 11px; 114 | border: 1px solid #bf370f; 115 | white-space: pre; 116 | white-space: pre-wrap; 117 | word-wrap: break-word; 118 | } 119 | pre code { 120 | background-color: #282a36; 121 | color: #ff4a14; 122 | font-size: 11px; 123 | padding: 0; 124 | } 125 | sup { 126 | font-size: 0.83em; 127 | vertical-align: super; 128 | line-height: 0; 129 | } 130 | * { 131 | -webkit-print-color-adjust: exact; 132 | } 133 | @media screen and (min-width: 914px) { 134 | body { 135 | width: 854px; 136 | margin:10px auto; 137 | } 138 | } 139 | @media print { 140 | body,code,pre code,h1,h2,h3,h4,h5,h6 { 141 | color: black; 142 | } 143 | table, pre { 144 | page-break-inside: avoid; 145 | } 146 | } -------------------------------------------------------------------------------- /build/style/Clearness.css: -------------------------------------------------------------------------------- 1 | h1, 2 | h2, 3 | h3, 4 | h4, 5 | h5, 6 | h6, 7 | p, 8 | blockquote { 9 | margin: 0; 10 | padding: 0; 11 | } 12 | body { 13 | font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", Arial, sans-serif; 14 | font-size: 13px; 15 | line-height: 18px; 16 | color: #737373; 17 | background-color: white; 18 | margin: 10px 13px 10px 13px; 19 | } 20 | table { 21 | margin: 10px 0 15px 0; 22 | border-collapse: collapse; 23 | } 24 | td,th { 25 | border: 1px solid #ddd; 26 | padding: 3px 10px; 27 | } 28 | th { 29 | padding: 5px 10px; 30 | } 31 | 32 | a { 33 | color: #0069d6; 34 | } 35 | a:hover { 36 | color: #0050a3; 37 | text-decoration: none; 38 | } 39 | a img { 40 | border: none; 41 | } 42 | p { 43 | margin-bottom: 9px; 44 | } 45 | h1, 46 | h2, 47 | h3, 48 | h4, 49 | h5, 50 | h6 { 51 | color: #404040; 52 | line-height: 36px; 53 | } 54 | h1 { 55 | margin-bottom: 18px; 56 | font-size: 30px; 57 | } 58 | h2 { 59 | font-size: 24px; 60 | } 61 | h3 { 62 | font-size: 18px; 63 | } 64 | h4 { 65 | font-size: 16px; 66 | } 67 | h5 { 68 | font-size: 14px; 69 | } 70 | h6 { 71 | font-size: 13px; 72 | } 73 | hr { 74 | margin: 0 0 19px; 75 | border: 0; 76 | border-bottom: 1px solid #ccc; 77 | } 78 | blockquote { 79 | padding: 13px 13px 21px 15px; 80 | margin-bottom: 18px; 81 | font-family:georgia,serif; 82 | font-style: italic; 83 | } 84 | blockquote:before { 85 | content:"\201C"; 86 | font-size:40px; 87 | margin-left:-10px; 88 | font-family:georgia,serif; 89 | color:#eee; 90 | } 91 | blockquote p { 92 | font-size: 14px; 93 | font-weight: 300; 94 | line-height: 18px; 95 | margin-bottom: 0; 96 | font-style: italic; 97 | } 98 | code, pre { 99 | font-family: Monaco, Andale Mono, Courier New, monospace; 100 | } 101 | code { 102 | background-color: #fee9cc; 103 | color: rgba(0, 0, 0, 0.75); 104 | padding: 1px 3px; 105 | font-size: 12px; 106 | -webkit-border-radius: 3px; 107 | -moz-border-radius: 3px; 108 | border-radius: 3px; 109 | } 110 | pre { 111 | display: block; 112 | padding: 14px; 113 | margin: 0 0 18px; 114 | line-height: 16px; 115 | font-size: 11px; 116 | border: 1px solid #d9d9d9; 117 | white-space: pre-wrap; 118 | word-wrap: break-word; 119 | } 120 | pre code { 121 | background-color: #fff; 122 | color:#737373; 123 | font-size: 11px; 124 | padding: 0; 125 | } 126 | sup { 127 | font-size: 0.83em; 128 | vertical-align: super; 129 | line-height: 0; 130 | } 131 | * { 132 | -webkit-print-color-adjust: exact; 133 | } 134 | @media screen and (min-width: 914px) { 135 | body { 136 | width: 854px; 137 | margin:10px auto; 138 | } 139 | } 140 | @media print { 141 | body,code,pre code,h1,h2,h3,h4,h5,h6 { 142 | color: black; 143 | } 144 | table, pre { 145 | page-break-inside: avoid; 146 | } 147 | } -------------------------------------------------------------------------------- /build/style/GitHub.css: -------------------------------------------------------------------------------- 1 | *{margin:0;padding:0;} 2 | body { 3 | font:13.34px helvetica,arial,freesans,clean,sans-serif; 4 | color:black; 5 | line-height:1.4em; 6 | background-color: #F8F8F8; 7 | padding: 0.7em; 8 | } 9 | p { 10 | margin:1em 0; 11 | line-height:1.5em; 12 | } 13 | table { 14 | font-size:inherit; 15 | font:100%; 16 | margin:1em; 17 | } 18 | table th{border-bottom:1px solid #bbb;padding:.2em 1em;} 19 | table td{border-bottom:1px solid #ddd;padding:.2em 1em;} 20 | input[type=text],input[type=password],input[type=image],textarea{font:99% helvetica,arial,freesans,sans-serif;} 21 | select,option{padding:0 .25em;} 22 | optgroup{margin-top:.5em;} 23 | pre,code{font:12px Monaco,"Courier New","DejaVu Sans Mono","Bitstream Vera Sans Mono",monospace;} 24 | pre { 25 | margin:1em 0; 26 | font-size:12px; 27 | background-color:#eee; 28 | border:1px solid #ddd; 29 | padding:5px; 30 | line-height:1.5em; 31 | color:#444; 32 | overflow:auto; 33 | -webkit-box-shadow:rgba(0,0,0,0.07) 0 1px 2px inset; 34 | -webkit-border-radius:3px; 35 | -moz-border-radius:3px;border-radius:3px; 36 | } 37 | pre code { 38 | padding:0; 39 | font-size:12px; 40 | background-color:#eee; 41 | border:none; 42 | } 43 | code { 44 | font-size:12px; 45 | background-color:#f8f8ff; 46 | color:#444; 47 | padding:0 .2em; 48 | border:1px solid #dedede; 49 | } 50 | img{border:0;max-width:100%;} 51 | abbr{border-bottom:none;} 52 | a{color:#4183c4;text-decoration:none;} 53 | a:hover{text-decoration:underline;} 54 | a code,a:link code,a:visited code{color:#4183c4;} 55 | h2,h3{margin:1em 0;} 56 | h1,h2,h3,h4,h5,h6{border:0;} 57 | h1{font-size:170%;border-top:4px solid #aaa;padding-top:.5em;margin-top:1.5em;} 58 | h1:first-child{margin-top:0;padding-top:.25em;border-top:none;} 59 | h2{font-size:150%;margin-top:1.5em;border-top:4px solid #e0e0e0;padding-top:.5em;} 60 | h3{margin-top:1em;} 61 | hr{border:1px solid #ddd;} 62 | ul{margin:1em 0 1em 2em;} 63 | ol{margin:1em 0 1em 2em;} 64 | ul li,ol li{margin-top:.5em;margin-bottom:.5em;} 65 | ul ul,ul ol,ol ol,ol ul{margin-top:0;margin-bottom:0;} 66 | blockquote{margin:1em 0;border-left:5px solid #ddd;padding-left:.6em;color:#555;} 67 | dt{font-weight:bold;margin-left:1em;} 68 | dd{margin-left:2em;margin-bottom:1em;} 69 | sup { 70 | font-size: 0.83em; 71 | vertical-align: super; 72 | line-height: 0; 73 | } 74 | * { 75 | -webkit-print-color-adjust: exact; 76 | } 77 | @media screen and (min-width: 914px) { 78 | body { 79 | width: 854px; 80 | margin:0 auto; 81 | } 82 | } 83 | @media print { 84 | table, pre { 85 | page-break-inside: avoid; 86 | } 87 | pre { 88 | word-wrap: break-word; 89 | } 90 | } -------------------------------------------------------------------------------- /build/style/GitHub2.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Helvetica, arial, sans-serif; 3 | font-size: 14px; 4 | line-height: 1.6; 5 | padding-top: 10px; 6 | padding-bottom: 10px; 7 | background-color: white; 8 | padding: 30px; } 9 | 10 | body > *:first-child { 11 | margin-top: 0 !important; } 12 | body > *:last-child { 13 | margin-bottom: 0 !important; } 14 | 15 | a { 16 | color: #4183C4; } 17 | a.absent { 18 | color: #cc0000; } 19 | a.anchor { 20 | display: block; 21 | padding-left: 30px; 22 | margin-left: -30px; 23 | cursor: pointer; 24 | position: absolute; 25 | top: 0; 26 | left: 0; 27 | bottom: 0; } 28 | 29 | h1, h2, h3, h4, h5, h6 { 30 | margin: 20px 0 10px; 31 | padding: 0; 32 | font-weight: bold; 33 | -webkit-font-smoothing: antialiased; 34 | cursor: text; 35 | position: relative; } 36 | 37 | h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor { 38 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA09pVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoMTMuMCAyMDEyMDMwNS5tLjQxNSAyMDEyLzAzLzA1OjIxOjAwOjAwKSAgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OUM2NjlDQjI4ODBGMTFFMTg1ODlEODNERDJBRjUwQTQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OUM2NjlDQjM4ODBGMTFFMTg1ODlEODNERDJBRjUwQTQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo5QzY2OUNCMDg4MEYxMUUxODU4OUQ4M0REMkFGNTBBNCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo5QzY2OUNCMTg4MEYxMUUxODU4OUQ4M0REMkFGNTBBNCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsQhXeAAAABfSURBVHjaYvz//z8DJYCRUgMYQAbAMBQIAvEqkBQWXI6sHqwHiwG70TTBxGaiWwjCTGgOUgJiF1J8wMRAIUA34B4Q76HUBelAfJYSA0CuMIEaRP8wGIkGMA54bgQIMACAmkXJi0hKJQAAAABJRU5ErkJggg==) no-repeat 10px center; 39 | text-decoration: none; } 40 | 41 | h1 tt, h1 code { 42 | font-size: inherit; } 43 | 44 | h2 tt, h2 code { 45 | font-size: inherit; } 46 | 47 | h3 tt, h3 code { 48 | font-size: inherit; } 49 | 50 | h4 tt, h4 code { 51 | font-size: inherit; } 52 | 53 | h5 tt, h5 code { 54 | font-size: inherit; } 55 | 56 | h6 tt, h6 code { 57 | font-size: inherit; } 58 | 59 | h1 { 60 | font-size: 28px; 61 | color: black; } 62 | 63 | h2 { 64 | font-size: 24px; 65 | border-bottom: 1px solid #cccccc; 66 | color: black; } 67 | 68 | h3 { 69 | font-size: 18px; } 70 | 71 | h4 { 72 | font-size: 16px; } 73 | 74 | h5 { 75 | font-size: 14px; } 76 | 77 | h6 { 78 | color: #777777; 79 | font-size: 14px; } 80 | 81 | p, blockquote, ul, ol, dl, li, table, pre { 82 | margin: 15px 0; } 83 | 84 | hr { 85 | background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAYAAACtBE5DAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OENDRjNBN0E2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OENDRjNBN0I2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4Q0NGM0E3ODY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4Q0NGM0E3OTY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqqezsUAAAAfSURBVHjaYmRABcYwBiM2QSA4y4hNEKYDQxAEAAIMAHNGAzhkPOlYAAAAAElFTkSuQmCC) repeat-x 0 0; 86 | border: 0 none; 87 | color: #cccccc; 88 | height: 4px; 89 | padding: 0; 90 | } 91 | 92 | body > h2:first-child { 93 | margin-top: 0; 94 | padding-top: 0; } 95 | body > h1:first-child { 96 | margin-top: 0; 97 | padding-top: 0; } 98 | body > h1:first-child + h2 { 99 | margin-top: 0; 100 | padding-top: 0; } 101 | body > h3:first-child, body > h4:first-child, body > h5:first-child, body > h6:first-child { 102 | margin-top: 0; 103 | padding-top: 0; } 104 | 105 | a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 { 106 | margin-top: 0; 107 | padding-top: 0; } 108 | 109 | h1 p, h2 p, h3 p, h4 p, h5 p, h6 p { 110 | margin-top: 0; } 111 | 112 | li p.first { 113 | display: inline-block; } 114 | li { 115 | margin: 0; } 116 | ul, ol { 117 | padding-left: 30px; } 118 | 119 | ul :first-child, ol :first-child { 120 | margin-top: 0; } 121 | 122 | dl { 123 | padding: 0; } 124 | dl dt { 125 | font-size: 14px; 126 | font-weight: bold; 127 | font-style: italic; 128 | padding: 0; 129 | margin: 15px 0 5px; } 130 | dl dt:first-child { 131 | padding: 0; } 132 | dl dt > :first-child { 133 | margin-top: 0; } 134 | dl dt > :last-child { 135 | margin-bottom: 0; } 136 | dl dd { 137 | margin: 0 0 15px; 138 | padding: 0 15px; } 139 | dl dd > :first-child { 140 | margin-top: 0; } 141 | dl dd > :last-child { 142 | margin-bottom: 0; } 143 | 144 | blockquote { 145 | border-left: 4px solid #dddddd; 146 | padding: 0 15px; 147 | color: #777777; } 148 | blockquote > :first-child { 149 | margin-top: 0; } 150 | blockquote > :last-child { 151 | margin-bottom: 0; } 152 | 153 | table { 154 | padding: 0;border-collapse: collapse; } 155 | table tr { 156 | border-top: 1px solid #cccccc; 157 | background-color: white; 158 | margin: 0; 159 | padding: 0; } 160 | table tr:nth-child(2n) { 161 | background-color: #f8f8f8; } 162 | table tr th { 163 | font-weight: bold; 164 | border: 1px solid #cccccc; 165 | margin: 0; 166 | padding: 6px 13px; } 167 | table tr td { 168 | border: 1px solid #cccccc; 169 | margin: 0; 170 | padding: 6px 13px; } 171 | table tr th :first-child, table tr td :first-child { 172 | margin-top: 0; } 173 | table tr th :last-child, table tr td :last-child { 174 | margin-bottom: 0; } 175 | 176 | img { 177 | max-width: 100%; } 178 | 179 | span.frame { 180 | display: block; 181 | overflow: hidden; } 182 | span.frame > span { 183 | border: 1px solid #dddddd; 184 | display: block; 185 | float: left; 186 | overflow: hidden; 187 | margin: 13px 0 0; 188 | padding: 7px; 189 | width: auto; } 190 | span.frame span img { 191 | display: block; 192 | float: left; } 193 | span.frame span span { 194 | clear: both; 195 | color: #333333; 196 | display: block; 197 | padding: 5px 0 0; } 198 | span.align-center { 199 | display: block; 200 | overflow: hidden; 201 | clear: both; } 202 | span.align-center > span { 203 | display: block; 204 | overflow: hidden; 205 | margin: 13px auto 0; 206 | text-align: center; } 207 | span.align-center span img { 208 | margin: 0 auto; 209 | text-align: center; } 210 | span.align-right { 211 | display: block; 212 | overflow: hidden; 213 | clear: both; } 214 | span.align-right > span { 215 | display: block; 216 | overflow: hidden; 217 | margin: 13px 0 0; 218 | text-align: right; } 219 | span.align-right span img { 220 | margin: 0; 221 | text-align: right; } 222 | span.float-left { 223 | display: block; 224 | margin-right: 13px; 225 | overflow: hidden; 226 | float: left; } 227 | span.float-left span { 228 | margin: 13px 0 0; } 229 | span.float-right { 230 | display: block; 231 | margin-left: 13px; 232 | overflow: hidden; 233 | float: right; } 234 | span.float-right > span { 235 | display: block; 236 | overflow: hidden; 237 | margin: 13px auto 0; 238 | text-align: right; } 239 | 240 | code, tt { 241 | margin: 0 2px; 242 | padding: 0 5px; 243 | white-space: nowrap; 244 | border: 1px solid #eaeaea; 245 | background-color: #f8f8f8; 246 | border-radius: 3px; } 247 | 248 | pre code { 249 | margin: 0; 250 | padding: 0; 251 | white-space: pre; 252 | border: none; 253 | background: transparent; } 254 | 255 | .highlight pre { 256 | background-color: #f8f8f8; 257 | border: 1px solid #cccccc; 258 | font-size: 13px; 259 | line-height: 19px; 260 | overflow: auto; 261 | padding: 6px 10px; 262 | border-radius: 3px; } 263 | 264 | pre { 265 | background-color: #f8f8f8; 266 | border: 1px solid #cccccc; 267 | font-size: 13px; 268 | line-height: 19px; 269 | overflow: auto; 270 | padding: 6px 10px; 271 | border-radius: 3px; } 272 | pre code, pre tt { 273 | background-color: transparent; 274 | border: none; } 275 | 276 | sup { 277 | font-size: 0.83em; 278 | vertical-align: super; 279 | line-height: 0; 280 | } 281 | * { 282 | -webkit-print-color-adjust: exact; 283 | } 284 | @media screen and (min-width: 914px) { 285 | body { 286 | width: 854px; 287 | margin:0 auto; 288 | } 289 | } 290 | @media print { 291 | table, pre { 292 | page-break-inside: avoid; 293 | } 294 | pre { 295 | word-wrap: break-word; 296 | } 297 | } -------------------------------------------------------------------------------- /build/style/demo.css: -------------------------------------------------------------------------------- 1 | html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { 2 | margin: 0;padding: 0;border: 0;outline: 0;font-weight: inherit;font-style: inherit;font-size: 100%;font-family: inherit;vertical-align: baseline;} 3 | body {color: #2f332a;font: 15px/21px Arial, Helvetica, simsun, sans-serif;background: #f0f6e4 \9;} 4 | h1, h2, h3, h4, h5, h6 {color: #2f332a;font-weight: bold;font-family: Helvetica, Arial, sans-serif;padding-bottom: 5px;} 5 | h1 {font-size: 24px;line-height: 34px;text-align: center;} 6 | h2 {font-size: 14px;line-height: 24px;padding-top: 5px;} 7 | h6 {font-weight: normal;font-size: 12px;letter-spacing: 1px;line-height: 24px;text-align: center;} 8 | a {color:#3C6E31;text-decoration: underline;} 9 | a:hover {background-color:#3C6E31;color:white;} 10 | input.radio {margin: 0 2px 0 8px;} 11 | input.radio.first {margin-left:0;} 12 | input.empty {color: lightgray;} 13 | code {color: #2f332a;} 14 | .highlight_red {color:#A60000;} 15 | .highlight_green {color:#A7F43D;} 16 | li {list-style: circle;font-size: 12px;} 17 | li.title {list-style: none;} 18 | ul.list {margin-left: 17px;} 19 | 20 | div.content_wrap {width: 600px;height:380px;} 21 | div.content_wrap div.left{float: left;width: 250px;} 22 | div.content_wrap div.right{float: right;width: 340px;} 23 | div.zTreeDemoBackground {width:250px;height:362px;text-align:left;} 24 | 25 | ul.ztree {margin-top: 10px;border: 1px solid #617775;background: #f0f6e4;width:220px;height:360px;overflow-y:scroll;overflow-x:auto;} 26 | ul.log {border: 1px solid #617775;background: #f0f6e4;width:300px;height:170px;overflow: hidden;} 27 | ul.log.small {height:45px;} 28 | ul.log li {color: #666666;list-style: none;padding-left: 10px;} 29 | ul.log li.dark {background-color: #E3E3E3;} 30 | 31 | /* ruler */ 32 | div.ruler {height:20px; width:220px; background-color:#f0f6e4;border: 1px solid #333; margin-bottom: 5px; cursor: pointer} 33 | div.ruler div.cursor {height:20px; width:30px; background-color:#3C6E31; color:white; text-align: right; padding-right: 5px; cursor: pointer} -------------------------------------------------------------------------------- /build/style/makedownpad.css: -------------------------------------------------------------------------------- 1 | 2 | /* GitHub stylesheet for MarkdownPad (http://markdownpad.com) */ 3 | /* Author: Nicolas Hery - http://nicolashery.com */ 4 | /* Version: b13fe65ca28d2e568c6ed5d7f06581183df8f2ff */ 5 | /* Source: https://github.com/nicolahery/markdownpad-github */ 6 | 7 | /* RESET 8 | =============================================================================*/ 9 | 10 | html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { 11 | margin: 0; 12 | padding: 0; 13 | border: 0; 14 | } 15 | 16 | /* BODY 17 | =============================================================================*/ 18 | 19 | body { 20 | font-family: Helvetica, arial, freesans, clean, sans-serif; 21 | font-size: 14px; 22 | line-height: 1.6; 23 | color: #333; 24 | background-color: #fff; 25 | padding: 20px; 26 | max-width: 960px; 27 | margin: 0 auto; 28 | } 29 | 30 | body>*:first-child { 31 | margin-top: 0 !important; 32 | } 33 | 34 | body>*:last-child { 35 | margin-bottom: 0 !important; 36 | } 37 | 38 | /* BLOCKS 39 | =============================================================================*/ 40 | 41 | p, blockquote, ul, ol, dl, table, pre { 42 | margin: 15px 0; 43 | } 44 | 45 | /* HEADERS 46 | =============================================================================*/ 47 | 48 | h1, h2, h3, h4, h5, h6 { 49 | margin: 20px 0 10px; 50 | padding: 0; 51 | font-weight: bold; 52 | -webkit-font-smoothing: antialiased; 53 | } 54 | 55 | h1 tt, h1 code, h2 tt, h2 code, h3 tt, h3 code, h4 tt, h4 code, h5 tt, h5 code, h6 tt, h6 code { 56 | font-size: inherit; 57 | } 58 | 59 | h1 { 60 | font-size: 28px; 61 | color: #000; 62 | } 63 | 64 | h2 { 65 | font-size: 24px; 66 | border-bottom: 1px solid #ccc; 67 | color: #000; 68 | } 69 | 70 | h3 { 71 | font-size: 18px; 72 | } 73 | 74 | h4 { 75 | font-size: 16px; 76 | } 77 | 78 | h5 { 79 | font-size: 14px; 80 | } 81 | 82 | h6 { 83 | color: #777; 84 | font-size: 14px; 85 | } 86 | 87 | body>h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h4:first-child, body>h5:first-child, body>h6:first-child { 88 | margin-top: 0; 89 | padding-top: 0; 90 | } 91 | 92 | a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 { 93 | margin-top: 0; 94 | padding-top: 0; 95 | } 96 | 97 | h1+p, h2+p, h3+p, h4+p, h5+p, h6+p { 98 | margin-top: 10px; 99 | } 100 | 101 | /* LINKS 102 | =============================================================================*/ 103 | 104 | a { 105 | color: #4183C4; 106 | text-decoration: none; 107 | } 108 | 109 | a:hover { 110 | text-decoration: underline; 111 | } 112 | 113 | /* LISTS 114 | =============================================================================*/ 115 | 116 | ul, ol { 117 | padding-left: 30px; 118 | } 119 | 120 | ul li > :first-child, 121 | ol li > :first-child, 122 | ul li ul:first-of-type, 123 | ol li ol:first-of-type, 124 | ul li ol:first-of-type, 125 | ol li ul:first-of-type { 126 | margin-top: 0px; 127 | } 128 | 129 | ul ul, ul ol, ol ol, ol ul { 130 | margin-bottom: 0; 131 | } 132 | 133 | dl { 134 | padding: 0; 135 | } 136 | 137 | dl dt { 138 | font-size: 14px; 139 | font-weight: bold; 140 | font-style: italic; 141 | padding: 0; 142 | margin: 15px 0 5px; 143 | } 144 | 145 | dl dt:first-child { 146 | padding: 0; 147 | } 148 | 149 | dl dt>:first-child { 150 | margin-top: 0px; 151 | } 152 | 153 | dl dt>:last-child { 154 | margin-bottom: 0px; 155 | } 156 | 157 | dl dd { 158 | margin: 0 0 15px; 159 | padding: 0 15px; 160 | } 161 | 162 | dl dd>:first-child { 163 | margin-top: 0px; 164 | } 165 | 166 | dl dd>:last-child { 167 | margin-bottom: 0px; 168 | } 169 | 170 | /* CODE 171 | =============================================================================*/ 172 | 173 | pre, code, tt { 174 | font-size: 12px; 175 | font-family: Consolas, "Liberation Mono", Courier, monospace; 176 | } 177 | 178 | code, tt { 179 | margin: 0 0px; 180 | padding: 0px 0px; 181 | white-space: nowrap; 182 | border: 1px solid #eaeaea; 183 | background-color: #f8f8f8; 184 | border-radius: 3px; 185 | } 186 | 187 | pre>code { 188 | margin: 0; 189 | padding: 0; 190 | white-space: pre; 191 | border: none; 192 | background: transparent; 193 | } 194 | 195 | pre { 196 | background-color: #f8f8f8; 197 | border: 1px solid #ccc; 198 | font-size: 13px; 199 | line-height: 19px; 200 | overflow: auto; 201 | padding: 6px 10px; 202 | border-radius: 3px; 203 | } 204 | 205 | pre code, pre tt { 206 | background-color: transparent; 207 | border: none; 208 | } 209 | 210 | kbd { 211 | -moz-border-bottom-colors: none; 212 | -moz-border-left-colors: none; 213 | -moz-border-right-colors: none; 214 | -moz-border-top-colors: none; 215 | background-color: #DDDDDD; 216 | background-image: linear-gradient(#F1F1F1, #DDDDDD); 217 | background-repeat: repeat-x; 218 | border-color: #DDDDDD #CCCCCC #CCCCCC #DDDDDD; 219 | border-image: none; 220 | border-radius: 2px 2px 2px 2px; 221 | border-style: solid; 222 | border-width: 1px; 223 | font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; 224 | line-height: 10px; 225 | padding: 1px 4px; 226 | } 227 | 228 | /* QUOTES 229 | =============================================================================*/ 230 | 231 | blockquote { 232 | border-left: 4px solid #DDD; 233 | padding: 0 15px; 234 | color: #777; 235 | } 236 | 237 | blockquote>:first-child { 238 | margin-top: 0px; 239 | } 240 | 241 | blockquote>:last-child { 242 | margin-bottom: 0px; 243 | } 244 | 245 | /* HORIZONTAL RULES 246 | =============================================================================*/ 247 | 248 | hr { 249 | clear: both; 250 | margin: 15px 0; 251 | height: 0px; 252 | overflow: hidden; 253 | border: none; 254 | background: transparent; 255 | border-bottom: 4px solid #ddd; 256 | padding: 0; 257 | } 258 | 259 | /* TABLES 260 | =============================================================================*/ 261 | 262 | table th { 263 | font-weight: bold; 264 | } 265 | 266 | table th, table td { 267 | border: 1px solid #ccc; 268 | padding: 6px 13px; 269 | } 270 | 271 | table tr { 272 | border-top: 1px solid #ccc; 273 | background-color: #fff; 274 | } 275 | 276 | table tr:nth-child(2n) { 277 | background-color: #f8f8f8; 278 | } 279 | 280 | /* IMAGES 281 | =============================================================================*/ 282 | 283 | img { 284 | max-width: 100% 285 | } 286 | -------------------------------------------------------------------------------- /build/style/zTreeStyle/img/diy/1_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i5ting/How-to-write-jQuery-plugin/8564fe9efeb4241b1c93bb1f9b4a27082b655b3d/build/style/zTreeStyle/img/diy/1_close.png -------------------------------------------------------------------------------- /build/style/zTreeStyle/img/diy/1_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i5ting/How-to-write-jQuery-plugin/8564fe9efeb4241b1c93bb1f9b4a27082b655b3d/build/style/zTreeStyle/img/diy/1_open.png -------------------------------------------------------------------------------- /build/style/zTreeStyle/img/diy/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i5ting/How-to-write-jQuery-plugin/8564fe9efeb4241b1c93bb1f9b4a27082b655b3d/build/style/zTreeStyle/img/diy/2.png -------------------------------------------------------------------------------- /build/style/zTreeStyle/img/diy/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i5ting/How-to-write-jQuery-plugin/8564fe9efeb4241b1c93bb1f9b4a27082b655b3d/build/style/zTreeStyle/img/diy/3.png -------------------------------------------------------------------------------- /build/style/zTreeStyle/img/diy/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i5ting/How-to-write-jQuery-plugin/8564fe9efeb4241b1c93bb1f9b4a27082b655b3d/build/style/zTreeStyle/img/diy/4.png -------------------------------------------------------------------------------- /build/style/zTreeStyle/img/diy/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i5ting/How-to-write-jQuery-plugin/8564fe9efeb4241b1c93bb1f9b4a27082b655b3d/build/style/zTreeStyle/img/diy/5.png -------------------------------------------------------------------------------- /build/style/zTreeStyle/img/diy/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i5ting/How-to-write-jQuery-plugin/8564fe9efeb4241b1c93bb1f9b4a27082b655b3d/build/style/zTreeStyle/img/diy/6.png -------------------------------------------------------------------------------- /build/style/zTreeStyle/img/diy/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i5ting/How-to-write-jQuery-plugin/8564fe9efeb4241b1c93bb1f9b4a27082b655b3d/build/style/zTreeStyle/img/diy/7.png -------------------------------------------------------------------------------- /build/style/zTreeStyle/img/diy/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i5ting/How-to-write-jQuery-plugin/8564fe9efeb4241b1c93bb1f9b4a27082b655b3d/build/style/zTreeStyle/img/diy/8.png -------------------------------------------------------------------------------- /build/style/zTreeStyle/img/diy/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i5ting/How-to-write-jQuery-plugin/8564fe9efeb4241b1c93bb1f9b4a27082b655b3d/build/style/zTreeStyle/img/diy/9.png -------------------------------------------------------------------------------- /build/style/zTreeStyle/img/line_conn.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i5ting/How-to-write-jQuery-plugin/8564fe9efeb4241b1c93bb1f9b4a27082b655b3d/build/style/zTreeStyle/img/line_conn.gif -------------------------------------------------------------------------------- /build/style/zTreeStyle/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i5ting/How-to-write-jQuery-plugin/8564fe9efeb4241b1c93bb1f9b4a27082b655b3d/build/style/zTreeStyle/img/loading.gif -------------------------------------------------------------------------------- /build/style/zTreeStyle/img/zTreeStandard.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i5ting/How-to-write-jQuery-plugin/8564fe9efeb4241b1c93bb1f9b4a27082b655b3d/build/style/zTreeStyle/img/zTreeStandard.gif -------------------------------------------------------------------------------- /build/style/zTreeStyle/img/zTreeStandard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i5ting/How-to-write-jQuery-plugin/8564fe9efeb4241b1c93bb1f9b4a27082b655b3d/build/style/zTreeStyle/img/zTreeStandard.png -------------------------------------------------------------------------------- /build/style/zTreeStyle/zTreeStyle.css: -------------------------------------------------------------------------------- 1 | /*------------------------------------- 2 | zTree Style 3 | 4 | version: 3.4 5 | author: Hunter.z 6 | email: hunter.z@263.net 7 | website: http://code.google.com/p/jquerytree/ 8 | 9 | -------------------------------------*/ 10 | 11 | .ztree * {padding:0; margin:0; font-size:12px; font-family: Verdana, Arial, Helvetica, AppleGothic, sans-serif} 12 | .ztree {margin:0; padding:5px; color:#333} 13 | .ztree li{padding:0; margin:0; list-style:none; line-height:14px; text-align:left; white-space:nowrap; outline:0} 14 | .ztree li ul{ margin:0; padding:0 0 0 18px} 15 | .ztree li ul.line{ background:url(./img/line_conn.gif) 0 0 repeat-y;} 16 | 17 | .ztree li a {padding:1px 3px 0 0; margin:0; cursor:pointer; height:17px; color:#333; background-color: transparent; 18 | text-decoration:none; vertical-align:top; display: inline-block} 19 | .ztree li a:hover {text-decoration:underline} 20 | .ztree li a.curSelectedNode {padding-top:0px; background-color:#FFE6B0; color:black; height:16px; border:1px #FFB951 solid; opacity:0.8;} 21 | .ztree li a.curSelectedNode_Edit {padding-top:0px; background-color:#FFE6B0; color:black; height:16px; border:1px #FFB951 solid; opacity:0.8;} 22 | .ztree li a.tmpTargetNode_inner {padding-top:0px; background-color:#316AC5; color:white; height:16px; border:1px #316AC5 solid; 23 | opacity:0.8; filter:alpha(opacity=80)} 24 | .ztree li a.tmpTargetNode_prev {} 25 | .ztree li a.tmpTargetNode_next {} 26 | .ztree li a input.rename {height:14px; width:80px; padding:0; margin:0; 27 | font-size:12px; border:1px #7EC4CC solid; *border:0px} 28 | .ztree li span {line-height:16px; margin-right:2px} 29 | .ztree li span.button {line-height:0; margin:0; width:16px; height:16px; display: inline-block; vertical-align:middle; 30 | border:0 none; cursor: pointer;outline:none; 31 | background-color:transparent; background-repeat:no-repeat; background-attachment: scroll; 32 | background-image:url("./img/zTreeStandard.png"); *background-image:url("./img/zTreeStandard.gif")} 33 | 34 | .ztree li span.button.chk {width:13px; height:13px; margin:0 3px 0 0; cursor: auto} 35 | .ztree li span.button.chk.checkbox_false_full {background-position:0 0} 36 | .ztree li span.button.chk.checkbox_false_full_focus {background-position:0 -14px} 37 | .ztree li span.button.chk.checkbox_false_part {background-position:0 -28px} 38 | .ztree li span.button.chk.checkbox_false_part_focus {background-position:0 -42px} 39 | .ztree li span.button.chk.checkbox_false_disable {background-position:0 -56px} 40 | .ztree li span.button.chk.checkbox_true_full {background-position:-14px 0} 41 | .ztree li span.button.chk.checkbox_true_full_focus {background-position:-14px -14px} 42 | .ztree li span.button.chk.checkbox_true_part {background-position:-14px -28px} 43 | .ztree li span.button.chk.checkbox_true_part_focus {background-position:-14px -42px} 44 | .ztree li span.button.chk.checkbox_true_disable {background-position:-14px -56px} 45 | .ztree li span.button.chk.radio_false_full {background-position:-28px 0} 46 | .ztree li span.button.chk.radio_false_full_focus {background-position:-28px -14px} 47 | .ztree li span.button.chk.radio_false_part {background-position:-28px -28px} 48 | .ztree li span.button.chk.radio_false_part_focus {background-position:-28px -42px} 49 | .ztree li span.button.chk.radio_false_disable {background-position:-28px -56px} 50 | .ztree li span.button.chk.radio_true_full {background-position:-42px 0} 51 | .ztree li span.button.chk.radio_true_full_focus {background-position:-42px -14px} 52 | .ztree li span.button.chk.radio_true_part {background-position:-42px -28px} 53 | .ztree li span.button.chk.radio_true_part_focus {background-position:-42px -42px} 54 | .ztree li span.button.chk.radio_true_disable {background-position:-42px -56px} 55 | 56 | .ztree li span.button.switch {width:18px; height:18px} 57 | .ztree li span.button.root_open{background-position:-92px -54px} 58 | .ztree li span.button.root_close{background-position:-74px -54px} 59 | .ztree li span.button.roots_open{background-position:-92px 0} 60 | .ztree li span.button.roots_close{background-position:-74px 0} 61 | .ztree li span.button.center_open{background-position:-92px -18px} 62 | .ztree li span.button.center_close{background-position:-74px -18px} 63 | .ztree li span.button.bottom_open{background-position:-92px -36px} 64 | .ztree li span.button.bottom_close{background-position:-74px -36px} 65 | .ztree li span.button.noline_open{background-position:-92px -72px} 66 | .ztree li span.button.noline_close{background-position:-74px -72px} 67 | .ztree li span.button.root_docu{ background:none;} 68 | .ztree li span.button.roots_docu{background-position:-56px 0} 69 | .ztree li span.button.center_docu{background-position:-56px -18px} 70 | .ztree li span.button.bottom_docu{background-position:-56px -36px} 71 | .ztree li span.button.noline_docu{ background:none;} 72 | 73 | .ztree li span.button.ico_open{margin-right:2px; background-position:-110px -16px; vertical-align:top; *vertical-align:middle} 74 | .ztree li span.button.ico_close{margin-right:2px; background-position:-110px 0; vertical-align:top; *vertical-align:middle} 75 | .ztree li span.button.ico_docu{margin-right:2px; background-position:-110px -32px; vertical-align:top; *vertical-align:middle} 76 | .ztree li span.button.edit {margin-right:2px; background-position:-110px -48px; vertical-align:top; *vertical-align:middle} 77 | .ztree li span.button.remove {margin-right:2px; background-position:-110px -64px; vertical-align:top; *vertical-align:middle} 78 | 79 | .ztree li span.button.ico_loading{margin-right:2px; background:url(./img/loading.gif) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle} 80 | 81 | ul.tmpTargetzTree {background-color:#FFE6B0; opacity:0.8; filter:alpha(opacity=80)} 82 | 83 | span.tmpzTreeMove_arrow {width:16px; height:16px; display: inline-block; padding:0; margin:2px 0 0 1px; border:0 none; position:absolute; 84 | background-color:transparent; background-repeat:no-repeat; background-attachment: scroll; 85 | background-position:-110px -80px; background-image:url("./img/zTreeStandard.png"); *background-image:url("./img/zTreeStandard.gif")} 86 | 87 | ul.ztree.zTreeDragUL {margin:0; padding:0; position:absolute; width:auto; height:auto;overflow:hidden; background-color:#cfcfcf; border:1px #00B83F dotted; opacity:0.8; filter:alpha(opacity=80)} 88 | .zTreeMask {z-index:10000; background-color:#cfcfcf; opacity:0.0; filter:alpha(opacity=0); position:absolute} 89 | 90 | /* level style*/ 91 | /*.ztree li span.button.level0 { 92 | display:none; 93 | } 94 | .ztree li ul.level0 { 95 | padding:0; 96 | background:none; 97 | }*/ -------------------------------------------------------------------------------- /examples/jquery_plugin/first/jQuery.tab.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 34 | 35 | 36 |
37 |
    38 |
  • 选项卡一
  • 39 |
  • 选项卡二
  • 40 |
  • 选项卡三
  • 41 |
42 | 43 |
我是第一个内容
44 |
我是第二个内容
45 |
我是第三个内容
46 |
47 | 48 | 57 | 58 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_first/jQuery.tab.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | second tab example 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 | 36 | 37 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_first/jQuery.tab_more.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | second tab example 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 | 58 | 59 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_first/tab.css: -------------------------------------------------------------------------------- 1 | *{ 2 | margin: 0; 3 | padding: 0; 4 | list-style: none; 5 | } 6 | #tab { 7 | width: 600px; 8 | height: 300px; 9 | border: 1px solid #ccc; 10 | } 11 | .tab_content > div{ 12 | display: none; 13 | } 14 | .tab_content .active{ 15 | display:block; 16 | } 17 | .tab_header ul{ 18 | height: 50px; 19 | line-height: 50px; 20 | border-bottom: 1px solid #ccc; 21 | } 22 | .tab_header li { 23 | float: left; 24 | width: 200px; 25 | text-align: center;; 26 | } 27 | .tab_header li.active{ 28 | background: #ccc; 29 | } -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_first/tab.js: -------------------------------------------------------------------------------- 1 | ;(function($) { 2 | 3 | $.fn.tab = function(options) { 4 | // 将defaults 和 options 参数合并到{} 5 | var opts = $.extend({},$.fn.tab.defaults,options); 6 | 7 | return this.each(function() { 8 | var obj = $(this); 9 | 10 | $(obj).find('.tab_header li').on('mouseover', function (){ 11 | $(obj).find('.tab_header li').removeClass('active'); 12 | $(this).addClass('active'); 13 | 14 | $(obj).find('.tab_content div').hide(); 15 | $(obj).find('.tab_content div').eq($(this).index()).show(); 16 | }) 17 | }); 18 | // each end 19 | } 20 | 21 | //定义默认 22 | $.fn.tab.defaults = { 23 | 24 | }; 25 | 26 | })(jQuery); -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_four/jQuery.tab.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | second tab example 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 | 36 | 37 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_four/jQuery.tab_more.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | second tab example 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 | 63 | 64 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_four/tab.css: -------------------------------------------------------------------------------- 1 | *{ 2 | margin: 0; 3 | padding: 0; 4 | list-style: none; 5 | } 6 | #tab { 7 | width: 600px; 8 | height: 300px; 9 | border: 1px solid #ccc; 10 | } 11 | .tab_content > div{ 12 | display: none; 13 | } 14 | .tab_content .active{ 15 | display:block; 16 | } 17 | .tab_header ul{ 18 | height: 50px; 19 | line-height: 50px; 20 | border-bottom: 1px solid #ccc; 21 | } 22 | .tab_header li { 23 | float: left; 24 | width: 200px; 25 | text-align: center;; 26 | } 27 | .tab_header li.active{ 28 | background: #ccc; 29 | } -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_four/tab.js: -------------------------------------------------------------------------------- 1 | ;(function($) { 2 | 3 | /** 4 | * 公共函数: 初始化tab出发事件 5 | */ 6 | function init_tab_trigger_event(container,opts) { 7 | $(container).find('.tab_header li').on(opts.trigger_event_type, function () { 8 | $(container).find('.tab_header li').removeClass('active'); 9 | $(this).addClass('active'); 10 | 11 | $(container).find('.tab_content div').hide(); 12 | $(container).find('.tab_content div').eq($(this).index()).show(); 13 | 14 | opts.change($(this).index()); 15 | }) 16 | } 17 | 18 | /** 19 | * 公共函数: 初始化tab出发事件 20 | */ 21 | function init_with_config(opts) { 22 | // 调用私有函数 23 | _init_aaa_with_config(opts); 24 | 25 | // 调用私有函数 26 | _init_bbb_with_config(opts); 27 | 28 | // 调用私有函数 29 | _init_ccc_with_config(opts); 30 | } 31 | 32 | /** 33 | * 私有函数 34 | */ 35 | function _init_aaa_with_config(opts) { 36 | 37 | } 38 | 39 | function _init_bbb_with_config(opts) { 40 | 41 | } 42 | 43 | function _init_ccc_with_config(opts) { 44 | 45 | } 46 | 47 | $.fn.tab = function(options) { 48 | // 将defaults 和 options 参数合并到{} 49 | var opts = $.extend({},$.fn.tab.defaults,options); 50 | 51 | return this.each(function() { 52 | var obj = $(this); 53 | 54 | // 根据配置进行初始化 55 | init_with_config(opts); 56 | 57 | // 初始化tab出发事件 58 | init_tab_trigger_event(obj,opts); 59 | }); 60 | // each end 61 | } 62 | 63 | //定义默认 64 | $.fn.tab.defaults = { 65 | trigger_event_type:'click', //mouseover | click 默认是click 66 | change: function(index) { 67 | console.log('current index = ' + index); 68 | } 69 | }; 70 | 71 | })(jQuery); -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_grunt/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_grunt/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "curly": true, 3 | "eqeqeq": true, 4 | "immed": true, 5 | "latedef": true, 6 | "newcap": true, 7 | "noarg": true, 8 | "sub": true, 9 | "undef": true, 10 | "unused": true, 11 | "boss": true, 12 | "eqnull": true, 13 | "node": true 14 | } 15 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_grunt/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ## Important notes 4 | Please don't edit files in the `dist` subdirectory as they are generated via Grunt. You'll find source code in the `src` subdirectory! 5 | 6 | ### Code style 7 | Regarding code style like indentation and whitespace, **follow the conventions you see used in the source already.** 8 | 9 | ### PhantomJS 10 | While Grunt can run the included unit tests via [PhantomJS](http://phantomjs.org/), this shouldn't be considered a substitute for the real thing. Please be sure to test the `test/*.html` unit test file(s) in _actual_ browsers. 11 | 12 | ## Modifying the code 13 | First, ensure that you have the latest [Node.js](http://nodejs.org/) and [npm](http://npmjs.org/) installed. 14 | 15 | Test that Grunt's CLI is installed by running `grunt --version`. If the command isn't found, run `npm install -g grunt-cli`. For more information about installing Grunt, see the [getting started guide](http://gruntjs.com/getting-started). 16 | 17 | 1. Fork and clone the repo. 18 | 1. Run `npm install` to install all dependencies (including Grunt). 19 | 1. Run `grunt` to grunt this project. 20 | 21 | Assuming that you don't see any red, you're ready to go. Just be sure to run `grunt` after making any changes, to ensure that nothing is broken. 22 | 23 | ## Submitting pull requests 24 | 25 | 1. Create a new branch, please don't work in your `master` branch directly. 26 | 1. Add failing tests for the change you want to make. Run `grunt` to see the tests fail. 27 | 1. Fix stuff. 28 | 1. Run `grunt` to see if the tests pass. Repeat steps 2-4 until done. 29 | 1. Open `test/*.html` unit test file(s) in actual browser to ensure tests pass everywhere. 30 | 1. Update the documentation to reflect any changes. 31 | 1. Push to your fork and submit a pull request. 32 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_grunt/Gruntfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(grunt) { 4 | 5 | // Project configuration. 6 | grunt.initConfig({ 7 | // Metadata. 8 | pkg: grunt.file.readJSON('i5ting-mobile.jquery.json'), 9 | banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' + 10 | '<%= grunt.template.today("yyyy-mm-dd") %>\n' + 11 | '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' + 12 | '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' + 13 | ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n', 14 | // Task configuration. 15 | clean: { 16 | files: ['dist'] 17 | }, 18 | concat: { 19 | options: { 20 | banner: '<%= banner %>', 21 | stripBanners: true 22 | }, 23 | dist: { 24 | src: ['src/<%= pkg.name %>.js'], 25 | dest: 'dist/<%= pkg.name %>.js' 26 | }, 27 | }, 28 | uglify: { 29 | options: { 30 | banner: '<%= banner %>' 31 | }, 32 | dist: { 33 | src: '<%= concat.dist.dest %>', 34 | dest: 'dist/<%= pkg.name %>.min.js' 35 | }, 36 | }, 37 | qunit: { 38 | files: ['test/**/*.html'] 39 | }, 40 | jshint: { 41 | gruntfile: { 42 | options: { 43 | jshintrc: '.jshintrc' 44 | }, 45 | src: 'Gruntfile.js' 46 | }, 47 | src: { 48 | options: { 49 | jshintrc: 'src/.jshintrc' 50 | }, 51 | src: ['src/**/*.js'] 52 | }, 53 | test: { 54 | options: { 55 | jshintrc: 'test/.jshintrc' 56 | }, 57 | src: ['test/**/*.js'] 58 | }, 59 | }, 60 | watch: { 61 | gruntfile: { 62 | files: '<%= jshint.gruntfile.src %>', 63 | tasks: ['jshint:gruntfile'] 64 | }, 65 | src: { 66 | files: '<%= jshint.src.src %>', 67 | tasks: ['jshint:src', 'qunit'] 68 | }, 69 | test: { 70 | files: '<%= jshint.test.src %>', 71 | tasks: ['jshint:test', 'qunit'] 72 | }, 73 | }, 74 | }); 75 | 76 | // These plugins provide necessary tasks. 77 | grunt.loadNpmTasks('grunt-contrib-clean'); 78 | grunt.loadNpmTasks('grunt-contrib-concat'); 79 | grunt.loadNpmTasks('grunt-contrib-uglify'); 80 | grunt.loadNpmTasks('grunt-contrib-qunit'); 81 | grunt.loadNpmTasks('grunt-contrib-jshint'); 82 | grunt.loadNpmTasks('grunt-contrib-watch'); 83 | 84 | // Default task. 85 | grunt.registerTask('default', ['jshint', 'qunit', 'clean', 'concat', 'uglify']); 86 | 87 | }; 88 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_grunt/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 i5ting 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_grunt/README.md: -------------------------------------------------------------------------------- 1 | # I5ting Mobile 2 | 3 | this is a test jq plugin 4 | 5 | ## Getting Started 6 | Download the [production version][min] or the [development version][max]. 7 | 8 | [min]: https://raw.github.com/i5ting/How-to-write-jQuery-plugin/master/dist/i5ting-mobile.min.js 9 | [max]: https://raw.github.com/i5ting/How-to-write-jQuery-plugin/master/dist/i5ting-mobile.js 10 | 11 | In your web page: 12 | 13 | ```html 14 | 15 | 16 | 21 | ``` 22 | 23 | ## Documentation 24 | _(Coming soon)_ 25 | 26 | ## Examples 27 | _(Coming soon)_ 28 | 29 | ## Release History 30 | _(Nothing yet)_ 31 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_grunt/dist/i5ting-mobile.js: -------------------------------------------------------------------------------- 1 | /*! I5ting Mobile - v0.1.0 - 2014-02-11 2 | * https://github.com/i5ting/How-to-write-jQuery-plugin 3 | * Copyright (c) 2014 i5ting; Licensed MIT */ 4 | (function($) { 5 | 6 | // Collection method. 7 | $.fn.awesome = function() { 8 | return this.each(function(i) { 9 | // Do something awesome to each selected element. 10 | $(this).html('awesome' + i); 11 | }); 12 | }; 13 | 14 | // Static method. 15 | $.awesome = function(options) { 16 | // Override default options with passed-in options. 17 | options = $.extend({}, $.awesome.options, options); 18 | // Return something awesome. 19 | return 'awesome' + options.punctuation; 20 | }; 21 | 22 | // Static method default options. 23 | $.awesome.options = { 24 | punctuation: '.' 25 | }; 26 | 27 | // Custom selector. 28 | $.expr[':'].awesome = function(elem) { 29 | // Is this element awesome? 30 | return $(elem).text().indexOf('awesome') !== -1; 31 | }; 32 | 33 | }(jQuery)); 34 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_grunt/dist/i5ting-mobile.min.js: -------------------------------------------------------------------------------- 1 | /*! I5ting Mobile - v0.1.0 - 2014-02-11 2 | * https://github.com/i5ting/How-to-write-jQuery-plugin 3 | * Copyright (c) 2014 i5ting; Licensed MIT */ 4 | !function(a){a.fn.awesome=function(){return this.each(function(b){a(this).html("awesome"+b)})},a.awesome=function(b){return b=a.extend({},a.awesome.options,b),"awesome"+b.punctuation},a.awesome.options={punctuation:"."},a.expr[":"].awesome=function(b){return-1!==a(b).text().indexOf("awesome")}}(jQuery); -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_grunt/i5ting-mobile.jquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "i5ting-mobile", 3 | "title": "I5ting Mobile", 4 | "description": "this is a test jq plugin", 5 | "version": "0.1.0", 6 | "homepage": "https://github.com/i5ting/How-to-write-jQuery-plugin", 7 | "author": { 8 | "name": "i5ting", 9 | "email": "i5ting@126.com" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git://github.com/i5ting/How-to-write-jQuery-plugin.git" 14 | }, 15 | "bugs": "https://github.com/i5ting/How-to-write-jQuery-plugin/issues", 16 | "licenses": [ 17 | { 18 | "type": "MIT", 19 | "url": "https://github.com/i5ting/How-to-write-jQuery-plugin/blob/master/LICENSE-MIT" 20 | } 21 | ], 22 | "dependencies": { 23 | "jquery": "*" 24 | }, 25 | "keywords": [] 26 | } -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_grunt/libs/jquery-loader.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | // Default to the local version. 3 | var path = '../libs/jquery/jquery.js'; 4 | // Get any jquery=___ param from the query string. 5 | var jqversion = location.search.match(/[?&]jquery=(.*?)(?=&|$)/); 6 | // If a version was specified, use that version from code.jquery.com. 7 | if (jqversion) { 8 | path = 'http://code.jquery.com/jquery-' + jqversion[1] + '.js'; 9 | } 10 | // This is the only time I'll ever use document.write, I promise! 11 | document.write(''); 12 | }()); 13 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_grunt/libs/qunit/qunit.css: -------------------------------------------------------------------------------- 1 | /** 2 | * QUnit v1.11.0 - A JavaScript Unit Testing Framework 3 | * 4 | * http://qunitjs.com 5 | * 6 | * Copyright 2012 jQuery Foundation and other contributors 7 | * Released under the MIT license. 8 | * http://jquery.org/license 9 | */ 10 | 11 | /** Font Family and Sizes */ 12 | 13 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { 14 | font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; 15 | } 16 | 17 | #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } 18 | #qunit-tests { font-size: smaller; } 19 | 20 | 21 | /** Resets */ 22 | 23 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter { 24 | margin: 0; 25 | padding: 0; 26 | } 27 | 28 | 29 | /** Header */ 30 | 31 | #qunit-header { 32 | padding: 0.5em 0 0.5em 1em; 33 | 34 | color: #8699a4; 35 | background-color: #0d3349; 36 | 37 | font-size: 1.5em; 38 | line-height: 1em; 39 | font-weight: normal; 40 | 41 | border-radius: 5px 5px 0 0; 42 | -moz-border-radius: 5px 5px 0 0; 43 | -webkit-border-top-right-radius: 5px; 44 | -webkit-border-top-left-radius: 5px; 45 | } 46 | 47 | #qunit-header a { 48 | text-decoration: none; 49 | color: #c2ccd1; 50 | } 51 | 52 | #qunit-header a:hover, 53 | #qunit-header a:focus { 54 | color: #fff; 55 | } 56 | 57 | #qunit-testrunner-toolbar label { 58 | display: inline-block; 59 | padding: 0 .5em 0 .1em; 60 | } 61 | 62 | #qunit-banner { 63 | height: 5px; 64 | } 65 | 66 | #qunit-testrunner-toolbar { 67 | padding: 0.5em 0 0.5em 2em; 68 | color: #5E740B; 69 | background-color: #eee; 70 | overflow: hidden; 71 | } 72 | 73 | #qunit-userAgent { 74 | padding: 0.5em 0 0.5em 2.5em; 75 | background-color: #2b81af; 76 | color: #fff; 77 | text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; 78 | } 79 | 80 | #qunit-modulefilter-container { 81 | float: right; 82 | } 83 | 84 | /** Tests: Pass/Fail */ 85 | 86 | #qunit-tests { 87 | list-style-position: inside; 88 | } 89 | 90 | #qunit-tests li { 91 | padding: 0.4em 0.5em 0.4em 2.5em; 92 | border-bottom: 1px solid #fff; 93 | list-style-position: inside; 94 | } 95 | 96 | #qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { 97 | display: none; 98 | } 99 | 100 | #qunit-tests li strong { 101 | cursor: pointer; 102 | } 103 | 104 | #qunit-tests li a { 105 | padding: 0.5em; 106 | color: #c2ccd1; 107 | text-decoration: none; 108 | } 109 | #qunit-tests li a:hover, 110 | #qunit-tests li a:focus { 111 | color: #000; 112 | } 113 | 114 | #qunit-tests li .runtime { 115 | float: right; 116 | font-size: smaller; 117 | } 118 | 119 | .qunit-assert-list { 120 | margin-top: 0.5em; 121 | padding: 0.5em; 122 | 123 | background-color: #fff; 124 | 125 | border-radius: 5px; 126 | -moz-border-radius: 5px; 127 | -webkit-border-radius: 5px; 128 | } 129 | 130 | .qunit-collapsed { 131 | display: none; 132 | } 133 | 134 | #qunit-tests table { 135 | border-collapse: collapse; 136 | margin-top: .2em; 137 | } 138 | 139 | #qunit-tests th { 140 | text-align: right; 141 | vertical-align: top; 142 | padding: 0 .5em 0 0; 143 | } 144 | 145 | #qunit-tests td { 146 | vertical-align: top; 147 | } 148 | 149 | #qunit-tests pre { 150 | margin: 0; 151 | white-space: pre-wrap; 152 | word-wrap: break-word; 153 | } 154 | 155 | #qunit-tests del { 156 | background-color: #e0f2be; 157 | color: #374e0c; 158 | text-decoration: none; 159 | } 160 | 161 | #qunit-tests ins { 162 | background-color: #ffcaca; 163 | color: #500; 164 | text-decoration: none; 165 | } 166 | 167 | /*** Test Counts */ 168 | 169 | #qunit-tests b.counts { color: black; } 170 | #qunit-tests b.passed { color: #5E740B; } 171 | #qunit-tests b.failed { color: #710909; } 172 | 173 | #qunit-tests li li { 174 | padding: 5px; 175 | background-color: #fff; 176 | border-bottom: none; 177 | list-style-position: inside; 178 | } 179 | 180 | /*** Passing Styles */ 181 | 182 | #qunit-tests li li.pass { 183 | color: #3c510c; 184 | background-color: #fff; 185 | border-left: 10px solid #C6E746; 186 | } 187 | 188 | #qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } 189 | #qunit-tests .pass .test-name { color: #366097; } 190 | 191 | #qunit-tests .pass .test-actual, 192 | #qunit-tests .pass .test-expected { color: #999999; } 193 | 194 | #qunit-banner.qunit-pass { background-color: #C6E746; } 195 | 196 | /*** Failing Styles */ 197 | 198 | #qunit-tests li li.fail { 199 | color: #710909; 200 | background-color: #fff; 201 | border-left: 10px solid #EE5757; 202 | white-space: pre; 203 | } 204 | 205 | #qunit-tests > li:last-child { 206 | border-radius: 0 0 5px 5px; 207 | -moz-border-radius: 0 0 5px 5px; 208 | -webkit-border-bottom-right-radius: 5px; 209 | -webkit-border-bottom-left-radius: 5px; 210 | } 211 | 212 | #qunit-tests .fail { color: #000000; background-color: #EE5757; } 213 | #qunit-tests .fail .test-name, 214 | #qunit-tests .fail .module-name { color: #000000; } 215 | 216 | #qunit-tests .fail .test-actual { color: #EE5757; } 217 | #qunit-tests .fail .test-expected { color: green; } 218 | 219 | #qunit-banner.qunit-fail { background-color: #EE5757; } 220 | 221 | 222 | /** Result */ 223 | 224 | #qunit-testresult { 225 | padding: 0.5em 0.5em 0.5em 2.5em; 226 | 227 | color: #2b81af; 228 | background-color: #D2E0E6; 229 | 230 | border-bottom: 1px solid white; 231 | } 232 | #qunit-testresult .module-name { 233 | font-weight: bold; 234 | } 235 | 236 | /** Fixture */ 237 | 238 | #qunit-fixture { 239 | position: absolute; 240 | top: -10000px; 241 | left: -10000px; 242 | width: 1000px; 243 | height: 1000px; 244 | } 245 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_grunt/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-plugin", 3 | "version": "0.0.0-ignored", 4 | "engines": { 5 | "node": ">= 0.8.0" 6 | }, 7 | "scripts": { 8 | "test": "grunt qunit" 9 | }, 10 | "devDependencies": { 11 | "grunt-contrib-jshint": "~0.6.0", 12 | "grunt-contrib-qunit": "~0.2.0", 13 | "grunt-contrib-concat": "~0.3.0", 14 | "grunt-contrib-uglify": "~0.2.0", 15 | "grunt-contrib-watch": "~0.4.0", 16 | "grunt-contrib-clean": "~0.4.0", 17 | "grunt": "~0.4.2" 18 | } 19 | } -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_grunt/src/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "curly": true, 3 | "eqeqeq": true, 4 | "immed": true, 5 | "latedef": true, 6 | "newcap": true, 7 | "noarg": true, 8 | "sub": true, 9 | "undef": true, 10 | "unused": true, 11 | "boss": true, 12 | "eqnull": true, 13 | "browser": true, 14 | "predef": ["jQuery"] 15 | } 16 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_grunt/src/i5ting-mobile.js: -------------------------------------------------------------------------------- 1 | /* 2 | * i5ting-mobile 3 | * https://github.com/i5ting/How-to-write-jQuery-plugin 4 | * 5 | * Copyright (c) 2014 i5ting 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | (function($) { 10 | 11 | // Collection method. 12 | $.fn.awesome = function() { 13 | return this.each(function(i) { 14 | // Do something awesome to each selected element. 15 | $(this).html('awesome' + i); 16 | }); 17 | }; 18 | 19 | // Static method. 20 | $.awesome = function(options) { 21 | // Override default options with passed-in options. 22 | options = $.extend({}, $.awesome.options, options); 23 | // Return something awesome. 24 | return 'awesome' + options.punctuation; 25 | }; 26 | 27 | // Static method default options. 28 | $.awesome.options = { 29 | punctuation: '.' 30 | }; 31 | 32 | // Custom selector. 33 | $.expr[':'].awesome = function(elem) { 34 | // Is this element awesome? 35 | return $(elem).text().indexOf('awesome') !== -1; 36 | }; 37 | 38 | }(jQuery)); 39 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_grunt/test/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "curly": true, 3 | "eqeqeq": true, 4 | "immed": true, 5 | "latedef": true, 6 | "newcap": true, 7 | "noarg": true, 8 | "sub": true, 9 | "undef": true, 10 | "unused": true, 11 | "boss": true, 12 | "eqnull": true, 13 | "browser": true, 14 | "predef": [ 15 | "jQuery", 16 | "QUnit", 17 | "module", 18 | "test", 19 | "asyncTest", 20 | "expect", 21 | "start", 22 | "stop", 23 | "ok", 24 | "equal", 25 | "notEqual", 26 | "deepEqual", 27 | "notDeepEqual", 28 | "strictEqual", 29 | "notStrictEqual", 30 | "throws" 31 | ] 32 | } -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_grunt/test/i5ting-mobile.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | I5ting Mobile Test Suite 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 |
21 |
22 | lame test markup 23 | normal test markup 24 | awesome test markup 25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_grunt/test/i5ting-mobile_test.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | /* 3 | ======== A Handy Little QUnit Reference ======== 4 | http://api.qunitjs.com/ 5 | 6 | Test methods: 7 | module(name, {[setup][ ,teardown]}) 8 | test(name, callback) 9 | expect(numberOfAssertions) 10 | stop(increment) 11 | start(decrement) 12 | Test assertions: 13 | ok(value, [message]) 14 | equal(actual, expected, [message]) 15 | notEqual(actual, expected, [message]) 16 | deepEqual(actual, expected, [message]) 17 | notDeepEqual(actual, expected, [message]) 18 | strictEqual(actual, expected, [message]) 19 | notStrictEqual(actual, expected, [message]) 20 | throws(block, [expected], [message]) 21 | */ 22 | 23 | module('jQuery#awesome', { 24 | // This will run before each test in this module. 25 | setup: function() { 26 | this.elems = $('#qunit-fixture').children(); 27 | } 28 | }); 29 | 30 | test('is chainable', function() { 31 | expect(1); 32 | // Not a bad test to run on collection methods. 33 | strictEqual(this.elems.awesome(), this.elems, 'should be chainable'); 34 | }); 35 | 36 | test('is awesome', function() { 37 | expect(1); 38 | strictEqual(this.elems.awesome().text(), 'awesome0awesome1awesome2', 'should be awesome'); 39 | }); 40 | 41 | module('jQuery.awesome'); 42 | 43 | test('is awesome', function() { 44 | expect(2); 45 | strictEqual($.awesome(), 'awesome.', 'should be awesome'); 46 | strictEqual($.awesome({punctuation: '!'}), 'awesome!', 'should be thoroughly awesome'); 47 | }); 48 | 49 | module(':awesome selector', { 50 | // This will run before each test in this module. 51 | setup: function() { 52 | this.elems = $('#qunit-fixture').children(); 53 | } 54 | }); 55 | 56 | test('is awesome', function() { 57 | expect(1); 58 | // Use deepEqual & .get() when comparing jQuery objects. 59 | deepEqual(this.elems.filter(':awesome').get(), this.elems.last().get(), 'knows awesome when it sees it'); 60 | }); 61 | 62 | }(jQuery)); 63 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_second/jQuery.tab.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | second tab example 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 | 36 | 37 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_second/jQuery.tab_more.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | second tab example 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 | 63 | 64 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_second/tab.css: -------------------------------------------------------------------------------- 1 | *{ 2 | margin: 0; 3 | padding: 0; 4 | list-style: none; 5 | } 6 | #tab { 7 | width: 600px; 8 | height: 300px; 9 | border: 1px solid #ccc; 10 | } 11 | .tab_content > div{ 12 | display: none; 13 | } 14 | .tab_content .active{ 15 | display:block; 16 | } 17 | .tab_header ul{ 18 | height: 50px; 19 | line-height: 50px; 20 | border-bottom: 1px solid #ccc; 21 | } 22 | .tab_header li { 23 | float: left; 24 | width: 200px; 25 | text-align: center;; 26 | } 27 | .tab_header li.active{ 28 | background: #ccc; 29 | } -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_second/tab.js: -------------------------------------------------------------------------------- 1 | ;(function($) { 2 | 3 | $.fn.tab = function(options) { 4 | // 将defaults 和 options 参数合并到{} 5 | var opts = $.extend({},$.fn.tab.defaults,options); 6 | 7 | return this.each(function() { 8 | var obj = $(this); 9 | 10 | $(obj).find('.tab_header li').on(opts.trigger_event_type, function (){ 11 | $(obj).find('.tab_header li').removeClass('active'); 12 | $(this).addClass('active'); 13 | 14 | $(obj).find('.tab_content div').hide(); 15 | $(obj).find('.tab_content div').eq($(this).index()).show(); 16 | }) 17 | }); 18 | // each end 19 | } 20 | 21 | //定义默认 22 | $.fn.tab.defaults = { 23 | trigger_event_type:'click', //mouseover | click 默认是click 24 | }; 25 | 26 | })(jQuery); -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_three/jQuery.tab.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | second tab example 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 | 36 | 37 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_three/jQuery.tab_more.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | second tab example 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 | 63 | 64 | -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_three/tab.css: -------------------------------------------------------------------------------- 1 | *{ 2 | margin: 0; 3 | padding: 0; 4 | list-style: none; 5 | } 6 | #tab { 7 | width: 600px; 8 | height: 300px; 9 | border: 1px solid #ccc; 10 | } 11 | .tab_content > div{ 12 | display: none; 13 | } 14 | .tab_content .active{ 15 | display:block; 16 | } 17 | .tab_header ul{ 18 | height: 50px; 19 | line-height: 50px; 20 | border-bottom: 1px solid #ccc; 21 | } 22 | .tab_header li { 23 | float: left; 24 | width: 200px; 25 | text-align: center;; 26 | } 27 | .tab_header li.active{ 28 | background: #ccc; 29 | } -------------------------------------------------------------------------------- /examples/jquery_plugin/plugin_three/tab.js: -------------------------------------------------------------------------------- 1 | ;(function($) { 2 | 3 | $.fn.tab = function(options) { 4 | // 将defaults 和 options 参数合并到{} 5 | var opts = $.extend({},$.fn.tab.defaults,options); 6 | 7 | return this.each(function() { 8 | var obj = $(this); 9 | 10 | $(obj).find('.tab_header li').on(opts.trigger_event_type, function (){ 11 | $(obj).find('.tab_header li').removeClass('active'); 12 | $(this).addClass('active'); 13 | 14 | $(obj).find('.tab_content div').hide(); 15 | $(obj).find('.tab_content div').eq($(this).index()).show(); 16 | 17 | opts.change($(this).index()); 18 | }) 19 | }); 20 | // each end 21 | } 22 | 23 | //定义默认 24 | $.fn.tab.defaults = { 25 | trigger_event_type:'click', //mouseover | click 默认是click 26 | change: function(index){ 27 | console.log('current index = ' + index); 28 | } 29 | }; 30 | 31 | })(jQuery); -------------------------------------------------------------------------------- /examples/jquery_plugin/second/jQuery.tab.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | second tab example 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 | -------------------------------------------------------------------------------- /examples/jquery_plugin/second/jQuery.tab_more.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | second tab example 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 | -------------------------------------------------------------------------------- /examples/jquery_plugin/second/tab.css: -------------------------------------------------------------------------------- 1 | *{ 2 | margin: 0; 3 | padding: 0; 4 | list-style: none; 5 | } 6 | #tab { 7 | width: 600px; 8 | height: 300px; 9 | border: 1px solid #ccc; 10 | } 11 | .tab_content > div{ 12 | display: none; 13 | } 14 | .tab_content .active{ 15 | display:block; 16 | } 17 | .tab_header ul{ 18 | height: 50px; 19 | line-height: 50px; 20 | border-bottom: 1px solid #ccc; 21 | } 22 | .tab_header li { 23 | float: left; 24 | width: 200px; 25 | text-align: center;; 26 | } 27 | .tab_header li.active{ 28 | background: #ccc; 29 | } -------------------------------------------------------------------------------- /examples/jquery_plugin/second/tab.js: -------------------------------------------------------------------------------- 1 | ;$(function(){ 2 | $('.tab_header li').on('mouseover', function (){ 3 | $('.tab_header li').removeClass('active'); 4 | $(this).addClass('active'); 5 | 6 | $('.tab_content div').hide(); 7 | $('.tab_content div').eq($(this).index()).show(); 8 | }) 9 | }); -------------------------------------------------------------------------------- /src/.toc/template.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i5ting/How-to-write-jQuery-plugin/8564fe9efeb4241b1c93bb1f9b4a27082b655b3d/src/.toc/template.html -------------------------------------------------------------------------------- /src/images/jquery_plugin/debug_with_callback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i5ting/How-to-write-jQuery-plugin/8564fe9efeb4241b1c93bb1f9b4a27082b655b3d/src/images/jquery_plugin/debug_with_callback.png -------------------------------------------------------------------------------- /src/images/tab.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/i5ting/How-to-write-jQuery-plugin/8564fe9efeb4241b1c93bb1f9b4a27082b655b3d/src/images/tab.gif -------------------------------------------------------------------------------- /src/jquery.plugin.md: -------------------------------------------------------------------------------- 1 | # How to write jQuery plugin? 2 | 3 | 4 | ## 前言 5 | 6 | jQuery学习通常会经历三个阶段: 7 | 8 | - 会用jquery是第一阶段 9 | - 能抽象成插件是第二阶段 10 | - 让插件足够灵活强大是第三阶段 11 | 12 | 现在,知道自己处在什么阶段了么? 13 | 14 | 这里假设读者已经通过第一阶段。如果jQuery还不够熟悉,请继续http://api.jquery.com 15 | 16 | ## jQuery支持2种插件方式 17 | 18 | - $.somePlugin 19 | - $.fn.somePlugin 20 | 21 | ### Global工具类的插件 22 | 23 | 比如 24 | 25 | $.trim('hello world ') 26 | 27 | 这个方法是用于去掉空格的工具方法。它其实是给jQuery对象上增加了trim方法。 28 | 29 | 此种插件一般是工具类的方法。 30 | 31 | ### 基于selector的插件 32 | 33 | 比如 34 | 35 | $('.mytab').tab({ 36 | change: function(index){ 37 | console.log('current index = ' + index); 38 | } 39 | }); 40 | 41 | 这实际是一个tab插件最简单的用法。 42 | 43 | 这个插件的特点是它前面必须是选择器,那么就可以是一个也可以多个,因为选择器有很多种,选择器返回的是数组,比如例子中的.mytab,在一个html文档里可以有多个 44 | 45 | 比如 46 | 47 |
48 |
49 | 50 |
51 |
52 | 53 |
54 |
55 | 56 |
57 |
58 | 59 | 这样就可以形成4个tab里。 60 | 61 | jQuery的哲学是“write less,do more”,它做到了么? 62 | 63 | ### 我们要讲的是后者 64 | 65 | 相比较而言,工具类的插件基本没有难度,它就是普通的function,即没有配置也没有selector,所以这里不做介绍。 66 | 而基于selector的插件复用程度高,又是基于配置的,在实际中应用非常广泛,是我们本节介绍的重点。 67 | 68 | 69 | ## 什么是Tab? 70 | 71 | ![](images/tab.gif) 72 | 73 | ### 看一下小灰灰的tab v1 74 | 75 | [v1](examples/jquery_plugin/first/jQuery.tab.html) 76 | 77 | 78 | 79 | 80 | 81 | Document 82 | 110 | 111 | 112 |
113 |
    114 |
  • 选项卡一
  • 115 |
  • 选项卡二
  • 116 |
  • 选项卡三
  • 117 |
118 | 119 |
我是第一个内容
120 |
我是第二个内容
121 |
我是第三个内容
122 |
123 | 124 | 133 | 134 | 135 | 136 | ### 它有几个明显问题 137 | 138 | - 样式与js代码没有和html分离 139 | - tab功能实现里,但无法复用,因为他用的是id方式 140 | - tab的骨架html模板也不合理 141 | 142 | ### 狮子的故事 143 | 144 | 曾经有一个小伙伴,写下来这样的代码 145 | 146 | 151 | 152 | 然后我在读css代码的时候,发现 153 | 154 | .lion { 155 | ... 156 | } 157 | 158 | 我看了很久,lion是狮子的意思,那这里呢? 159 | 160 | 后来才明白,原来是li on的意思,也就是选中的tab的状态是on。 161 | 162 | 命名是非常容易闹笑话的,其实,这里用active更合适 163 | 164 | 165 | ### 看一下小灰灰的tab v2 166 | 167 | [v2](examples/jquery_plugin/second/jQuery.tab.html) 168 | 169 | 提取css和js的部分不是本章重点,下面比较一下重构后的tab骨架结构 170 | 171 | 之前的tab骨架 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 | // html 222 |
223 | 我是第一个内容 224 |
225 | 226 | // css 227 | .tab_content .active{ 228 | display:block; 229 | } 230 | 231 | 把行内样式抽象成状态,继而让代码更具可读性 232 | 233 | ### v2的js 234 | 235 | 结构改了,js也一定做了修改,tab.js具体内容如下: 236 | 237 | ;$(function(){ 238 | $('.tab_header li').on('mouseover', function (){ 239 | $('.tab_header li').removeClass('active'); 240 | $(this).addClass('active'); 241 | 242 | $('.tab_content div').hide(); 243 | $('.tab_content div').eq($(this).index()).show(); 244 | }) 245 | }); 246 | 247 | ### 点评 248 | 249 | v2的js只是根据tab的骨架接口修改而进行了简单修改,主要是dom selector的修改 250 | 251 | 没有什么特别值得说明的。 252 | 253 | ### 让我们看看一个页面多个tab,它如何? 254 | 255 | 详见 jQuery.tab_more.html 256 | 257 | 出现的问题是在第二个tab上滑动的时候,更新的是第一个tab content,这是为什么呢? 258 | 259 | 答:js代码写的太随意,没有注意控制组件自身管控范围 260 | 261 | ***不严谨是写代码的大忌*** 262 | 263 | ## 开始写第一个插件 264 | 265 | 代码位于plugin_first 266 | 267 | [plugin_first](examples/jquery_plugin/plugin_first/jQuery.tab.html) 268 | 269 | 让我们动手改造一下tab.js吧: 270 | 271 | ### 代码 272 | 273 | ;(function($) { 274 | 275 | $.fn.tab = function(options) { 276 | // 将defaults 和 options 参数合并到{} 277 | var opts = $.extend({},$.fn.tab.defaults,options); 278 | 279 | return this.each(function() { 280 | var obj = $(this); 281 | 282 | $(obj).find('.tab_header li').on('mouseover', function (){ 283 | $(obj).find('.tab_header li').removeClass('active'); 284 | $(this).addClass('active'); 285 | 286 | $(obj).find('.tab_content div').hide(); 287 | $(obj).find('.tab_content div').eq($(this).index()).show(); 288 | }) 289 | }); 290 | // each end 291 | } 292 | 293 | //定义默认 294 | $.fn.tab.defaults = { 295 | 296 | }; 297 | 298 | })(jQuery); 299 | 300 | 这段代码除了套用jQuery plugin模板外,就是几处select变成基于obj的查找的selector,其他与之前无异。 301 | 302 | 是不是很简单? 303 | 304 | ### 代码基础说明 305 | 306 | #### 命名空间 307 | 308 | 防止变量方法污染的 309 | 310 | (function($) { 311 | 312 | })(jQuery); 313 | 314 | #### 分号问题 315 | 316 | 防止被别人的代码暗箭所伤 317 | 318 | ;(function($) { 319 | 320 | })(jQuery); 321 | 322 | ### 配置项 323 | 324 | // 将defaults 和 options 参数合并到{} 325 | var opts = $.extend({},$.fn.tab.defaults,options); 326 | 327 | 上面的代码是大家会100%疑问的地方,在此做一个简要说明 328 | 329 | 首页要区分清楚 330 | 331 | - options是调用插件的时候传入的参数 332 | - $.fn.tab.defaults是一个写死的plain object 333 | - {}是一个写死的plain object 334 | 335 | 那么$.extend方法是jQuery的方法,它是用于属性或者方法合并的,也就是说options和$.fn.tab.defaults先合并,合并的时候已后面的options为主,如果 336 | 337 | $.fn.tab.defaults={ 338 | a : 0 339 | } 340 | 341 | 而options的是 342 | $('.tab').tab({ 343 | a : 1 344 | }); 345 | 346 | 那么合并的结果将是a = 1,即以后面的为主 347 | 348 | 如果options里没有b,而$.fn.tab.defaults里有b配置呢 349 | 350 | $.fn.tab.defaults={ 351 | a : 0, 352 | b : true 353 | } 354 | 355 | 那么合并的结果将是 356 | 357 | { 358 | a : 1, 359 | b : true 360 | } 361 | 362 | 如果后面没有前面有,此值就是前面的值,即插件的默认项 363 | 364 | 只有最前面的 365 | 366 | opts = $.extend({},***) 367 | 368 | 这是是一种防御性写法,保证返回的opts一定是一个plain object,仅此而已。 369 | 370 | 大家一定要记住,插件是以默认配置项为主,配置项是作为私人定制的高级需求用的。力求通用的同时,也要考虑足够的可扩展性,后面章节讲配置项的时候会详细说明。 371 | 372 | ### 缓存this 373 | 374 | // 将defaults 和 options 参数合并到{} 375 | var obj = $(this); 376 | 377 | 给每个对象增加$(obj)属于防御性写法,保证对象一定是jq对象【这属于个人习惯,可以不参考】,cache是说jquery的this是指代上下文,上下文变换的时候,this就找不到了 378 | 379 | 比如 380 | 381 | return this.each(function() { 382 | // this 1 383 | var obj = $(this); 384 | 385 | $(obj).find('.tab_header li').on('mouseover', function (){ 386 | $(obj).find('.tab_header li').removeClass('active'); 387 | 388 | // this 2 389 | $(this).addClass('active'); 390 | 391 | $(obj).find('.tab_content div').hide(); 392 | $(obj).find('.tab_content div').eq($(this).index()).show(); 393 | }) 394 | }); 395 | // each end 396 | 397 | 比较this1和this2的用法,如果之前没有定义obj,在事件回调函数里再想调用$('.tab')容器就非常麻烦了 398 | 399 | 此处的缓存主要是为了后面调用方便 400 | 401 | ### selector和$.fn 402 | 403 | 插件的定义是 404 | 405 | $.fn.tab = function(options){ 406 | return this.each(function(){ 407 | ... 408 | }); 409 | } 410 | 411 | 插件的用法是 412 | 413 | $('.tab').tab({ 414 | config.... 415 | }); 416 | 417 | 这样对比很容易得出 418 | 419 | $.fn其实就是jQuery的selector对象,给此对象增加的方法而已。 420 | 421 | ### 调用方式 422 | 423 | 428 | 429 | 是不是更简单? 430 | 431 | ### jQuery plugin template 432 | 433 | ;(function($) { 434 | 435 | $.fn.XXXXXX = function(options) { 436 | // 将defaults 和 options 参数合并到{} 437 | var opts = $.extend({},$.fn.XXXXXX.defaults,options); 438 | 439 | return this.each(function() { 440 | var obj = $(this); 441 | 442 | ... 443 | }); 444 | // each end 445 | } 446 | 447 | //定义默认 448 | $.fn.XXXXXX.defaults = { 449 | 450 | }; 451 | 452 | })(jQuery); 453 | 454 | ### 插件特点 455 | 456 | 1. 有默认项 457 | 458 | $.fn.XXXXXX.defaults 459 | 460 | 1. 基于selector 461 | 462 | return this.each(function() { 463 | var obj = $(this); 464 | 465 | ... 466 | }); 467 | 468 | 469 | 解读: 470 | 471 | - 有默认项,是约定大于配置,让用户用的时候如果没有个性化需求,可以很简单,安装插件的默认配置走,如果有个性化需求,修改配置项,同样很简单 472 | - 基于selector意味着你可以复用,给tag或class应用此插件,以便写更少代码,完成更多功能 473 | 474 | 475 | ***亲,你明白插件的好处了么?如果没明白继续往下看*** 476 | 477 | 478 | ## jQuery插件配置项 479 | 480 | 这其实算一个高级话题: 481 | 482 | - 会用jquery是第一阶段 483 | - 能抽象成插件是第二阶段 484 | - 让插件足够灵活强大是第三阶段 485 | 486 | 代码位于plugin_second 487 | 488 | 配置项分2类 489 | 490 | - 普通配置项 491 | - 回调函数 492 | 493 | ### 迭代1:普通配置项 494 | 495 | 回顾一下之前tab,发现我们的tab是只能鼠标移动到上面才能切换,那是不是所有tab都这样呢? 496 | 当然不是了,我们看到很多网站的tab都是点击切换的,那么我们如何能让我们的tab支持这2种方式呢? 497 | 498 | ### 支持tab触发事件选项 499 | 500 | ;(function($) { 501 | 502 | $.fn.tab = function(options) { 503 | // 将defaults 和 options 参数合并到{} 504 | var opts = $.extend({},$.fn.tab.defaults,options); 505 | 506 | return this.each(function() { 507 | var obj = $(this); 508 | 509 | $(obj).find('.tab_header li').on(opts.trigger_event_type, function (){ 510 | $(obj).find('.tab_header li').removeClass('active'); 511 | $(this).addClass('active'); 512 | 513 | $(obj).find('.tab_content div').hide(); 514 | $(obj).find('.tab_content div').eq($(this).index()).show(); 515 | }) 516 | }); 517 | // each end 518 | } 519 | 520 | //定义默认 521 | $.fn.tab.defaults = { 522 | trigger_event_type:'click', //mouseover | click 默认是click 523 | }; 524 | 525 | })(jQuery); 526 | 527 | 528 | 这就是普通配置项的例子,配置项的值是js支持的类型 529 | 530 | ### 示例1 531 | 532 | 首先看一下plugin_second/jQuery.tab.html它没有任何变化 533 | 534 | 539 | 540 | 默认项是click,所以这个tab只能点击 541 | 542 | ### 示例2 543 | 544 | 看一下plugin_second/jQuery.tab_more.html,第一个tab只能点击,第二个tab只能鼠标划过 545 | 546 | 556 | 557 | 这里补充一点:第一个tab完全和例子一样,既然默认项都是click,再写的话就真有点 558 | ***脱裤子放屁-多此一举*** 559 | 了 560 | 561 | 562 | [plugin_2](examples/jquery_plugin/plugin_second/jQuery.tab.html) 563 | 564 | ### 迭代2:回调函数 565 | 566 | jquery_plugin/plugin_three 567 | 568 | 既然用tab,就是利用它可以在一个地方显示多个内容,点击的时候切换对应的tab content,tab内容不可能都是静态的,那么这时候怎么办? 569 | 570 | 是不是应该在点击的时候更改内容呢?答案是回调函数,笨啦,前面不是说配置项有2种么? 571 | 572 | ### 回调函数 573 | 574 | 这就是普通配置项的例子,配置项的值是js支持的类型 575 | 576 | ;(function($) { 577 | 578 | $.fn.tab = function(options) { 579 | // 将defaults 和 options 参数合并到{} 580 | var opts = $.extend({},$.fn.tab.defaults,options); 581 | 582 | return this.each(function() { 583 | var obj = $(this); 584 | 585 | $(obj).find('.tab_header li').on(opts.trigger_event_type, function (){ 586 | $(obj).find('.tab_header li').removeClass('active'); 587 | $(this).addClass('active'); 588 | 589 | $(obj).find('.tab_content div').hide(); 590 | $(obj).find('.tab_content div').eq($(this).index()).show(); 591 | 592 | opts.change($(this).index()); 593 | }) 594 | }); 595 | // each end 596 | } 597 | 598 | //定义默认 599 | $.fn.tab.defaults = { 600 | trigger_event_type:'click', //mouseover | click 默认是click 601 | change: function(index){ 602 | console.log('current index = ' + index); 603 | } 604 | }; 605 | 606 | })(jQuery); 607 | 608 | ### 生效了么? 609 | 610 | 打开jquery_plugin/plugin_three/jQuery.tab.html 611 | 612 | ![](images/jquery_plugin/debug_with_callback.png) 613 | 614 | 615 | ### 变动 616 | 617 | 1. 增加了change配置项 618 | 619 | //定义默认 620 | $.fn.tab.defaults = { 621 | ...... 622 | change: function(index){ 623 | console.log('current index = ' + index); 624 | } 625 | }; 626 | 627 | 2. 在插件内部调用了此回调函数 628 | 629 | return this.each(function() { 630 | var obj = $(this); 631 | 632 | $(obj).find('.tab_header li').on(opts.trigger_event_type, function (){ 633 | ...... 634 | 635 | opts.change($(this).index()); 636 | }) 637 | }); 638 | 639 | 640 | ### 回调函数最需要注意的问题 641 | 642 | - 调用场合,在什么地方调用,这是生命周期的核心问题 643 | - 参数,确保在调用处有这些值 644 | - 回调函数也要有默认行为的 645 | 646 | [plugin_3](examples/jquery_plugin/plugin_three/jQuery.tab.html) 647 | 648 | ### 总结 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 |
配置项类型 数据类型 特点
普通配置项 js基本类型 不可变
回调函数配置项 函数可变行为
667 | 668 | ### 迭代3:重构代码 669 | 670 | jquery_plugin/plugin_four 671 | 672 | [plugin_4](examples/jquery_plugin/plugin_four/jQuery.tab.html) 673 | 674 | ;(function($) { 675 | 676 | /** 677 | * 公共函数: 初始化tab出发事件 678 | */ 679 | function init_tab_trigger_event(container,opts) { 680 | $(container).find('.tab_header li').on(opts.trigger_event_type, function (){ 681 | $(container).find('.tab_header li').removeClass('active'); 682 | $(this).addClass('active'); 683 | 684 | $(container).find('.tab_content div').hide(); 685 | $(container).find('.tab_content div').eq($(this).index()).show(); 686 | 687 | opts.change($(this).index()); 688 | }) 689 | } 690 | 691 | /** 692 | * 公共函数: 初始化tab出发事件 693 | */ 694 | function init_with_config(opts){ 695 | _init_aaa_with_config(opts); 696 | 697 | _init_bbb_with_config(opts); 698 | 699 | _init_ccc_with_config(opts); 700 | } 701 | 702 | /** 703 | * 私有函数 704 | */ 705 | function _init_aaa_with_config(opts){ 706 | 707 | } 708 | 709 | function _init_bbb_with_config(opts){ 710 | 711 | } 712 | 713 | function _init_ccc_with_config(opts){ 714 | 715 | } 716 | 717 | $.fn.tab = function(options) { 718 | // 将defaults 和 options 参数合并到{} 719 | var opts = $.extend({},$.fn.tab.defaults,options); 720 | 721 | return this.each(function() { 722 | var obj = $(this); 723 | 724 | // 根据配置进行初始化 725 | init_with_config(opts); 726 | 727 | // 初始化tab出发事件 728 | init_tab_trigger_event(obj,opts); 729 | }); 730 | // each end 731 | } 732 | 733 | //定义默认 734 | $.fn.tab.defaults = { 735 | trigger_event_type:'click', //mouseover | click 默认是click 736 | change: function(index){ 737 | console.log('current index = ' + index); 738 | } 739 | }; 740 | 741 | })(jQuery); 742 | 743 | ### 将插件核心逻辑,抽象成公共函数 744 | 745 | return this.each(function() { 746 | var obj = $(this); 747 | 748 | // 根据配置进行初始化 749 | init_with_config(opts); 750 | 751 | // 初始化tab出发事件 752 | init_tab_trigger_event(obj,opts); 753 | }); 754 | 755 | ### 将大的公共函数拆解成n个私有函数 756 | 757 | /** 758 | * 公共函数: 初始化tab出发事件 759 | */ 760 | function init_with_config(opts) { 761 | // 调用私有函数 762 | _init_aaa_with_config(opts); 763 | 764 | // 调用私有函数 765 | _init_bbb_with_config(opts); 766 | 767 | // 调用私有函数 768 | _init_ccc_with_config(opts); 769 | } 770 | 771 | /** 772 | * 私有函数 773 | */ 774 | function _init_aaa_with_config(opts) { 775 | 776 | } 777 | 778 | function _init_bbb_with_config(opts) { 779 | 780 | } 781 | 782 | function _init_ccc_with_config(opts) { 783 | 784 | } 785 | 786 | ### 注意注释和编码规范 787 | 788 | 函数注释 789 | 790 | /** 791 | * 私有函数 792 | */ 793 | function _init_aaa_with_config(opts) { 794 | 795 | } 796 | 797 | 函数内注释 798 | 799 | // 调用私有函数 800 | _init_ccc_with_config(opts); 801 | 802 | 函数体前面加一个空格 803 | 804 | 805 | ## 使用grunt创建项目 806 | 807 | [grunt](http://gruntjs.com/getting-started)是基于任务的构建工具,和make,rake,ant,cake,maven,gradle等是一样的 808 | 809 | ### 前置条件 810 | 811 | 前置条件需要有nodejs和npm,请确保已安装成功: 812 | 813 | npm install -g grunt 814 | npm install -g grunt-init 815 | git clone https://github.com/gruntjs/grunt-init-jquery.git ~/.grunt-init/jquery 816 | grunt-init jquery 817 | 818 | 如果是万恶的window系统,请修改: 819 | 820 | git clone https://github.com/gruntjs/grunt-init-jquery.git %USERPROFILE%/.grunt-init/jquery 821 | 822 | 823 | 另外如果是linux或者mac,使用-g安装的时候可能需要sudo权限,具体自己看日志 824 | 825 | ### 创建项目 826 | 827 | ➜ jquery_plugin git:(master) ✗ mkdir plugin_grunt 828 | ➜ jquery_plugin git:(master) ✗ cd plugin_grunt 829 | ➜ plugin_grunt git:(master) ✗ grunt-init jquery 830 | Running "init:jquery" (init) task 831 | This task will create one or more files in the current directory, based on the 832 | environment and the answers to a few questions. Note that answering "?" to any 833 | question will show question-specific help and answering "none" to most questions 834 | will leave its value blank. 835 | 836 | "jquery" template notes: 837 | Project name should not contain "jquery" or "js" and should be a unique ID not 838 | already in use at plugins.jquery.com. Project title should be a human-readable 839 | title, and doesn't need to contain the word "jQuery", although it may. For 840 | example, a plugin titled "Awesome Plugin" might have the name "awesome-plugin". 841 | 842 | For more information, please see the following documentation: 843 | 844 | Naming Your Plugin http://plugins.jquery.com/docs/names/ 845 | Publishing Your Plugin http://plugins.jquery.com/docs/publish/ 846 | Package Manifest http://plugins.jquery.com/docs/package-manifest/ 847 | 848 | Please answer the following: 849 | [?] Project name (plugin_grunt) i5ting-mobile 850 | [?] Project title (I5ting Mobile) 851 | [?] Description (The best jQuery plugin ever.) this is a test jq plugin 852 | [?] Version (0.1.0) 853 | [?] Project git repository (git://github.com/i5ting/How-to-write-jQuery-plugin.git) 854 | [?] Project homepage (https://github.com/i5ting/How-to-write-jQuery-plugin) 855 | [?] Project issues tracker (https://github.com/i5ting/How-to-write-jQuery-plugin/issues) 856 | [?] Licenses (MIT) 857 | [?] Author name (shiren1118) i5ting 858 | [?] Author email (shiren1118@126.com) i5ting@126.com 859 | [?] Author url (none) 860 | [?] Required jQuery version (*) 861 | [?] Do you need to make any changes to the above before continuing? (y/N) 862 | 863 | Writing .gitignore...OK 864 | Writing .jshintrc...OK 865 | Writing CONTRIBUTING.md...OK 866 | Writing Gruntfile.js...OK 867 | Writing README.md...OK 868 | Writing libs/jquery-loader.js...OK 869 | Writing libs/jquery/jquery.js...OK 870 | Writing libs/qunit/qunit.css...OK 871 | Writing libs/qunit/qunit.js...OK 872 | Writing src/.jshintrc...OK 873 | Writing src/i5ting-mobile.js...OK 874 | Writing test/.jshintrc...OK 875 | Writing test/i5ting-mobile.html...OK 876 | Writing test/i5ting-mobile_test.js...OK 877 | Writing LICENSE-MIT...OK 878 | Writing package.json...OK 879 | Writing i5ting-mobile.jquery.json...OK 880 | 881 | Initialized from template "jquery". 882 | You should now install project dependencies with npm install. After that, you 883 | may execute project tasks with grunt. For more information about installing 884 | and configuring Grunt, please see the Getting Started guide: 885 | 886 | http://gruntjs.com/getting-started 887 | 888 | Done, without errors. 889 | ➜ plugin_grunt git:(master) ✗ 890 | 891 | 892 | ### 安装依赖 893 | 894 | 切换到plugin_grunt根目录,通过下面命令安装grunt依赖的包 895 | 896 | ➜ plugin_grunt git:(master) npm install 897 | 898 | qunit 依赖phantomjs,需要翻墙,自备梯子或者 http://i5ting.github.io/How-to-write-jQuery-plugin/node_modules.zip 899 | 900 | ### 测试 901 | 902 | grunt的task是在Gruntfile.js里定义的,所以看最后的2句 903 | 904 | // Default task. 905 | grunt.registerTask('default', ['jshint', 'qunit', 'clean', 'concat', 'uglify']); 906 | 907 | 通过上面可以知道grunt默认的tast包括'jshint', 'qunit', 'clean', 'concat', 'uglify',也就是说执行grunt命令会依次执行这些task。 908 | 909 | 任务说明 910 | 911 | - jshint 语法校验 912 | - qunit 单元测试 913 | - clean 清理历史 914 | - concat 合并多个src到一个文件中 915 | - uglify 将concat的文件进行混淆 916 | 917 | 918 | 当然你也可以分别运行,比如,运行单元测试: 919 | 920 | grunt qunit 921 | 922 | 比如,运行混淆代码 923 | 924 | grunt uglify 925 | 926 | 927 | 没有error,通过即可。 928 | 929 | ## 如何发布到jquery plugin官方网站上 930 | 931 | jquery插件标准化 932 | 933 | 1月16日,jQuery Foundation发布了新版插件资源库,以期能够为jQuery 核心代码库的第三方开发带来更好的支持与促进。 934 | 935 | 自从一年多以前,早先的jQuery插件站点关闭以来,jQuery Foundation团队就在着手搭建一个能够更智能地抵御垃圾的插件系统。作为jQuery Foundation的秘书长,Scott Gonzalez同时也是新站点在GitHub上最大的贡献者。他说到,这个新站点“将通过某个大多数垃圾制造者都不会关注的提交过程 —— 修订控制系统,来减少垃圾的数量。”利用GitHub钩子(Hooks),第三方jQuery插件的开发者将获得前所未有的丰富工具集。 936 | 937 | “托管在GitHub或者Bitbucket这样的平台上的一大好处是,作为用户,你可以直接获得一系列功能。比方说:你可以联系作者,你可以看到代码是否还在继续维护,你也可以检查bug报告或提交bug,甚至可以提交bug 的补丁。这在之前的站点上多数都做不到。我们认为,促使用户使用能够免费提供这些功能的服务,并且在已有大量用户每天都在使用的环境中工作,是一种巨大的进步。” Gonzalez说到。 938 | 939 | 要发布你的jQuery插件,你需要利用Post-receive钩子,以及一个Package 清单(manifest)文件。自动化的流程正在创建中。“David Radcliffe已经提交了一个Pull request,为站点新加入了一个Service钩子,使得用户不必再手动填写钩子的URL。我们也计划创建一个能够自动生成清单文件的Grunt任务。” Gonzalez说到。 940 | 941 | 随着jQuery 2.0的即将到来,现有插件的作者们需要将他们的插件重新发布到新的平台。Gonzalez和其他jQuery Foundation的成员希望为整个社区的积极参与搭建好舞台。“新插件站点的一大亮点是其100%开源,因此整个社区可以建议新特性、讨论特性的优缺点,乃至开发实现新特性。我们非常乐于看到能够为我们的用户提供更好的服务,并把与我们的代码项目同等程度的透明性以及开发性带给我们的这个站点项目,以实现更快的迭代。” 942 | 943 | 查看英文原文:jQuery's Github-Driven Plugin Repository Launched 944 | 上面是infoq的文章 945 | 946 | 947 | ----- 948 | 949 | 详细步骤:http://plugins.jquery.com/docs/publish/ 950 | 951 | -------------------------- 952 | 953 | 我总结一下: 954 | 955 | 1、Add a Post-Receive Hook 956 | 这步必须做 957 | 958 | 学习一下https://help.github.com/articles/post-receive-hooks不错哦 959 | 960 | http://plugins.jquery.com/docs/publish/ 961 | 962 | Settings -> Service Hooks -> WebHook URLs 963 | 964 | http://plugins.jquery.com/postreceive-hook 965 | 966 | 2、*jquery.json可以用grunt生成 967 | 968 | grunt init:jquery 969 | 970 | 3、发布的tag必须和*jquery.json里的版本一样,可以用v开头 971 | 972 | the tag should be either "0.1.1" or "v0.1.1" 973 | 974 | 建议说不用git tag -f 来覆盖老版本的tag 975 | 976 | ## 实践作业 977 | 答题的同学,还有实践作业,每个人写一个jQuery插件,使用grunt创建,发布到github上,并在jQuery官方网站可以搜到 978 | 979 | 例如 http://plugins.jquery.com/?s=ztree 980 | 981 | ## 笔试 982 | 983 | - 插件有几种? 984 | 985 | - 文中举了几个例子?分别用于阐述什么问题 986 | 987 | - 插件配置项有几种,举例说明 988 | 989 | - 如何重构代码 990 | 991 | - grunt 是做什么的,如果使用grunt创建jQuery插件 992 | 993 | - 如何发布插件 994 | 995 | - 为什么缓存this 996 | --------------------------------------------------------------------------------