├── LICENSE ├── README.md ├── amuse.md ├── api ├── README.md └── github.md ├── git ├── README.md ├── github.md └── ssh.md ├── go └── README.md ├── html-css ├── README.md ├── complete-list-of-html-meta-tags.md ├── css.md └── svg.md ├── js ├── README.md ├── ajax.md ├── event.md └── jquery.md ├── markdown └── README.md ├── mysql ├── README.md ├── batch-update.md ├── error-code.md ├── explain.md └── used.md ├── nosql └── README.md ├── open-source ├── README.md └── sublime-text.md ├── php ├── README.md ├── array.md ├── composer.md ├── http.md ├── laravel.md ├── string.md └── vote-ranking-algorithm.md ├── python └── README.md └── server ├── README.md ├── http-code.md ├── laravel4-vhost.md ├── protocols.md ├── shell.md ├── sphinx.md └── vagrant.md /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 宋小北 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 编程技巧汇总 :books: 2 | 3 | 为了方便快速编写代码,创建了这个公开库。旨在提高编写效率和编写质量,避免多次google一样的代码。这是一个在线公开笔记,也是一个提高自己能力的文档,会收集大量优秀的代码片段。 4 | 5 | #### 贡献方式: 6 | 7 | * [`fork`](https://github.com/xiaobeicn/skills-summary/fork) 项目,然后推送给我 8 | * 创建 [`issues`](https://github.com/xiaobeicn/skills-summary/issues/new) ,我会及时处理 9 | 10 | #### 贡献要求 11 | 12 | * 在对应文件夹内创建单独文件(推荐)或在文件夹内对应文件直接扩充 13 | * 文件内容不宜过大,最好控制在百行以内 14 | * 如果是多个片段一个归属类,最好只创建一个文件 15 | * 代码质量要高,可以是自己代码的提炼,也可以是开源优秀代码段(注明来源) 16 | * `pull` 的时候必须写好 `commit`,并且检查好代码的格式与缩进 17 | * 不满足以上条件不予 *通过* 18 | 19 | ### 列表状态 20 | 21 | - [x] [api](https://github.com/xiaobeicn/skills-summary/tree/master/api) 22 | - [x] [git](https://github.com/xiaobeicn/skills-summary/tree/master/git) 23 | - [x] [html-css](https://github.com/xiaobeicn/skills-summary/tree/master/html-css) 24 | - [x] [js](https://github.com/xiaobeicn/skills-summary/tree/master/js) 25 | - [x] [markdown](https://github.com/xiaobeicn/skills-summary/tree/master/markdown) 26 | - [x] [mysql](https://github.com/xiaobeicn/skills-summary/tree/master/mysql) 27 | - [x] [nosql](https://github.com/xiaobeicn/skills-summary/tree/master/nosql) 28 | - [x] [PHP](https://github.com/xiaobeicn/skills-summary/tree/master/php) 29 | - [x] [server](https://github.com/xiaobeicn/skills-summary/tree/master/server) 30 | - [x] [open-source](https://github.com/xiaobeicn/skills-summary/tree/master/open-source) 31 | - [x] [python](https://github.com/xiaobeicn/skills-summary/tree/master/python) 32 | - [x] [go](https://github.com/xiaobeicn/skills-summary/tree/master/go) 33 | - [ ] other 34 | 35 | ### 贡献者(排名不分先后) 36 | | 贡献者 | 贡献目录| Github | 37 | | -------- | :-----: | :----: | 38 | | xiaobeicn | all | https://github.com/xiaobeicn | 39 | | overtrue | php | https://github.com/overtrue | 40 | | Lin-H | js | https://github.com/Lin-H | 41 | | feilengcui | php | https://github.com/feilengcui | 42 | | joshle | php | https://github.com/joshle | 43 | | itsmikej | php | https://github.com/itsmikej | 44 | | lifesign | laravel | https://github.com/lifesign | 45 | | lovecn | php/js/python | https://github.com/lovecn | 46 | | ... | ... | ... | 47 | 48 | #### 开源协议 49 | 基于 [MIT License](https://github.com/xiaobeicn/skills-summary/blob/master/LICENSE) 开源,使用代码只需说明来源即可。 50 | 部分源码来源网络收集,如果不希望我们展示或者侵权的地方联系我 ,我会及时处理。 51 | -------------------------------------------------------------------------------- /amuse.md: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | *    ┏┓   ┏┓ 4 | *   ┏┛┻━━━┛┻┓ 5 | *   ┃       ┃ 6 | *   ┃   ━   ┃ 7 | *   ┃ ┳┛ ┗┳ ┃ 8 | *   ┃       ┃ 9 | *   ┃   ┻   ┃ 10 | *   ┃       ┃ 11 | *   ┗━┓   ┏━┛Code is far away from bug with the animal protecting 12 | *     ┃   ┃ 神兽保佑,代码无bug 13 | *     ┃   ┃ 14 | *     ┃   ┗━━━┓ 15 | *     ┃      ┣┓ 16 | *     ┃     ┏┛ 17 | *     ┗┓┓┏━┳┓┏┛ 18 | *      ┃┫┫ ┃┫┫ 19 | *      ┗┻┛ ┗┻┛ 20 | * 21 | */ 22 | -------------------------------------------------------------------------------- /api/README.md: -------------------------------------------------------------------------------- 1 | ### 让RESTful Web services更实用的10个技巧 2 | * 不要寻找一个官方的“REST 标准” 3 | * 还是坚持一些标准 4 | * 确保你的文档是完美无瑕疵的 5 | * 提供 JSON 输出 6 | * 不要漏掉 XML 7 | * 理解 HTTP 动词 8 | * 理解 URI 路由的重要性 9 | * 在版本管理下进行更新维护 10 | * 与你的用户保持联系 11 | * 提供示例代码 12 | 13 | > via:[link](http://www.huahuaxia.net/cs-research/restful-api-resource-naming/) 14 | ---- 15 | -------------------------------------------------------------------------------- /api/github.md: -------------------------------------------------------------------------------- 1 | ### github api 2 | * 获取用户项目的json数据 [github api owner](https://api.github.com/users/xiaobeicn/repos?type=owner) 3 | * 获取现有的api https://api.github.com 4 | 5 | ```json 6 | { 7 | "current_user_url": "https://api.github.com/user", 8 | "authorizations_url": "https://api.github.com/authorizations", 9 | "code_search_url": "https://api.github.com/search/code?q={query}{&page,per_page,sort,order}", 10 | "emails_url": "https://api.github.com/user/emails", 11 | "emojis_url": "https://api.github.com/emojis", 12 | "events_url": "https://api.github.com/events", 13 | "feeds_url": "https://api.github.com/feeds", 14 | "following_url": "https://api.github.com/user/following{/target}", 15 | "gists_url": "https://api.github.com/gists{/gist_id}", 16 | "hub_url": "https://api.github.com/hub", 17 | "issue_search_url": "https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}", 18 | "issues_url": "https://api.github.com/issues", 19 | "keys_url": "https://api.github.com/user/keys", 20 | "notifications_url": "https://api.github.com/notifications", 21 | "organization_repositories_url": "https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}", 22 | "organization_url": "https://api.github.com/orgs/{org}", 23 | "public_gists_url": "https://api.github.com/gists/public", 24 | "rate_limit_url": "https://api.github.com/rate_limit", 25 | "repository_url": "https://api.github.com/repos/{owner}/{repo}", 26 | "repository_search_url": "https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}", 27 | "current_user_repositories_url": "https://api.github.com/user/repos{?type,page,per_page,sort}", 28 | "starred_url": "https://api.github.com/user/starred{/owner}{/repo}", 29 | "starred_gists_url": "https://api.github.com/gists/starred", 30 | "team_url": "https://api.github.com/teams", 31 | "user_url": "https://api.github.com/users/{user}", 32 | "user_organizations_url": "https://api.github.com/user/orgs", 33 | "user_repositories_url": "https://api.github.com/users/{user}/repos{?type,page,per_page,sort}", 34 | "user_search_url": "https://api.github.com/search/users?q={query}{&page,per_page,sort,order}" 35 | } 36 | ``` 37 | -------------------------------------------------------------------------------- /git/README.md: -------------------------------------------------------------------------------- 1 | ### git工作流 2 | https://github.com/xirong/my-git/blob/master/git-workflow-tutorial.md 3 | 4 | ### 让你们clone laravel更快(by [overtrue](https://github.com/overtrue) ) 5 | 我们通常在克隆github上的项目时做法如下: 6 | 7 | ```git 8 | git clone git@github.com:laravel/laravel.git 9 | ``` 10 | 11 | 你会发现各种慢(如果该项目历史比较悠久,也就是说有很多commits),那么其实你clone的时候是把历史也拉下来。可是我们需要这些东西吗?不需要,那么就加一个选项吧: 12 | 13 | ```git 14 | git clone git@github.com:laravel/laravel.git --depth=1 15 | ``` 16 | 17 | --depth=1 是指只拉取最后一次的提交结果。 18 | 19 | ---- 20 | 21 | ### 开发者私人信息保密方法 22 | 实际开发中(类似邮件功能)需要开发者私人密码的文件,可以采用以下方法进行隐私保护。请在命令行中使用。 23 | 24 | ```git 25 | // 假设文件无改动,作用于版本库中已存在的文件。 26 | // 此方法将确保本地文件不提交,并且版本库中此文件的变更无法影响本地文件。 27 | git update-index --assume-unchanged app/config/mail.php 28 | // 取消并恢复为普通文件 29 | git update-index --no-assume-unchanged app/config/mail.php 30 | ``` 31 | 32 | ---- 33 | 34 | ### 设置全局代理(来自网络) 35 | 36 | ```git 37 | git config --global https.proxy https://user:password@address:port 38 | ``` 39 | 40 | ### clone某个特定分支 41 | 42 | ```git 43 | mkdir $BRANCH 44 | cd $BRANCH 45 | git init 46 | git remote add -t $BRANCH -f origin $REMOTE_REPO 47 | git checkout $BRANCH 48 | ``` 49 | 50 | ### 比较某个文件和远程分支上的区别 51 | 52 | ```git 53 | git diff localbranch remotebranch filepath 54 | ``` 55 | 56 | ### 在版本库所有版本中搜寻一条字符串 57 | 58 | ```git 59 | git rev-list --all | ( 60 | while read revision; do 61 | git grep -F 'Your search string' $revision 62 | done 63 | ) 64 | ``` 65 | 66 | ### 向分支提交一个初始的空commit,保证完全复位 67 | 68 | ```git 69 | 1.创建一个新的空分支,例如:newroot 70 | 71 | git checkout --orphan newroot 72 | git rm --cached -r . 73 | git clean -f -d 74 | 2.创建空的commit 75 | 76 | git commit --allow-empty -m '[empty] initial commit' 77 | 3.重新发送分支的全部内容 78 | 79 | git rebase --onto newroot --root master 80 | 4.删除临时分支newroot 81 | 82 | git branch -d newroot 83 | 现在master就已经包含了一个空的root commit了。 84 | ``` 85 | 86 | ### 如何修改一个特定的commit 87 | 88 | ```git 89 | 当你想在推送前重做你最后的commit时,可以使用修改命令(git commit --amend)。如果你想修改的不是最后一个commit呢? 90 | 91 | 这种情况下,你可以使用git rebase,例如,你想要修改bbc643cd commit,运行下面的命令: 92 | 93 | $git rebase bbc643cd^ --interactive 94 | 在默认的编辑器中选择并修改你期望修改的,然后保存修改并输入: 95 | 96 | $ git add 97 | < 98 | filepattern 99 | > 100 | 101 | 现在你就可以使用 102 | 103 | $git commit --amend 104 | 来修改commit,之后使用 105 | 106 | $ git rebase --continue 107 | 返回之前最新的commit。 108 | ``` 109 | 110 | ### 密钥登录 111 | * 生成密钥 112 | > ssh-keygen -t rsa -C "your_email@example.com" 113 | * 上传服务器 114 | > ssh-copy-id -i ~/.ssh/id_rsa.pub root@100.100.100.100 115 | 116 | ### git 给远程库 添加多个url地址 117 | 118 | * 第一个地址 git remote add origin 119 | * 第二个地址 git remote set-url --add origin 120 | * 第三个地址 git remote set-url --add origin 121 | 122 | > 注意:使用git push origin master时,你可以push到origin的多个url地址。但是使用 git pull时,只能拉取origin里的一个url地址,这个fetch-url默认为 你添加的到origin的第一个地址 123 | -------------------------------------------------------------------------------- /git/github.md: -------------------------------------------------------------------------------- 1 | ### 通过Web界面创建文件夹 2 | 由"/"结束创建新文件夹。或者指定文件扩展名,点击提交文件也可创建新文件夹 3 | 4 | ### 使用Git URL短地址 5 | 使用Github的Git.io。Git.io将会缩短你的项目地址连接。也可以使用gitio命令,Git.io的命令行接口来缩短地址。 6 | 7 | ### 文件查找 8 | 处理新建文件,你还可以在任何存储库快速浏览这些文件。该功能不是太明显,需要快捷方式,在键盘上按"T"激活文件查找功能。在按上下键上下查找。当然,也可以输入文件名称来选择特定的文件 。 9 | 10 | ### 连接 11 | 有时候我们需要在自己的文件项目中分享或者输出特殊行。Github可以实现,我们只需要添加"#L "放在URL行号后面 12 | 13 | ### 任务清单 14 | 15 | Github 扩展了markdown来满足自己的需要,现在你可以在Github上添加一个复选框列表,使用 - [ ] or - [x]来表示一个检查项目。请注意,复选框只会出现在列表项中。"[ ]"必须以"‐"开始。下面有一盒例子: 16 | 17 | - [x] create a post. 18 | - [x] create a page. 19 | - [x] add images. 20 | - [ ] published the post. 21 | 22 | ---- 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /git/ssh.md: -------------------------------------------------------------------------------- 1 | 2 | ### Checking for existing SSH keys 3 | 4 | ```shell 5 | ls -al ~/.ssh 6 | # Lists the files in your .ssh directory, if they exist 7 | ``` 8 | 9 | ### Generating a new SSH key 10 | 11 | ```shell 12 | ssh-keygen -t rsa -b 4096 -C "your_email@example.com" -f ~/.ssh/id_rsa_[custom file name] 13 | ``` 14 | 15 | ### Adding your SSH key to the ssh-agent 16 | 17 | * Start the ssh-agent in the background. 18 | ```shell 19 | eval "$(ssh-agent -s)" 20 | ### Agent pid 59566 21 | ``` 22 | * modify your ~/.ssh/config file 23 | ```shell 24 | # gitHub user Self 25 | Host github.com 26 | User xiaobeicn 27 | AddKeysToAgent yes 28 | UseKeychain yes 29 | IdentityFile ~/.ssh/id_rsa_github 30 | 31 | # gitlab user 32 | Host gitlab.com 33 | User xiaobeicn 34 | AddKeysToAgent yes 35 | UseKeychain yes 36 | IdentityFile ~/.ssh/id_rsa_gitlab 37 | ``` 38 | * Add your SSH private key to the ssh-agent and store your passphrase in the keychain. 39 | ```shell 40 | ssh-add -K ~/.ssh/id_rsa 41 | ``` 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /go/README.md: -------------------------------------------------------------------------------- 1 | ```go 2 | /* 3 | Golang速学速查速用代码手册 4 | 5 | Source: github.com/coderzh/CodeTips/blob/master/gotips_test.go 6 | Author: coderzh(github.com/coderzh) 7 | Blog: http://blog.coderzh.com 8 | 参考:《Go语言编程》 9 | */ 10 | 11 | package main 12 | 13 | import ( 14 | "errors" 15 | "fmt" 16 | "github.com/stretchr/testify/assert" 17 | "io" 18 | "io/ioutil" 19 | "log" 20 | "math" 21 | "os" 22 | "path/filepath" 23 | "regexp" 24 | "strings" 25 | "sync" 26 | "testing" 27 | "time" 28 | ) 29 | 30 | // 0. 注释 31 | /* 32 | 规范: 33 | 1. 命名:骆驼命名法(不要用下划线) 34 | 35 | 命令: 36 | go get github.com/coderzh/xxx 37 | go build calc 38 | go run xxx.go 39 | go install calc 40 | */ 41 | 42 | // 1. Hello World 43 | func helloWorld() { 44 | fmt.Println("Hello, 世界") 45 | } 46 | 47 | // 2.变量类型 48 | func typeDemo() { 49 | // 变量声明 50 | var v1 int 51 | var ( 52 | v2 int 53 | v3 string 54 | ) 55 | //var p *int // 指针类型 56 | 57 | // 变量初始化 58 | var v4 int = 10 59 | // 等价于: 60 | var v5 = 10 61 | // 一般这样就好 62 | v6 := 10 63 | 64 | // 赋值,多重赋值 65 | v1 = 10 66 | v2, v3 = 20, "test" 67 | // 匿名变量 _ 68 | _, v4 = v5, v6 69 | 70 | fmt.Println(v1, v2, v3, v4) 71 | 72 | // 常量 73 | const Pi float64 = 3.1415926 74 | const MaxPlayer = 10 75 | 76 | // 枚举 77 | const ( 78 | Sunday = iota // iota从0递增 79 | Mondy 80 | Tuesday 81 | // ... 82 | ) 83 | 84 | // 类型 85 | // 1. 布尔 86 | var b1 bool 87 | b1 = true 88 | b1 = (1 == 2) 89 | 90 | fmt.Println(b1) 91 | 92 | // 2. 整形 93 | // int8 uint8 int16 uint16 int32 uint32 int64 uint64 int uint uintptr 94 | var i32 int32 95 | // 强制转换 96 | i32 = int32(64) 97 | // 运算:+, -, *, /, %(求余) 98 | // 比较:>, <, ==, >=, <=, != 99 | // 位运算:x << y, x >> y, x ^ y, x & y, x | y, ^x (取反) 100 | 101 | fmt.Println(i32) 102 | 103 | // 3. 浮点 104 | // float32, float64 105 | var f1 float64 = 1.0001 106 | var f2 float64 = 1.0002 107 | // 浮点比较 108 | isEqual := math.Dim(f1, f2) < 0.0001 109 | 110 | fmt.Println(isEqual) 111 | 112 | // 4. 字符串 113 | var s1 string 114 | s1 = "abc" 115 | // 字符串连接 116 | s1 = s1 + "ddd" 117 | // 取长度 118 | n := len(s1) 119 | // 取字符 120 | c1 := s1[0] 121 | // 反引号,不转义,常用于正则表达式 122 | s1 = `\w+` 123 | 124 | fmt.Println(c1) 125 | 126 | fmt.Println(strings.HasPrefix("prefix", "pre")) // true 127 | fmt.Println(strings.HasSuffix("suffix", "fix")) // true 128 | 129 | // 字节遍历 130 | for i := 0; i < n; i++ { 131 | ch := s1[i] 132 | fmt.Println(ch) 133 | } 134 | // Unicode字符Rune遍历 135 | for i, ch := range s1 { 136 | fmt.Println(i, ch) 137 | } 138 | 139 | // 5. 数组 140 | var arr1 [32]int 141 | //var arr2 [3][8]int // 二维数组 142 | // 初始化 143 | arr1 = [32]int{0} 144 | array := [5]int{1, 2, 3, 4, 5} 145 | // 临时结构体数组 146 | structArray := []struct { 147 | name string 148 | age int 149 | }{{"Tim", 18}, {"Jim", 20}} 150 | 151 | // 数组遍历 152 | for i := 0; i < len(array); i++ { 153 | fmt.Println(array[i]) 154 | } 155 | for i, v := range structArray { 156 | fmt.Println(i, v) 157 | } 158 | // 数组是值类型,每次参数传递都是一份拷贝 159 | 160 | // 数组切片Slice 161 | var mySlice []int = arr1[:2] 162 | mySlice1 := make([]int, 5) 163 | mySlice2 := make([]int, 5, 10) 164 | 165 | fmt.Println("len(mySlice2:", len(mySlice2)) // 5 166 | fmt.Println("cap(mySlice2:", cap(mySlice2)) // 10 167 | 168 | mySlice3 := append(mySlice, 2, 3, 4) 169 | mySlice4 := append(mySlice, mySlice1...) 170 | 171 | copy(mySlice3, mySlice4) 172 | 173 | // 6. Map 174 | var m map[int]string 175 | m[1] = "ddd" 176 | m1 := make(map[int]string) 177 | m2 := map[int]string{ 178 | 1: "a", 179 | 2: "b", 180 | } 181 | 182 | delete(m2, 1) 183 | 184 | value, ok := m1[1] 185 | if ok { 186 | fmt.Println(value) 187 | } 188 | 189 | for k, v := range m2 { 190 | fmt.Println(k, v) 191 | } 192 | 193 | } 194 | 195 | // 3. 流程控制 196 | func flowDemo() { 197 | // if else 198 | a := 10 199 | if a < 10 { 200 | // .. 201 | } else { 202 | // .. 203 | } 204 | 205 | // switch 206 | switch a { 207 | case 0: 208 | fmt.Println("0") 209 | case 10: 210 | fmt.Println("10") 211 | default: 212 | fmt.Println("default") 213 | } 214 | 215 | switch { 216 | case a < 10: 217 | fmt.Println("<10") 218 | case a < 20: 219 | fmt.Println("<20") 220 | } 221 | 222 | // 循环 223 | for i := 0; i < 10; i++ { 224 | } 225 | // 无限循环 226 | sum := 0 227 | for { 228 | sum++ 229 | if sum > 10 { 230 | break 231 | // 指定break 232 | // break JLoop 233 | } 234 | } 235 | 236 | goto JLoop 237 | 238 | JLoop: 239 | // break to here 240 | 241 | } 242 | 243 | // 4. 函数 244 | // func 函数名(参数列表)(返回值列表) { 245 | // } 246 | func sum1(value1 int, value2 int) (result int, err error) { 247 | // err = errors.New("xxxx") 248 | return value1 + value2, nil 249 | } 250 | 251 | func sum2(value1, value2 int) int { 252 | return value1 + value2 253 | } 254 | 255 | // 不定参数 256 | // myFunc(1, 2, 3, 4, 5) 257 | func myFunc(args ...int) { 258 | for _, arg := range args { 259 | fmt.Println(arg) 260 | } 261 | // 传递 262 | // myFunc2(args...) 263 | // myFunc2(args[1:]...) 264 | } 265 | 266 | // 任意类型的不定参数 267 | func myPrintf(args ...interface{}) { 268 | for _, arg := range args { 269 | switch arg.(type) { 270 | case int: 271 | fmt.Println(arg, "is int") 272 | case string: 273 | fmt.Println(arg, "is string") 274 | default: 275 | fmt.Println(arg, "is unknown") 276 | } 277 | } 278 | } 279 | 280 | // 匿名函数 281 | func anonymousFunc() { 282 | f := func(a, b int) int { 283 | return a + b 284 | } 285 | 286 | f(1, 2) 287 | } 288 | 289 | // defer 290 | func deferDemo(path string) { 291 | f, err := os.Open(path) 292 | if err != nil { 293 | return 294 | } 295 | 296 | defer f.Close() 297 | // or 298 | defer func() { 299 | if r := recover(); r != nil { 300 | fmt.Printf("Runtime error caught: %v", r) 301 | } 302 | }() 303 | } 304 | 305 | // 5. 结构体 306 | type Rect struct { 307 | // 小写为private 308 | x, y float64 309 | // 大写为public 310 | Width, Height float64 311 | } 312 | 313 | // 大写方法为public,小写为private 314 | func (r *Rect) Area() float64 { 315 | return r.Width * r.Height 316 | } 317 | 318 | func netRect(x, y, width, height float64) *Rect { 319 | // 实例化结构体 320 | // rect1 := new(Rect) 321 | // rect2 := &Rect{} 322 | // rect3 := &Rect{Width:100, Height:200} 323 | return &Rect{x, y, width, height} 324 | } 325 | 326 | // 匿名组合 327 | type Base struct { 328 | Name string 329 | } 330 | 331 | func (base *Base) Foo() {} 332 | func (base *Base) Bar() {} 333 | 334 | type Foo struct { 335 | Base 336 | *log.Logger 337 | } 338 | 339 | func (foo *Foo) Bar() { 340 | foo.Base.Bar() 341 | // ... 342 | } 343 | 344 | // 非侵入式接口 345 | type IFile interface { 346 | Read(buf []byte) (n int, err error) 347 | Write(buf []byte) (n int, err error) 348 | } 349 | 350 | type File struct { 351 | } 352 | 353 | func (file *File) Read(buf []byte) (n int, err error) { 354 | return 0, nil 355 | } 356 | 357 | func (file *File) Write(buf []byte) (n int, err error) { 358 | return 0, nil 359 | } 360 | 361 | func interfaceDemo() { 362 | // 只要实现了Read, Write方法即可 363 | var file IFile = new(File) 364 | 365 | // 接口查询 366 | // 是否实现了IFile接口 367 | if file2, ok := file.(IFile); ok { 368 | file2.Read([]byte{}) 369 | } 370 | // 实例类型是否是File 371 | if file3, ok := file.(*File); ok { 372 | file3.Read([]byte{}) 373 | } 374 | 375 | // 类型查询 376 | switch v := file.(type) { 377 | } 378 | } 379 | 380 | // 6. 并发编程 381 | func counting(ch chan int) { 382 | ch <- 1 383 | fmt.Println("counting") 384 | } 385 | 386 | func channelDemo() { 387 | chs := make([]chan int, 10) 388 | for i := 0; i < len(chs); i++ { 389 | chs[i] = make(chan int) 390 | // 带缓冲区大小 391 | // c: = make(chan int, 1024) 392 | // for i:= range c { 393 | // } 394 | go counting(chs[i]) 395 | } 396 | 397 | for _, ch := range chs { 398 | <-ch 399 | // channel select 400 | /* 401 | select { 402 | case <-ch: 403 | // ... 404 | case ch <- 1: 405 | } 406 | */ 407 | } 408 | 409 | // 单向Channel 410 | var ch1 chan<- int // 只能写入int 411 | var ch2 <-chan int // 只能读出int 412 | 413 | // 关闭Channel 414 | close(ch1) 415 | _, ok := <-ch2 416 | if !ok { 417 | // already closed 418 | } 419 | } 420 | 421 | // 锁 422 | var m sync.Mutex 423 | 424 | func lockDemo() { 425 | m.Lock() 426 | // do something 427 | defer m.Unlock() 428 | } 429 | 430 | // 全局唯一操作 431 | var once sync.Once 432 | 433 | // once.Do(someFunction) 434 | 435 | // 7. 网络编程 436 | // import "net" 437 | // net.Dial("tcp", "127.0.0.1:8080") 438 | 439 | // 8. json处理 440 | // import "encoding/json" 441 | // json.Marshal(obj) 序列化 442 | // json.Unmarshal() 反序列化 443 | 444 | // 9. Web开发 445 | // import "net/http" 446 | // 模板 447 | // import "html/template" 448 | 449 | // 10. 常用库 450 | // import "os" 451 | // import "io" 452 | // import "flag" 453 | // import "strconv" 454 | // import "crypto/sha1" 455 | // import "crypto/md5" 456 | 457 | // 11. 单元测试 458 | // _test结尾的go文件: xxx_test.go 459 | // 函数名以Test开头 460 | func TestDemo(t *testing.T) { 461 | r := sum2(2, 3) 462 | if r != 5 { 463 | t.Errorf("sum2(2, 3) failed. Got %d, expect 5.", r) 464 | } 465 | 466 | assert.Equal(t, 1, 1) 467 | } 468 | 469 | // 12. 性能测试 470 | func benchmarkAdd(b *testing.B) { 471 | b.StopTimer() 472 | // dosometing 473 | b.StartTimer() 474 | } 475 | 476 | /* 477 | 其他常用的代码片段 478 | */ 479 | 480 | // 1. 遍历文件 filepath.Walk 481 | // import "path/filepath" 482 | func doHashWalk(dirPath string) error { 483 | 484 | fullPath, err := filepath.Abs(dirPath) 485 | 486 | if err != nil { 487 | return err 488 | } 489 | 490 | callback := func(path string, fi os.FileInfo, err error) error { 491 | return hashFile(fullPath, path, fi, err) 492 | } 493 | 494 | return filepath.Walk(fullPath, callback) 495 | } 496 | 497 | func hashFile(root string, path string, fi os.FileInfo, err error) error { 498 | if fi.IsDir() { 499 | return nil 500 | } 501 | rel, err := filepath.Rel(root, path) 502 | if err != nil { 503 | return err 504 | } 505 | log.Println("hash rel:", rel, "abs:", path) 506 | return nil 507 | } 508 | 509 | // 2. 读取文件 510 | // import "io/ioutil" 511 | func readFileDemo(filename string) { 512 | content, err := ioutil.ReadFile(filename) 513 | if err != nil { 514 | //Do something 515 | } 516 | lines := strings.Split(string(content), "\n") 517 | fmt.Println("line count:", len(lines)) 518 | } 519 | 520 | // 判断目录或文件是否存在 521 | func existsPathCheck(path string) (bool, error) { 522 | // 判断不存在 523 | if _, err := os.Stat(path); os.IsNotExist(err) { 524 | // 不存在 525 | } 526 | 527 | // 判断是否存在 528 | _, err := os.Stat(path) 529 | if err == nil { 530 | return true, nil 531 | } 532 | if os.IsNotExist(err) { 533 | return false, nil 534 | } 535 | return true, err 536 | } 537 | 538 | // 文件目录操作 539 | func fileDirDemo() { 540 | // 级联创建目录 541 | os.MkdirAll("/path/to/create", 0777) 542 | } 543 | 544 | // 拷贝文件 545 | func copyFile(source string, dest string) (err error) { 546 | sf, err := os.Open(source) 547 | if err != nil { 548 | return err 549 | } 550 | defer sf.Close() 551 | df, err := os.Create(dest) 552 | if err != nil { 553 | return err 554 | } 555 | defer df.Close() 556 | _, err = io.Copy(df, sf) 557 | if err == nil { 558 | si, err := os.Stat(source) 559 | if err != nil { 560 | err = os.Chmod(dest, si.Mode()) 561 | } 562 | 563 | } 564 | return 565 | } 566 | 567 | // 拷贝目录 568 | func copyDir(source string, dest string) (err error) { 569 | fi, err := os.Stat(source) 570 | if err != nil { 571 | return err 572 | } 573 | if !fi.IsDir() { 574 | return errors.New(source + " is not a directory") 575 | } 576 | err = os.MkdirAll(dest, fi.Mode()) 577 | if err != nil { 578 | return err 579 | } 580 | entries, err := ioutil.ReadDir(source) 581 | for _, entry := range entries { 582 | sfp := filepath.Join(source, entry.Name()) 583 | dfp := filepath.Join(dest, entry.Name()) 584 | if entry.IsDir() { 585 | err = copyDir(sfp, dfp) 586 | if err != nil { 587 | fmt.Println(err) 588 | } 589 | } else { 590 | err = copyFile(sfp, dfp) 591 | if err != nil { 592 | fmt.Println(err) 593 | } 594 | } 595 | 596 | } 597 | return nil 598 | } 599 | 600 | // 3. 时间处理 601 | // import "time" 602 | func TestTimeDemo(t *testing.T) { 603 | // Parse 604 | postDate, err := time.Parse("2006-01-02 15:04:05", "2015-09-30 19:19:00") 605 | fmt.Println(postDate, err) 606 | 607 | // Format 608 | assert.Equal(t, "2015/Sep/30 07:19:00", postDate.Format("2006/Jan/02 03:04:05")) 609 | assert.Equal(t, "2015-09-30T19:19:00Z", postDate.Format(time.RFC3339)) 610 | } 611 | 612 | // 4. 正则表达式 613 | // import "regexp" 614 | func TestRegexp(t *testing.T) { 615 | // 查找匹配 616 | re := regexp.MustCompile(`(\d+)-(\d+)`) 617 | r := re.FindAllStringSubmatch("123-666", -1) 618 | 619 | assert.Equal(t, 1, len(r)) 620 | assert.Equal(t, "123", r[0][1]) 621 | assert.Equal(t, "666", r[0][2]) 622 | 623 | cjkRe := regexp.MustCompile(`\p{Han}|\p{Hangul}|\p{Hiragana}|\p{Katakana}`) 624 | 625 | assert.True(t, cjkRe.MatchString("中文")) 626 | assert.True(t, cjkRe.MatchString("도형이")) 627 | assert.True(t, cjkRe.MatchString("カテゴリー")) 628 | assert.False(t, cjkRe.MatchString("abc")) 629 | } 630 | 631 | func main() { 632 | helloWorld() 633 | } 634 | ``` 635 | -------------------------------------------------------------------------------- /html-css/README.md: -------------------------------------------------------------------------------- 1 | ### 建议 2 | * 用 firebug 或 console 3 | * 用 CSS animation 取代 Javascript 4 | * 不修改 image width & height attribute 5 | * 使用 max width and height 调整 image 比例 6 | * 善用 :before and :after 7 | * 減少 CSS 程式码 8 | -------------------------------------------------------------------------------- /html-css/complete-list-of-html-meta-tags.md: -------------------------------------------------------------------------------- 1 | > From:(http://code.lancepollard.com/complete-list-of-html-meta-tags/) 2 | 3 | ### Basic HTML Meta Tags 4 | ```html 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | ``` 33 | 34 | ### OpenGraph Meta Tags 35 | ```html 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | ``` 75 | 76 | ### Create Custom Meta Tags 77 | ```html 78 | 79 | 80 | 81 | 82 | ``` 83 | 84 | ### Company/Service Meta Tags 85 | ```html 86 | 87 | ``` 88 | 89 | ### APPLE META TAGS 90 | ```html 91 | 92 | 93 | 94 | 95 | 96 | ``` 97 | 98 | ### INTERNET EXPLORER META TAGS 99 | ```html 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | ``` 115 | 116 | ### TWEETMEME META TAGS 117 | ```html 118 | 119 | ``` 120 | 121 | ### BLOG CATALOG META TAGS 122 | ```html 123 | 124 | ``` 125 | 126 | ### RAILS META TAGS 127 | ```html 128 | 129 | 130 | ``` 131 | 132 | ### APPLE TAGS 133 | ```html 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | ``` 147 | 148 | ### HTML Link Tags 149 | ```html 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | ``` 174 | 175 | 176 | 177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /html-css/css.md: -------------------------------------------------------------------------------- 1 | ### 清除子元素浮动clearfix方法 2 | 3 | ```css 4 | /*简洁版*/ 5 | .clearfix:before, .clearfix:after { 6 | content:""; 7 | display:table; 8 | } 9 | .clearfix:after{ 10 | clear:both; 11 | overflow:hidden; 12 | } 13 | .clearfix{ 14 | zoom:1; 15 | } 16 | /* 经典版 */ 17 | .clearfix:after { 18 | visibility: hidden; 19 | display: block; 20 | font-size: 0; 21 | content: " "; 22 | clear: both; 23 | height: 0; 24 | } 25 | * html .clearfix { zoom: 1; } /* IE6 */ 26 | *:first-child+html .clearfix { zoom: 1; } /* IE7 */ 27 | 注:clearfix的方法主要就是在浮动元素的父元素上加上一个clearfix class,然后这个父元素的框就会包括所有的浮动子元素。 28 | ``` 29 | 30 | ### 清除子元素浮动overflow方法 31 | 32 | ```css 33 | /* overflow:auto */ 34 | #demo2{ 35 | overflow:auto;*zoom:1; 36 | } 37 | /*或 overflow:hidden */ 38 | #demo2{ 39 | overflow:hidden;*zoom:1; 40 | } 41 | 注:这种方法主要是对父元素设置css,所以不需要加个class,下面的inline-block方法相同,只需设置父元素的css即可 42 | ``` 43 | 44 | ### 清除子元素浮动inline-block方法 45 | 46 | ```css 47 | #demo3{ 48 | display:inline-block;*display:inline;*zoom:1; 49 | } 50 | ``` 51 | 52 | ---- 53 | 54 | ### 单行省略号纯css解决方案 55 | 56 | ```css 57 | selector{ 58 | -o-text-overflow: ellipsis;/*兼容opera*/ 59 | text-overflow: ellipsis;/*这就是省略号喽*/ 60 | overflow: hidden;/*设置超过的隐藏*/ 61 | white-space: nowrap;/*设置不折行*/ 62 | width:200px;/*设置宽度*/ 63 | } 64 | ``` 65 | 66 | ---- 67 | 68 | ### 解决中文版Chrome下不能显示小于12px的字体 69 | 70 | ```css 71 | html{-webkit-text-size-adjust: none;} 72 | ``` 73 | 74 | ---- 75 | 76 | ### 垂直对齐 77 | 78 | ```css 79 | .verticalcenter{ 80 | position: relative; 81 | top: 50%; 82 | -webkit-transform: translateY(-50%); 83 | -o-transform: translateY(-50%); 84 | transform: translateY(-50%); 85 | } 86 | ``` 87 | ### 根据文件格式引用不同样式 88 | 89 | ```css 90 | a[href^="http://"]{ 91 | padding-right: 20px; 92 | background: url(external.gif) no-repeat center right; 93 | } 94 | /* emails */ 95 | a[href^="mailto:"]{ 96 | padding-right: 20px; 97 | background: url(email.png) no-repeat center right; 98 | } 99 | 100 | /* pdfs */ 101 | a[href$=".pdf"]{ 102 | padding-right: 20px; 103 | background: url(pdf.png) no-repeat center right; 104 | } 105 | ```` 106 | http://jsfiddle.net/agusesetiyono/3sL1r0mw/light/ 107 | 108 | ### 跨浏览器图像灰度 109 | 110 | ```css 111 | 112 | 113 | 114 | 115 | 116 | ``` 117 | 118 | ### CSS 列表自动宽度 119 | 120 | ```css 121 | white-space: nowrap; 122 | ``` 123 | 124 | ### 显示阴影 125 | 126 | ```css 127 | .box-shadow { 128 | background-color: #FF8020; 129 | width: 160px; 130 | height: 90px; 131 | margin-top: -45px; 132 | margin-left: -80px; 133 | position: absolute; 134 | top: 50%; 135 | left: 50%; 136 | } 137 | .box-shadow:after { 138 | content: ""; 139 | width: 150px; 140 | height: 1px; 141 | margin-top: 88px; 142 | margin-left: -75px; 143 | display: block; 144 | position: absolute; 145 | left: 50%; 146 | z-index: -1; 147 | -webkit-box-shadow: 0px 0px 8px 2px #000000; 148 | -moz-box-shadow: 0px 0px 8px 2px #000000; 149 | box-shadow: 0px 0px 8px 2px #000000; 150 | } 151 | ``` 152 | 153 | ### 长文本封装 154 | 155 | ```css 156 | pre { 157 | white-space: pre-line; 158 | word-wrap: break-word; 159 | } 160 | ``` 161 | 162 | ### 模糊文本 163 | 164 | ```css 165 | .blurry-text { 166 | color: transparent; 167 | text-shadow: 0 0 5px rgba(0,0,0,0.5); 168 | } 169 | ``` 170 | 171 | ### 使用CSS制作动画省略号 172 | 173 | ```css 174 | .loading:after { 175 | overflow: hidden; 176 | display: inline-block; 177 | vertical-align: bottom; 178 | animation: ellipsis 2s infinite; 179 | content: "\2026"; /* ascii code for the ellipsis character */ 180 | } 181 | @keyframes ellipsis { 182 | from { 183 | width: 2px; 184 | } 185 | to { 186 | width: 15px; 187 | } 188 | } 189 | ``` 190 | 191 | ---- 192 | 193 | -------------------------------------------------------------------------------- /html-css/svg.md: -------------------------------------------------------------------------------- 1 | ### twitter logo 2 | ```html 3 | 4 | 5 | 6 | ``` 7 | 8 | ### github logo 9 | ```html 10 | 11 | 12 | 13 | ``` 14 | -------------------------------------------------------------------------------- /js/README.md: -------------------------------------------------------------------------------- 1 | 1、原生JavaScript实现字符串长度截取 2 | 3 | ```javascript 4 | function cutstr(str, len) { 5 | var temp; 6 | var icount = 0; 7 | var patrn = /[^\x00-\xff]/; 8 | var strre = ""; 9 | for (var i = 0; i < str.length; i++) { 10 | if (icount < len - 1) { 11 | temp = str.substr(i, 1); 12 | if (patrn.exec(temp) == null) { 13 | icount = icount + 1 14 | } else { 15 | icount = icount + 2 16 | } 17 | strre += temp 18 | } else { 19 | break 20 | } 21 | } 22 | return strre + "..." 23 | } 24 | ```` 25 | 26 | 2、原生JavaScript获取域名主机 27 | 28 | ```javascript 29 | function getHost(url) { 30 | var host = "null"; 31 | if(typeof url == "undefined"|| null == url) { 32 | url = window.location.href; 33 | } 34 | var regex = /^\w+\:\/\/([^\/]*).*/; 35 | var match = url.match(regex); 36 | if(typeof match != "undefined" && null != match) { 37 | host = match[1]; 38 | } 39 | return host; 40 | } 41 | ```` 42 | 43 | 3、原生JavaScript清除空格 44 | 45 | ```javascript 46 | String.prototype.trim = 47 | function() { 48 | var reExtraSpace = /^\s*(.*?)\s+$/; 49 | return this.replace(reExtraSpace, "$1") 50 | } 51 | ```` 52 | 53 | 4、原生JavaScript替换全部 54 | 55 | ```javascript 56 | String.prototype.replaceAll = 57 | function(s1, s2) { 58 | return this.replace(new RegExp(s1, "gm"), s2) 59 | } 60 | ```` 61 | 62 | 5、原生JavaScript转义html标签 63 | 64 | ```javascript 65 | function HtmlEncode(text) { 66 | return text.replace(/&/g, '&').replace(/\"/g, '"').replace(//g, '>') 67 | } 68 | ```` 69 | 70 | 6、原生JavaScript还原html标签 71 | 72 | ```javascript 73 | function HtmlDecode(text) { 74 | return text.replace(/&/g, '&').replace(/"/g, '\"').replace(//g, '>') 75 | } 76 | ```` 77 | 78 | 7、原生JavaScript时间日期格式转换 79 | 80 | ```javascript 81 | Date.prototype.Format = 82 | function(formatStr) { 83 | var str = formatStr; 84 | var Week = ['日', '一', '二', '三', '四', '五', '六']; 85 | str = str.replace(/yyyy|YYYY/, this.getFullYear()); 86 | str = str.replace(/yy|YY/, (this.getYear() % 100) > 9 ? (this.getYear() % 100).toString() : '0' + (this.getYear() % 100)); 87 | str = str.replace(/MM/, (this.getMonth() + 1) > 9 ? (this.getMonth() + 1).toString() : '0' + (this.getMonth() + 1)); 88 | str = str.replace(/M/g, (this.getMonth() + 1)); 89 | str = str.replace(/w|W/g, Week[this.getDay()]); 90 | str = str.replace(/dd|DD/, this.getDate() > 9 ? this.getDate().toString() : '0' + this.getDate()); 91 | str = str.replace(/d|D/g, this.getDate()); 92 | str = str.replace(/hh|HH/, this.getHours() > 9 ? this.getHours().toString() : '0' + this.getHours()); 93 | str = str.replace(/h|H/g, this.getHours()); 94 | str = str.replace(/mm/, this.getMinutes() > 9 ? this.getMinutes().toString() : '0' + this.getMinutes()); 95 | str = str.replace(/m/g, this.getMinutes()); 96 | str = str.replace(/ss|SS/, this.getSeconds() > 9 ? this.getSeconds().toString() : '0' + this.getSeconds()); 97 | str = str.replace(/s|S/g, this.getSeconds()); 98 | return str 99 | } 100 | ```` 101 | 102 | 8、原生JavaScript判断是否为数字类型 103 | 104 | ```javascript 105 | function isDigit(value) { 106 | var patrn = /^[0-9]*$/; 107 | if (patrn.exec(value) == null || value == "") { 108 | return false 109 | } else { 110 | return true 111 | } 112 | } 113 | ```` 114 | 115 | 9、原生JavaScript设置cookie值 116 | 117 | ```javascript 118 | function setCookie(name, value, Hours) { 119 | var d = new Date(); 120 | var offset = 8; 121 | var utc = d.getTime() + (d.getTimezoneOffset() * 60000); 122 | var nd = utc + (3600000 * offset); 123 | var exp = new Date(nd); 124 | exp.setTime(exp.getTime() + Hours * 60 * 60 * 1000); 125 | document.cookie = name + "=" + escape(value) + ";path=/;expires=" + exp.toGMTString() + ";domain=360doc.com;" 126 | } 127 | ```` 128 | 129 | 10、原生JavaScript获取cookie值 130 | 131 | ```javascript 132 | function getCookie(name) { 133 | var arr = document.cookie.match(new RegExp("(^| )" + name + "=([^;]*)(;|$)")); 134 | if (arr != null) return unescape(arr[2]); 135 | return null 136 | } 137 | ```` 138 | 139 | 11、原生JavaScript加入收藏夹 140 | 141 | ```javascript 142 | function AddFavorite(sURL, sTitle) { 143 | try { 144 | window.external.addFavorite(sURL, sTitle) 145 | } catch(e) { 146 | try { 147 | window.sidebar.addPanel(sTitle, sURL, "") 148 | } catch(e) { 149 | alert("加入收藏失败,请使用Ctrl+D进行添加") 150 | } 151 | } 152 | } 153 | ```` 154 | 155 | 12、原生JavaScript设为首页 156 | 157 | ```javascript 158 | function setHomepage() { 159 | if (document.all) { 160 | document.body.style.behavior = 'url(#default#homepage)'; 161 | document.body.setHomePage('http://www.jq-school.com') 162 | } else if (window.sidebar) { 163 | if (window.netscape) { 164 | try { 165 | netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect") 166 | } catch(e) { 167 | alert("该操作被浏览器拒绝,如果想启用该功能,请在地址栏内输入 about:config,然后将项 signed.applets.codebase_principal_support 值该为true") 168 | } 169 | } 170 | var prefs = Components.classes['@mozilla.org/preferences-service;1'].getService(Components.interfaces.nsIPrefBranch); 171 | prefs.setCharPref('browser.startup.homepage', 'http://www.jq-school.com') 172 | } 173 | } 174 | ```` 175 | 176 | 13、原生JavaScript判断IE6 177 | 178 | ```javascript 179 | var ua = navigator.userAgent.toLowerCase(); 180 | var isIE6 = ua.indexOf("msie 6") > -1; 181 | if (isIE6) { 182 | try { 183 | document.execCommand("BackgroundImageCache", false, true) 184 | } catch(e) {} 185 | } 186 | ```` 187 | 188 | 14、原生JavaScript加载样式文件 189 | 190 | ```javascript 191 | function LoadStyle(url) { 192 | try { 193 | document.createStyleSheet(url) 194 | } catch(e) { 195 | var cssLink = document.createElement('link'); 196 | cssLink.rel = 'stylesheet'; 197 | cssLink.type = 'text/css'; 198 | cssLink.href = url; 199 | var head = document.getElementsByTagName('head')[0]; 200 | head.appendChild(cssLink) 201 | } 202 | } 203 | ```` 204 | 205 | 15、原生JavaScript返回脚本内容 206 | 207 | ```javascript 208 | function evalscript(s) { 209 | if(s.indexOf(']*?>([^\x00]*?)<\/script>/ig; 211 | var arr = []; 212 | while(arr = p.exec(s)) { 213 | var p1 = /]*?src=\"([^\>]*?)\"[^\>]*?(reload=\"1\")?(?:charset=\"([\w\-]+?)\")?><\/script>/i; 214 | var arr1 = []; 215 | arr1 = p1.exec(arr[0]); 216 | if(arr1) { 217 | appendscript(arr1[1], '', arr1[2], arr1[3]); 218 | } else { 219 | p1 = /([^\x00]+?)<\/script>/i; 220 | arr1 = p1.exec(arr[0]); 221 | appendscript('', arr1[2], arr1[1].indexOf('reload=') != -1); 222 | } 223 | } 224 | return s; 225 | } 226 | ```` 227 | 228 | 16、原生JavaScript清除脚本内容 229 | 230 | ```javascript 231 | function stripscript(s) { 232 | return s.replace(/.*?<\/script>/ig, ''); 233 | } 234 | ```` 235 | 236 | 17、原生JavaScript动态加载脚本文件 237 | 238 | ```javascript 239 | function appendscript(src, text, reload, charset) { 240 | var id = hash(src + text); 241 | if(!reload && in_array(id, evalscripts)) return; 242 | if(reload && $(id)) { 243 | $(id).parentNode.removeChild($(id)); 244 | } 245 | 246 | evalscripts.push(id); 247 | var scriptNode = document.createElement("script"); 248 | scriptNode.type = "text/javascript"; 249 | scriptNode.id = id; 250 | scriptNode.charset = charset ? charset : (BROWSER.firefox ? document.characterSet : document.charset); 251 | try { 252 | if(src) { 253 | scriptNode.src="\'#\'" = false; 254 | scriptNode.onload = 255 | function () { 256 | scriptNode. = true; 257 | JSLOADED[src] = 1; 258 | }; 259 | scriptNode.onreadystatechange = 260 | function () { 261 | if((scriptNode.readyState == 'loaded' || scriptNode.readyState == 'complete') && !scriptNode. { 262 | scriptNode. = true; 263 | JSLOADED[src] = 1; 264 | } 265 | }; 266 | } else if(text){ 267 | scriptNode.text = text; 268 | } 269 | document.getElementsByTagName('head')[0].appendChild(scriptNode); 270 | } catch(e) {} 271 | } 272 | ```` 273 | 274 | 18、原生JavaScript返回按ID检索的元素对象 275 | 276 | ```javascript 277 | function $(id) { 278 | return !id ? null : document.getElementById(id); 279 | } 280 | ```` 281 | 282 | 19、原生JavaScript返回浏览器版本内容 283 | 284 | ```javascript 285 | function browserVersion(types) { 286 | var other = 1; 287 | for(i in types) { 288 | var v = types[i] ? types[i] : i; 289 | if(USERAGENT.indexOf(v) != -1) { 290 | var re = new RegExp(v + '(\\/|\\s)([\\d\\.]+)', 'ig'); 291 | var matches = re.exec(USERAGENT); 292 | var ver = matches != null ? matches[2] : 0; 293 | other = ver !== 0 && v != 'mozilla' ? 0 : other; 294 | }else { 295 | var ver = 0; 296 | } 297 | eval('BROWSER.' + i + '= ver'); 298 | } 299 | BROWSER.other = other; 300 | } 301 | ```` 302 | 303 | 20、原生JavaScript元素显示的通用方法 304 | 305 | ```javascript 306 | function $(id) { 307 | return !id ? null : document.getElementById(id); 308 | } 309 | 310 | function display(id) { 311 | var obj = $(id); 312 | if(obj.style.visibility) { 313 | obj.style.visibility = obj.style.visibility == 'visible' ? 'hidden' : 'visible'; 314 | } else { 315 | obj.style.display = obj.style.display == '' ? 'none' : ''; 316 | } 317 | } 318 | ```` 319 | 320 | 21、原生JavaScript中有insertBefore方法,可惜却没有insertAfter方法?用如下函数实现 321 | 322 | ```javascript 323 | function insertAfter(newChild,refChild){ 324 | var parElem=refChild.parentNode; 325 | if(parElem.lastChild==refChild){ 326 | refChild.appendChild(newChild); 327 | }else{ 328 | parElem.insertBefore(newChild,refChild.nextSibling); 329 | } 330 | } 331 | ```` 332 | 333 | 22、原生JavaScript中兼容浏览器绑定元素事件 334 | 335 | ```javascript 336 | function addEventSamp(obj,evt,fn){ 337 | if (obj.addEventListener) { 338 | obj.addEventListener(evt, fn, false); 339 | }else if(obj.attachEvent){ 340 | obj.attachEvent('on'+evt,fn); 341 | } 342 | } 343 | ```` 344 | 345 | 23、原生JavaScript光标停在文字的后面,文本框获得焦点时调用 346 | 347 | ```javascript 348 | function focusLast(){ 349 | var e = event.srcElement; 350 | var r =e.createTextRange(); 351 | r.moveStart('character',e.value.length); 352 | r.collapse(true); 353 | r.select(); 354 | } 355 | ```` 356 | 357 | 24、原生JavaScript检验URL链接是否有效 358 | 359 | ```javascript 360 | function getUrlState(URL){ 361 | var xmlhttp = new ActiveXObject("microsoft.xmlhttp"); 362 | xmlhttp.Open("GET",URL, false); 363 | try{ 364 | xmlhttp.Send(); 365 | }catch(e){ 366 | }finally{ 367 | var result = xmlhttp.responseText; 368 | if(result){ 369 | if(xmlhttp.Status==200){ 370 | return(true); 371 | }else{ 372 | return(false); 373 | } 374 | }else{ 375 | return(false); 376 | } 377 | } 378 | } 379 | ```` 380 | 381 | 25、原生JavaScript格式化CSS样式代码 382 | 383 | ```javascript 384 | function formatCss(s){//格式化代码 385 | s = s.replace(/\s*([\{\}\:\;\,])\s*/g, "$1"); 386 | s = s.replace(/;\s*;/g, ";"); //清除连续分号 387 | s = s.replace(/\,[\s\.\#\d]*{/g, "{"); 388 | s = s.replace(/([^\s])\{([^\s])/g, "$1 {\n\t$2"); 389 | s = s.replace(/([^\s])\}([^\n]*)/g, "$1\n}\n$2"); 390 | s = s.replace(/([^\s]);([^\s\}])/g, "$1;\n\t$2"); 391 | return s; 392 | } 393 | ```` 394 | 395 | 26、原生JavaScript压缩CSS样式代码 396 | 397 | ```javascript 398 | function yasuoCss (s) {//压缩代码 399 | s = s.replace(/\/\*(.|\n)*?\*\//g, ""); //删除注释 400 | s = s.replace(/\s*([\{\}\:\;\,])\s*/g, "$1"); 401 | s = s.replace(/\,[\s\.\#\d]*\{/g, "{"); //容错处理 402 | s = s.replace(/;\s*;/g, ";"); //清除连续分号 403 | s = s.match(/^\s*(\S+(\s+\S+)*)\s*$/); //去掉首尾空白 404 | return (s == null) ? "" : s[1]; 405 | } 406 | ```` 407 | 408 | 27、原生JavaScript获取当前路径 409 | 410 | ```javascript 411 | var currentPageUrl = ""; 412 | if (typeof this.href === "undefined") { 413 | currentPageUrl = document.location.toString().toLowerCase(); 414 | } 415 | else { 416 | currentPageUrl = this.href.toString().toLowerCase(); 417 | } 418 | ```` 419 | 420 | 28、原生JavaScriptIP转成整型 421 | 422 | ```javascript 423 | function _ip2int(ip){ 424 | var num = 0; 425 | ip = ip.split("."); 426 | num = Number(ip[0]) * 256 * 256 * 256 + Number(ip[1]) * 256 * 256 + Number(ip[2]) * 256 + Number(ip[3]); 427 | num = num >>> 0; 428 | return num; 429 | } 430 | ```` 431 | 432 | 29、原生JavaScript整型解析为IP地址 433 | 434 | ```javascript 435 | function _int2iP(num){ 436 | var str; 437 | var tt = new Array(); 438 | tt[0] = (num >>> 24) >>> 0; 439 | tt[1] = ((num << 8) >>> 24) >>> 0; 440 | tt[2] = (num << 16) >>> 24; 441 | tt[3] = (num << 24) >>> 24; 442 | str = String(tt[0]) + "." + String(tt[1]) + "." + String(tt[2]) + "." + String(tt[3]); 443 | return str; 444 | } 445 | ```` 446 | 447 | 30、原生JavaScript实现checkbox全选与全不选 448 | 449 | ```javascript 450 | function checkAll() { 451 | var selectall = document.getElementById("selectall"); 452 | var allbox = document.getElementsByName("allbox"); 453 | if (selectall.checked) { 454 | for (var i = 0; i < allbox.length; i++) { 455 | allbox[i].checked = true; 456 | } 457 | } else { 458 | for (var i = 0; i < allbox.length; i++) { 459 | allbox[i].checked = false; 460 | } 461 | } 462 | } 463 | ```` 464 | 465 | 31、原生JavaScript判断是否移动设备 466 | 467 | ```javascript 468 | function isMobile(){ 469 | if (typeof this._isMobile === 'boolean'){ 470 | return this._isMobile; 471 | } 472 | var screenWidth = this.getScreenWidth(); 473 | var fixViewPortsExperiment = rendererModel.runningExperiments.FixViewport || rendererModel.runningExperiments.fixviewport; 474 | var fixViewPortsExperimentRunning = fixViewPortsExperiment && (fixViewPortsExperiment.toLowerCase() === "new"); 475 | if(!fixViewPortsExperiment){ 476 | if(!this.isAppleMobileDevice()){ 477 | screenWidth = screenWidth/window.devicePixelRatio; 478 | } 479 | } 480 | var isMobileScreenSize = screenWidth < 600; 481 | var isMobileUserAgent = false; 482 | this._isMobile = isMobileScreenSize && this.isTouchScreen(); 483 | return this._isMobile; 484 | } 485 | ```` 486 | 487 | 32、原生JavaScript判断是否移动设备访问 488 | 489 | ```javascript 490 | function isMobileUserAgent(){ 491 | return (/iphone|ipod|android.*mobile|windows.*phone|blackberry.*mobile/i.test(window.navigator.userAgent.toLowerCase())); 492 | } 493 | ```` 494 | 495 | 33、原生JavaScript判断是否苹果移动设备访问 496 | 497 | ```javascript 498 | function isAppleMobileDevice(){ 499 | return (/iphone|ipod|ipad|Macintosh/i.test(navigator.userAgent.toLowerCase())); 500 | } 501 | ```` 502 | 503 | 34、原生JavaScript判断是否安卓移动设备访问 504 | 505 | ```javascript 506 | function isAndroidMobileDevice(){ 507 | return (/android/i.test(navigator.userAgent.toLowerCase())); 508 | } 509 | ```` 510 | 511 | 35、原生JavaScript判断是否Touch屏幕 512 | 513 | ```javascript 514 | function isTouchScreen(){ 515 | return (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch); 516 | } 517 | ```` 518 | 519 | 36、原生JavaScript判断是否在安卓上的谷歌浏览器 520 | 521 | ```javascript 522 | function isNewChromeOnAndroid(){ 523 | if(this.isAndroidMobileDevice()){ 524 | var userAgent = navigator.userAgent.toLowerCase(); 525 | if((/chrome/i.test(userAgent))){ 526 | var parts = userAgent.split('chrome/'); 527 | 528 | var fullVersionString = parts[1].split(" ")[0]; 529 | var versionString = fullVersionString.split('.')[0]; 530 | var version = parseInt(versionString); 531 | 532 | if(version >= 27){ 533 | return true; 534 | } 535 | } 536 | } 537 | return false; 538 | } 539 | ```` 540 | 541 | 37、原生JavaScript判断是否打开视窗 542 | 543 | ```javascript 544 | function isViewportOpen() { 545 | return !!document.getElementById('wixMobileViewport'); 546 | } 547 | ```` 548 | 549 | 38、原生JavaScript获取移动设备初始化大小 550 | 551 | ```javascript 552 | function getInitZoom(){ 553 | if(!this._initZoom){ 554 | var screenWidth = Math.min(screen.height, screen.width); 555 | if(this.isAndroidMobileDevice() && !this.isNewChromeOnAndroid()){ 556 | screenWidth = screenWidth/window.devicePixelRatio; 557 | } 558 | this._initZoom = screenWidth /document.body.offsetWidth; 559 | } 560 | return this._initZoom; 561 | } 562 | ```` 563 | 564 | 39、原生JavaScript获取移动设备最大化大小 565 | 566 | ```javascript 567 | function getZoom(){ 568 | var screenWidth = (Math.abs(window.orientation) === 90) ? Math.max(screen.height, screen.width) : Math.min(screen.height, screen.width); 569 | if(this.isAndroidMobileDevice() && !this.isNewChromeOnAndroid()){ 570 | screenWidth = screenWidth/window.devicePixelRatio; 571 | } 572 | var FixViewPortsExperiment = rendererModel.runningExperiments.FixViewport || rendererModel.runningExperiments.fixviewport; 573 | var FixViewPortsExperimentRunning = FixViewPortsExperiment && (FixViewPortsExperiment === "New" || FixViewPortsExperiment === "new"); 574 | if(FixViewPortsExperimentRunning){ 575 | return screenWidth / window.innerWidth; 576 | }else{ 577 | return screenWidth / document.body.offsetWidth; 578 | } 579 | } 580 | ```` 581 | 582 | 40、原生JavaScript获取移动设备屏幕宽度 583 | 584 | ```javascript 585 | function getScreenWidth(){ 586 | var smallerSide = Math.min(screen.width, screen.height); 587 | var fixViewPortsExperiment = rendererModel.runningExperiments.FixViewport || rendererModel.runningExperiments.fixviewport; 588 | var fixViewPortsExperimentRunning = fixViewPortsExperiment && (fixViewPortsExperiment.toLowerCase() === "new"); 589 | if(fixViewPortsExperiment){ 590 | if(this.isAndroidMobileDevice() && !this.isNewChromeOnAndroid()){ 591 | smallerSide = smallerSide/window.devicePixelRatio; 592 | } 593 | } 594 | return smallerSide; 595 | } 596 | ```` 597 | 598 | 41、原生JavaScript完美判断是否为网址 599 | 600 | ```javascript 601 | function IsURL(strUrl) { 602 | var regular = /^\b(((https?|ftp):\/\/)?[-a-z0-9]+(\.[-a-z0-9]+)*\.(?:com|edu|gov|int|mil|net|org|biz|info|name|museum|asia|coop|aero|[a-z][a-z]|((25[0-5])|(2[0-4]\d)|(1\d\d)|([1-9]\d)|\d))\b(\/[-a-z0-9_:\@&?=+,.!\/~%\$]*)?)$/i 603 | if (regular.test(strUrl)) { 604 | return true; 605 | } 606 | else { 607 | return false; 608 | } 609 | } 610 | ```` 611 | 612 | 42、原生JavaScript根据样式名称检索元素对象 613 | 614 | ```javascript 615 | function getElementsByClassName(name) { 616 | var tags = document.getElementsByTagName('*') || document.all; 617 | var els = []; 618 | for (var i = 0; i < tags.length; i++) { 619 | if (tags[i].className) { 620 | var cs = tags[i].className.split(' '); 621 | for (var j = 0; j < cs.length; j++) { 622 | if (name == cs[j]) { 623 | els.push(tags[i]); 624 | break 625 | } 626 | } 627 | } 628 | } 629 | return els 630 | } 631 | ```` 632 | 633 | 43、原生JavaScript判断是否以某个字符串开头 634 | 635 | ```javascript 636 | String.prototype.startWith = 637 | function (s) { 638 | return this.indexOf(s) == 0 639 | } 640 | ```` 641 | 642 | 44、原生JavaScript判断是否以某个字符串结束 643 | 644 | ```javascript 645 | String.prototype.endWith = 646 | function (s) { 647 | var d = this.length - s.length; 648 | return (d >= 0 && this.lastIndexOf(s) == d) 649 | } 650 | ```` 651 | 652 | 45、原生JavaScript返回IE浏览器的版本号 653 | 654 | ```javascript 655 | function getIE(){ 656 | if (window.ActiveXObject){ 657 | var v = navigator.userAgent.match(/MSIE ([^;]+)/)[1]; 658 | return parseFloat(v.substring(0, v.indexOf("."))) 659 | } 660 | return false 661 | } 662 | ```` 663 | 664 | 46、原生JavaScript获取页面高度 665 | 666 | ```javascript 667 | function getPageHeight(){ 668 | var g = document, a = g.body, f = g.documentElement, d = g.compatMode == "BackCompat" 669 | ? a 670 | : g.documentElement; 671 | return Math.max(f.scrollHeight, a.scrollHeight, d.clientHeight); 672 | } 673 | ```` 674 | 675 | 47、原生JavaScript获取页面scrollLeft 676 | 677 | ```javascript 678 | function getPageScrollLeft(){ 679 | var a = document; 680 | return a.documentElement.scrollLeft || a.body.scrollLeft; 681 | } 682 | ```` 683 | 684 | 48、原生JavaScript获取页面可视宽度 685 | 686 | ```javascript 687 | function getPageViewWidth(){ 688 | var d = document, a = d.compatMode == "BackCompat" 689 | ? d.body 690 | : d.documentElement; 691 | return a.clientWidth; 692 | } 693 | ```` 694 | 695 | 49、原生JavaScript获取页面宽度 696 | 697 | ```javascript 698 | function getPageWidth(){ 699 | var g = document, a = g.body, f = g.documentElement, d = g.compatMode == "BackCompat" 700 | ? a 701 | : g.documentElement; 702 | return Math.max(f.scrollWidth, a.scrollWidth, d.clientWidth); 703 | } 704 | 50、原生JavaScript获取页面scrollTop 705 | 706 | ```javascript 707 | function getPageScrollTop(){ 708 | var a = document; 709 | return a.documentElement.scrollTop || a.body.scrollTop; 710 | } 711 | ```` 712 | 713 | 61、原生JavaScript解决offsetX兼容性问题 714 | 715 | ```javascript 716 | // 针对火狐不支持offsetX/Y 717 | 718 | function getOffset(e){ 719 | var target = e.target, // 当前触发的目标对象 720 | eventCoord, 721 | pageCoord, 722 | offsetCoord; 723 | 724 | 725 | // 计算当前触发元素到文档的距离 726 | pageCoord = getPageCoord(target); 727 | 728 | 729 | // 计算光标到文档的距离 730 | eventCoord = { 731 | X : window.pageXOffset + e.clientX, 732 | Y : window.pageYOffset + e.clientY 733 | }; 734 | 735 | 736 | // 相减获取光标到第一个定位的父元素的坐标 737 | offsetCoord = { 738 | X : eventCoord.X - pageCoord.X, 739 | Y : eventCoord.Y - pageCoord.Y 740 | }; 741 | return offsetCoord; 742 | } 743 | 744 | 745 | 746 | function getPageCoord(element){ 747 | var coord = { X : 0, Y : 0 }; 748 | // 计算从当前触发元素到根节点为止, 749 | // 各级 offsetParent 元素的 offsetLeft 或 offsetTop 值之和 750 | while (element){ 751 | coord.X += element.offsetLeft; 752 | coord.Y += element.offsetTop; 753 | element = element.offsetParent; 754 | } 755 | return coord; 756 | } 757 | ```` 758 | 759 | 62、原生JavaScript常用的正则表达式 760 | 761 | ```javascript 762 | //正整数 763 | /^[0-9]*[1-9][0-9]*$/; 764 | //负整数 765 | /^-[0-9]*[1-9][0-9]*$/; 766 | //正浮点数 767 | /^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$/; 768 | //负浮点数 769 | /^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$/; 770 | //浮点数 771 | /^(-?\d+)(\.\d+)?$/; 772 | //email地址 773 | /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/; 774 | //url地址 775 | /^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$/; 776 | //年/月/日(年-月-日、年.月.日) 777 | /^(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$/; 778 | //匹配中文字符 779 | /[\u4e00-\u9fa5]/; 780 | //匹配帐号是否合法(字母开头,允许5-10字节,允许字母数字下划线) 781 | /^[a-zA-Z][a-zA-Z0-9_]{4,9}$/; 782 | //匹配空白行的正则表达式 783 | /\n\s*\r/; 784 | //匹配中国邮政编码 785 | /[1-9]\d{5}(?!\d)/; 786 | //匹配身份证 787 | /\d{15}|\d{18}/; 788 | //匹配国内电话号码 789 | /(\d{3}-|\d{4}-)?(\d{8}|\d{7})?/; 790 | //匹配IP地址 791 | /((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)/; 792 | //匹配首尾空白字符的正则表达式 793 | /^\s*|\s*$/; 794 | //匹配HTML标记的正则表达式 795 | < (\S*?)[^>]*>.*?|< .*? />; 796 | ```` 797 | 798 | 63、原生JavaScript实现返回顶部的通用方法 799 | 800 | ```javascript 801 | function backTop(btnId) { 802 | var btn = document.getElementById(btnId); 803 | var d = document.documentElement; 804 | var b = document.body; 805 | window.onscroll = set; 806 | btn.style.display = "none"; 807 | btn.onclick = 808 | function() { 809 | btn.style.display = "none"; 810 | window.onscroll = null; 811 | this.timer = setInterval( 812 | function() { 813 | d.scrollTop -= Math.ceil((d.scrollTop + b.scrollTop) * 0.1); 814 | b.scrollTop -= Math.ceil((d.scrollTop + b.scrollTop) * 0.1); 815 | if ((d.scrollTop + b.scrollTop) == 0) clearInterval(btn.timer, window.onscroll = set); 816 | }, 817 | 10); 818 | }; 819 | 820 | function set() { 821 | btn.style.display = (d.scrollTop + b.scrollTop > 100) ? 'block': "none" 822 | } 823 | }; 824 | backTop('goTop'); 825 | ```` 826 | 827 | 64、原生JavaScript获得URL中GET参数值 828 | 829 | ```javascript 830 | // 用法:如果地址是 test.htm?t1=1&t2=2&t3=3, 那么能取得:GET["t1"], GET["t2"], GET["t3"] 831 | 832 | function get_get(){ 833 | querystr = window.location.href.split("?") 834 | if(querystr[1]){ 835 | GETs = querystr[1].split("&") 836 | GET =new Array() 837 | for(i=0;i -1; 906 | } 907 | if (o == 'isIE'){ 908 | t = b.indexOf('msie') > -1; 909 | } 910 | if (o == 'isFF'){ 911 | t = b.indexOf('firefox') > -1; 912 | } 913 | return t; 914 | } 915 | ```` 916 | 917 | 69、原生JavaScript获取单选按钮的值 918 | 919 | ```javascript 920 | function get_radio_value(field){ 921 | if(field&&field.length){ 922 | for(var i=0;i|\[|\]|\{|\}|『|』|※|○|●|◎|§|△|▲|☆|★|◇|◆|□|▼|㊣|﹋|⊕|⊙|〒|ㄅ|ㄆ|ㄇ|ㄈ|ㄉ|ㄊ|ㄋ|ㄌ|ㄍ|ㄎ|ㄏ|ㄐ|ㄑ|ㄒ|ㄓ|ㄔ|ㄕ|ㄖ|ㄗ|ㄘ|ㄙ|ㄚ|ㄛ|ㄜ|ㄝ|ㄞ|ㄟ|ㄢ|ㄣ|ㄤ|ㄥ|ㄦ|ㄧ|ㄨ|ㄩ|■|▄|▆|\*|@|#|\^|\\/; 967 | if (re.test( chars) == true) { 968 | return false; 969 | }else{ 970 | return true; 971 | } 972 | } 973 | ```` 974 | 975 | 73、原生JavaScript判断字符串是否大于规定的长度 976 | 977 | ```javascript 978 | function isValidLength(chars, len) { 979 | if (chars.length < len) { 980 | return false; 981 | } 982 | return true; 983 | } 984 | ```` 985 | 986 | 74、原生JavaScript判断字符串是为网址不区分大小写 987 | 988 | ```javascript 989 | function isValidURL( chars ) { 990 | var re=/^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(\S+\.\S+)$/; 991 | if (!isNULL(chars)) { 992 | chars = jsTrim(chars); 993 | if (chars.match(re) == null) 994 | return false; 995 | else 996 | return true; 997 | } 998 | return false; 999 | } 1000 | ```` 1001 | 1002 | 75、原生JavaScript判断字符串是否为小数 1003 | 1004 | ```javascript 1005 | function isValidDecimal( chars ) { 1006 | var re=/^\d*\.?\d{1,2}$/; 1007 | if (chars.match(re) == null) 1008 | return false; 1009 | else 1010 | return true; 1011 | } 1012 | ```` 1013 | 1014 | 76、原生JavaScript判断字符串是否为整数 1015 | 1016 | ```javascript 1017 | function isNumber( chars ) { 1018 | var re=/^\d*$/; 1019 | if (chars.match(re) == null) 1020 | return false; 1021 | else 1022 | return true; 1023 | } 1024 | ```` 1025 | 1026 | 77、原生JavaScript判断字符串是否为浮点数 1027 | 1028 | ```javascript 1029 | function isFloat( str ) { 1030 | for(i=0;i"9")&& str.charAt(i) != '.'){ 1032 | return false; 1033 | } 1034 | } 1035 | return true; 1036 | } 1037 | ```` 1038 | 1039 | 78、原生JavaScript判断字符是否为A-Za-z英文字母 1040 | 1041 | ```javascript 1042 | function isLetters( str ){ 1043 | var re=/^[A-Za-z]+$/; 1044 | if (str.match(re) == null) 1045 | return false; 1046 | else 1047 | return true; 1048 | } 1049 | ```` 1050 | 1051 | 79、原生JavaScript判断字符串是否邮政编码 1052 | 1053 | ```javascript 1054 | function isValidPost( chars ) { 1055 | var re=/^\d{6}$/; 1056 | if (chars.match(re) == null) 1057 | return false; 1058 | else 1059 | return true; 1060 | } 1061 | ```` 1062 | 1063 | 80、原生JavaScript判断字符是否空NULL 1064 | 1065 | ```javascript 1066 | function isNULL( chars ) { 1067 | if (chars == null) 1068 | return true; 1069 | if (jsTrim(chars).length==0) 1070 | return true; 1071 | return false; 1072 | } 1073 | ```` 1074 | 1075 | 81、原生JavaScript用正则表达式提取页面代码中所有网址 1076 | 1077 | ```javascript 1078 | var aa = document.documentElement.outerHTML.match(/(url\(|src=\'#\'" ]+)[\"\'\)]*|(http:\/\/[\w\-\.]+[^\"\'\(\)\<\>\[\] ]+)/ig).join("\r\n").replace(/^(src=\'#\'" ) ]*$/igm,""); 1079 | alert(aa) 1080 | ```` 1081 | 1082 | 82、原生JavaScript用正则表达式清除相同的数组(低效率) 1083 | 1084 | ```javascript 1085 | Array.prototype.unique= 1086 | function(){ 1087 | return this.reverse().join(",").match(/([^,]+)(?!.*\1)/ig).reverse(); 1088 | } 1089 | ```` 1090 | 1091 | 83、原生JavaScript用正则表达式清除相同的数组(高效率) 1092 | 1093 | ```javascript 1094 | String.prototype.unique= 1095 | function(){ 1096 | var x=this.split(/[\r\n]+/); 1097 | var y=''; 1098 | for(var i=0;i[\s\S]*?<\/script>|\s+on[a-zA-Z]{3,16}\s?=\s?"[\s\S]*?"|\s+on[a-zA-Z]{3,16}\s?=\s?'[\s\S]*?'|\s+on[a-zA-Z]{3,16}\s?=[^ >]+/ig,""); 1130 | } 1131 | ```` 1132 | 1133 | 87、原生JavaScript动态执行JavaScript脚本 1134 | 1135 | ```javascript 1136 | function javascript(){ 1137 | try{ 1138 | eval(K1.value); 1139 | }catch(e){ 1140 | alert(e.message); 1141 | } 1142 | } 1143 | ```` 1144 | 1145 | 88、原生JavaScript动态执行VBScript脚本 1146 | 1147 | ```javascript 1148 | function vbscript(){ 1149 | try{ 1150 | var script=document.getElementById("K1").value; 1151 | if(script.trim()=="")return; 1152 | window.execScript('On Error Resume Next \n'+script+'\n If Err.Number<>0 Then \n MsgBox "请输入正确的VBScript脚本!",48,"脚本错误!" \n End If',"vbscript") 1153 | }catch(e){ 1154 | alert(e.message); 1155 | } 1156 | } 1157 | ```` 1158 | 1159 | 89、原生JavaScript实现金额大写转换函数 1160 | 1161 | ```javascript 1162 | function transform(tranvalue) { 1163 | try { 1164 | var i = 1; 1165 | var dw2 = new Array("", "万", "亿"); //大单位 1166 | var dw1 = new Array("拾", "佰", "仟"); //小单位 1167 | var dw = new Array("零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"); //整数部分用 1168 | //以下是小写转换成大写显示在合计大写的文本框中 1169 | //分离整数与小数 1170 | var source = splits(tranvalue); 1171 | var num = source[0]; 1172 | var dig = source[1]; 1173 | //转换整数部分 1174 | var k1 = 0; //计小单位 1175 | var k2 = 0; //计大单位 1176 | var sum = 0; 1177 | var str = ""; 1178 | var len = source[0].length; //整数的长度 1179 | for (i = 1; i <= len; i++) { 1180 | var n = source[0].charAt(len - i); //取得某个位数上的数字 1181 | var bn = 0; 1182 | if (len - i - 1 >= 0) { 1183 | bn = source[0].charAt(len - i - 1); //取得某个位数前一位上的数字 1184 | } 1185 | sum = sum + Number(n); 1186 | if (sum != 0) { 1187 | str = dw[Number(n)].concat(str); //取得该数字对应的大写数字,并插入到str字符串的前面 1188 | if (n == '0') sum = 0; 1189 | } 1190 | if (len - i - 1 >= 0) { //在数字范围内 1191 | if (k1 != 3) { //加小单位 1192 | if (bn != 0) { 1193 | str = dw1[k1].concat(str); 1194 | } 1195 | k1++; 1196 | } else { //不加小单位,加大单位 1197 | k1 = 0; 1198 | var temp = str.charAt(0); 1199 | if (temp == "万" || temp == "亿") //若大单位前没有数字则舍去大单位 1200 | str = str.substr(1, str.length - 1); 1201 | str = dw2[k2].concat(str); 1202 | sum = 0; 1203 | } 1204 | } 1205 | if (k1 == 3) //小单位到千则大单位进一 1206 | { 1207 | k2++; 1208 | } 1209 | } 1210 | //转换小数部分 1211 | var strdig = ""; 1212 | if (dig != "") { 1213 | var n = dig.charAt(0); 1214 | if (n != 0) { 1215 | strdig += dw[Number(n)] + "角"; //加数字 1216 | } 1217 | var n = dig.charAt(1); 1218 | if (n != 0) { 1219 | strdig += dw[Number(n)] + "分"; //加数字 1220 | } 1221 | } 1222 | str += "元" + strdig; 1223 | } catch(e) { 1224 | return "0元"; 1225 | } 1226 | return str; 1227 | } 1228 | //拆分整数与小数 1229 | 1230 | function splits(tranvalue) { 1231 | var value = new Array('', ''); 1232 | temp = tranvalue.split("."); 1233 | for (var i = 0; i < temp.length; i++) { 1234 | value[i] = temp[i]; 1235 | } 1236 | return value; 1237 | } 1238 | ```` 1239 | 1240 | 90、原生JavaScript常用的正则表达式大收集 1241 | 1242 | ```javascript 1243 | 匹配中文字符的正则表达式: [\u4e00-\u9fa5] 1244 | 匹配双字节字符(包括汉字在内):[^\x00-\xff] 1245 | 匹配空行的正则表达式:\n[\s| ]*\r 1246 | 匹配 HTML 标记的正则表达式:<(.*)>.*<\/\1>|<(.*) \/> 1247 | 匹配首尾空格的正则表达式:(^\s*)|(\s*$) 1248 | 匹配 IP 地址的正则表达式:/(\d+)\.(\d+)\.(\d+)\.(\d+)/g 1249 | 匹配 Email 地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* 1250 | 匹配网址 URL 的正则表达式:http://(/[\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)? 1251 | sql 语句:^(select|drop|delete|create|update|insert).*$ 1252 | 非负整数:^\d+$ 1253 | 正整数:^[0-9]*[1-9][0-9]*$ 1254 | 非正整数:^((-\d+)|(0+))$ 1255 | 负整数:^-[0-9]*[1-9][0-9]*$ 1256 | 整数:^-?\d+$ 1257 | 非负浮点数:^\d+(\.\d+)?$ 1258 | 正浮点数:^((0-9)+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$ 1259 | 非正浮点数:^((-\d+\.\d+)?)|(0+(\.0+)?))$ 1260 | 英文字符串:^[A-Za-z]+$ 1261 | 英文大写串:^[A-Z]+$ 1262 | 英文小写串:^[a-z]+$ 1263 | 英文字符数字串:^[A-Za-z0-9]+$ 1264 | 英数字加下划线串:^\w+$ 1265 | E-mail地址:^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$ 1266 | URL:^[a-zA-Z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\s*)?$ 或:^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$ 1267 | 邮政编码:^[1-9]\d{5}$ 1268 | 电话号码:^((\(\d{2,3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$ 1269 | 手机号码:^((\(\d{2,3}\))|(\d{3}\-))?13\d{9}$ 1270 | 双字节字符(包括汉字在内):^\x00-\xff 1271 | 匹配首尾空格:(^\s*)|(\s*$) 1272 | 匹配 HTML 标记:<(.*)>.*<\/\1>|<(.*) \/> 1273 | 匹配空行:\n[\s| ]*\r 1274 | 提取信息中的网络链接:(h|H)(r|R)(e|E)(f|F) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)? 1275 | 提取信息中的邮件地址:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* 1276 | 提取信息中的图片链接:(s|S)(r|R)(c|C) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)? 1277 | 提取信息中的 IP 地址:(\d+)\.(\d+)\.(\d+)\.(\d+) 1278 | 提取信息中的中国手机号码:(86)*0*13\d{9} 1279 | 提取信息中的中国固定电话号码:(\(\d{3,4}\)|\d{3,4}-|\s)?\d{8} 1280 | 提取信息中的中国电话号码(包括移动和固定电话):(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14} 1281 | 提取信息中的中国邮政编码:[1-9]{1}(\d+){5} 1282 | 提取信息中的浮点数(即小数):(-?\d*)\.?\d+ 1283 | 提取信息中的任何数字 :(-?\d*)(\.\d+)? 1284 | IP:(\d+)\.(\d+)\.(\d+)\.(\d+) 1285 | 电话区号:^0\d{2,3}$ 1286 | 腾讯 QQ 号:^[1-9]*[1-9][0-9]*$ 1287 | 帐号(字母开头,允许 5-16 字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$ 1288 | 中文、英文、数字及下划线:^[\u4e00-\u9fa5_a-zA-Z0-9]+$ 1289 | ```` 1290 | 1291 | 91、原生JavaScript实现窗体改变事件resize的操作(兼容所以的浏览器) 1292 | 1293 | ```javascript 1294 | ( 1295 | function(){ 1296 | var fn = 1297 | function(){ 1298 | var w = document.documentElement ? document.documentElement.clientWidth : document.body.clientWidth 1299 | ,r = 1255 1300 | ,b = Element.extend(document.body) 1301 | ,classname = b.className; 1302 | if(w < r){ 1303 | //当窗体的宽度小于1255的时候执行相应的操作 1304 | }else{ 1305 | //当窗体的宽度大于1255的时候执行相应的操作 1306 | } 1307 | } 1308 | if(window.addEventListener){ 1309 | window.addEventListener('resize', 1310 | function(){ fn(); }); 1311 | }else if(window.attachEvent){ 1312 | window.attachEvent('onresize', 1313 | function(){ fn(); }); 1314 | } 1315 | fn(); 1316 | })(); 1317 | ```` 1318 | 1319 | 92、原生JavaScript用正则清除空格分左右 1320 | 1321 | ```javascript 1322 | function ltrim(s){ return s.replace( /^(\s*| *)/, ""); } 1323 | 1324 | function rtrim(s){ return s.replace( /(\s*| *)$/, ""); } 1325 | 1326 | function trim(s){ return ltrim(rtrim(s));} 1327 | ```` 1328 | 1329 | 93、原生JavaScript判断变量是否空值 1330 | 1331 | /** 1332 | * 判断变量是否空值 1333 | * undefined, null, '', false, 0, [], {} 均返回true,否则返回false 1334 | */ 1335 | 1336 | ```javascript 1337 | function empty(v){ 1338 | switch (typeof v){ 1339 | case 'undefined' : return true; 1340 | case 'string' : if(trim(v).length == 0) return true; break; 1341 | case 'boolean' : if(!v) return true; break; 1342 | case 'number' : if(0 === v) return true; break; 1343 | case 'object' : 1344 | if(null === v) return true; 1345 | if(undefined !== v.length && v.length==0) return true; 1346 | for(var k in v){return false;} return true; 1347 | break; 1348 | } 1349 | return false; 1350 | } 1351 | ```` 1352 | 1353 | 94、原生JavaScript实现base64解码 1354 | 1355 | ```javascript 1356 | function base64_decode(data){ 1357 | var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 1358 | var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,ac = 0,dec = "",tmp_arr = []; 1359 | if (!data) { return data; } 1360 | data += ''; 1361 | do { 1362 | h1 = b64.indexOf(data.charAt(i++)); 1363 | h2 = b64.indexOf(data.charAt(i++)); 1364 | h3 = b64.indexOf(data.charAt(i++)); 1365 | h4 = b64.indexOf(data.charAt(i++)); 1366 | bits = h1 << 18 | h2 << 12 | h3 << 6 | h4; 1367 | o1 = bits >> 16 & 0xff; 1368 | o2 = bits >> 8 & 0xff; 1369 | o3 = bits & 0xff; 1370 | if (h3 == 64) { 1371 | tmp_arr[ac++] = String.fromCharCode(o1); 1372 | } else if (h4 == 64) { 1373 | tmp_arr[ac++] = String.fromCharCode(o1, o2); 1374 | } else { 1375 | tmp_arr[ac++] = String.fromCharCode(o1, o2, o3); 1376 | } 1377 | } while (i < data.length); 1378 | dec = tmp_arr.join(''); 1379 | dec = utf8_decode(dec); 1380 | return dec; 1381 | } 1382 | ```` 1383 | 1384 | 95、原生JavaScript实现utf8解码 1385 | 1386 | ```javascript 1387 | function utf8_decode(str_data){ 1388 | var tmp_arr = [],i = 0,ac = 0,c1 = 0,c2 = 0,c3 = 0;str_data += ''; 1389 | while (i < str_data.length) { 1390 | c1 = str_data.charCodeAt(i); 1391 | if (c1 < 128) { 1392 | tmp_arr[ac++] = String.fromCharCode(c1); 1393 | i++; 1394 | } else if (c1 > 191 && c1 < 224) { 1395 | c2 = str_data.charCodeAt(i + 1); 1396 | tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63)); 1397 | i += 2; 1398 | } else { 1399 | c2 = str_data.charCodeAt(i + 1); 1400 | c3 = str_data.charCodeAt(i + 2); 1401 | tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); 1402 | i += 3; 1403 | } 1404 | } 1405 | return tmp_arr.join(''); 1406 | } 1407 | ```` 1408 | 1409 | 96、原生JavaScript获取窗体可见范围的宽与高 1410 | 1411 | ```javascript 1412 | function getViewSize(){ 1413 | var de=document.documentElement; 1414 | var db=document.body; 1415 | var viewW=de.clientWidth==0 ? db.clientWidth : de.clientWidth; 1416 | var viewH=de.clientHeight==0 ? db.clientHeight : de.clientHeight; 1417 | return Array(viewW ,viewH); 1418 | } 1419 | ```` 1420 | 1421 | 97、原生JavaScript判断IE版本号(既简洁、又向后兼容!) 1422 | 1423 | ```javascript 1424 | var _IE = ( function(){ var v = 3, div = document.createElement('div'), all = div.getElementsByTagName('i'); while ( div.innerHTML = '', all[0] ); return v > 4 ? v : false ; }()); 98、原生JavaScript获取浏览器版本号 1425 | 1426 | function browserVersion(types) { 1427 | var other = 1; 1428 | for (i in types) { 1429 | var v = types[i] ? types[i] : i; 1430 | if (USERAGENT.indexOf(v) != -1) { 1431 | var re = new RegExp(v + '(\\/|\\s|:)([\\d\\.]+)', 'ig'); 1432 | var matches = re.exec(USERAGENT); 1433 | var ver = matches != null ? matches[2] : 0; 1434 | other = ver !== 0 && v != 'mozilla' ? 0 : other; 1435 | } else { 1436 | var ver = 0; 1437 | } 1438 | eval('BROWSER.' + i + '= ver'); 1439 | } 1440 | BROWSER.other = other; 1441 | } 1442 | ```` 1443 | 1444 | 99、原生JavaScript半角转换为全角函数 1445 | 1446 | ```javascript 1447 | function ToDBC(str){ 1448 | var result = ''; 1449 | for(var i=0; i < str.length; i++){ 1450 | code = str.charCodeAt(i); 1451 | if(code >= 33 && code <= 126){ 1452 | result += String.fromCharCode(str.charCodeAt(i) + 65248); 1453 | }else if (code == 32){ 1454 | result += String.fromCharCode(str.charCodeAt(i) + 12288 - 32); 1455 | }else{ 1456 | result += str.charAt(i); 1457 | } 1458 | } 1459 | return result; 1460 | } 1461 | ```` 1462 | 1463 | 100、原生JavaScript全角转换为半角函数 1464 | 1465 | ```javascript 1466 | function ToCDB(str){ 1467 | var result = ''; 1468 | for(var i=0; i < str.length; i++){ 1469 | code = str.charCodeAt(i); 1470 | if(code >= 65281 && code <= 65374){ 1471 | result += String.fromCharCode(str.charCodeAt(i) - 65248); 1472 | }else if (code == 12288){ 1473 | result += String.fromCharCode(str.charCodeAt(i) - 12288 + 32); 1474 | }else{ 1475 | result += str.charAt(i); 1476 | } 1477 | } 1478 | return result; 1479 | } 1480 | ```` 1481 | 101、localStorage过期设置 1482 | 1483 | ```javascript 1484 | function set(key,value){ 1485 | var time = +new Date(); 1486 | localStorage.setItem(key,JSON.stringify({data:value,time:time})); 1487 | } 1488 | function get(key,expire){ 1489 | var data = localStorage.getItem(key); 1490 | var obj = JSON.parse(data); 1491 | if(+new Date() - obj.time > expire){ 1492 | console.log('expired'); 1493 | localStorage.removeItem(key); 1494 | }else{ 1495 | console.log(obj.data); 1496 | } 1497 | } 1498 | 1499 | ```` 1500 | 102.数组交集 1501 | ```javascript 1502 | function intersect (arr1,arr2){ 1503 | return arr1.filter(function(v){ 1504 | return ~arr2.indexOf(v); 1505 | }); 1506 | } 1507 | 1508 | ```` 1509 | 1510 | 1511 | -------------------------------------------------------------------------------- /js/ajax.md: -------------------------------------------------------------------------------- 1 | 1、原生Javascript实现监听滚动条ajax加载(GET方法) 2 | 3 | ```javascript 4 | function scrollLoad(options){ 5 | if(window.innerHeight+document.body.scrollTop+options.heightOffset>=document.body.scrollHeight){ 6 | window.onscroll=null; 7 | var xmlhttp; 8 | if(window.XMLHttpRequest){ 9 | xmlhttp=new XMLHttpRequest(); 10 | } 11 | else{ 12 | xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 13 | } 14 | xmlhttp.onreadystatechange = function(){ 15 | if(xmlhttp.readyState==1 && options.before!=undefined) 16 | options.before(); 17 | if(xmlhttp.readyState==4 && options.after!=undefined) 18 | options.after(xmlhttp.responseText,xmlhttp.status); 19 | } 20 | xmlhttp.open("GET",options.url,true); 21 | xmlhttp.send(); 22 | if(!options.isStopped(xmlhttp.responseText,xmlhttp.status)) window.onscroll=function(){ 23 | scrollLoad(options); 24 | } 25 | else window.onscroll=null; 26 | } 27 | }; 28 | window.onscroll=function(){ 29 | scrollLoad({ 30 | url: "./", //相对路径 31 | heightOffset: 30, //触发加载的距离底部的距离 32 | after: function(responseText,status){ //ajax加载之后调用 33 | console.log("success in loading"); 34 | console.log(responseText); 35 | }, 36 | isStopped: function(responseText,status){ //确定何时需要停止监听,需要返回boolean类型 37 | if(responseText==null) 38 | return true; 39 | else return false; 40 | }, 41 | before: function(){ //ajax加载之前调用 42 | console.log("ajax is about to run"); 43 | } 44 | }); 45 | }; 46 | ``` 47 | 48 | -------------------------------------------------------------------------------- /js/event.md: -------------------------------------------------------------------------------- 1 | ### 阻止事件冒泡 2 | ```javascript 3 | stopPropagation 只阻止冒泡过程,不会阻止事件的默认行为 4 | preventDefault 不会阻止冒泡过程,但会阻止默认行为 5 | return false 不仅会阻止冒泡过程,也会组织事件的默认行为 6 | ```` 7 | -------------------------------------------------------------------------------- /js/jquery.md: -------------------------------------------------------------------------------- 1 | ### 缓存变量 2 | DOM遍历是昂贵的,所以尽量将会重用的元素缓存。 3 | ```javascript 4 | // 糟糕 5 | 6 | h = $('#element').height(); 7 | $('#element').css('height',h-20); 8 | 9 | // 建议 10 | 11 | $element = $('#element'); 12 | h = $element.height(); 13 | $element.css('height',h-20); 14 | ``` 15 | ### 避免全局变量 16 | jQuery与javascript一样,一般来说,最好确保你的变量在函数作用域内。 17 | ```javascript 18 | // 糟糕 19 | 20 | $element = $('#element'); 21 | h = $element.height(); 22 | $element.css('height',h-20); 23 | 24 | // 建议 25 | 26 | var $element = $('#element'); 27 | var h = $element.height(); 28 | $element.css('height',h-20); 29 | ``` 30 | ### 使用匈牙利命名法 31 | 在变量前加$前缀,便于识别出jQuery对象。 32 | ```javascript 33 | // 糟糕 34 | 35 | var first = $('#first'); 36 | var second = $('#second'); 37 | var value = $first.val(); 38 | 39 | // 建议 - 在jQuery对象前加$前缀 40 | 41 | var $first = $('#first'); 42 | var $second = $('#second'), 43 | var value = $first.val(); 44 | ``` 45 | ### 使用 Var 链(单 Var 模式) 46 | 将多条var语句合并为一条语句,我建议将未赋值的变量放到后面。 47 | ```javascript 48 | var 49 | $first = $('#first'), 50 | $second = $('#second'), 51 | value = $first.val(), 52 | k = 3, 53 | cookiestring = 'SOMECOOKIESPLEASE', 54 | i, 55 | j, 56 | myArray = {}; 57 | ``` 58 | ### 请使用’On’ 59 | 在新版jQuery中,更短的 on(“click”) 用来取代类似 click() 这样的函数。在之前的版本中 on() 就是 bind()。自从jQuery 1.7版本后,on() 附加事件处理程序的首选方法。然而,出于一致性考虑,你可以简单的全部使用 on()方法。 60 | ```javascript 61 | // 糟糕 62 | 63 | $first.click(function(){ 64 | $first.css('border','1px solid red'); 65 | $first.css('color','blue'); 66 | }); 67 | 68 | $first.hover(function(){ 69 | $first.css('border','1px solid red'); 70 | }) 71 | 72 | // 建议 73 | $first.on('click',function(){ 74 | $first.css('border','1px solid red'); 75 | $first.css('color','blue'); 76 | }) 77 | 78 | $first.on('hover',function(){ 79 | $first.css('border','1px solid red'); 80 | }) 81 | ``` 82 | ### 精简javascript 83 | 一般来说,最好尽可能合并函数。 84 | ```javascript 85 | // 糟糕 86 | 87 | $first.click(function(){ 88 | $first.css('border','1px solid red'); 89 | $first.css('color','blue'); 90 | }); 91 | 92 | // 建议 93 | 94 | $first.on('click',function(){ 95 | $first.css({ 96 | 'border':'1px solid red', 97 | 'color':'blue' 98 | }); 99 | }); 100 | ``` 101 | ### 链式操作 102 | jQuery实现方法的链式操作是非常容易的。下面利用这一点。 103 | ```javascript 104 | // 糟糕 105 | 106 | $second.html(value); 107 | $second.on('click',function(){ 108 | alert('hello everybody'); 109 | }); 110 | $second.fadeIn('slow'); 111 | $second.animate({height:'120px'},500); 112 | 113 | // 建议 114 | 115 | $second.html(value); 116 | $second.on('click',function(){ 117 | alert('hello everybody'); 118 | }).fadeIn('slow').animate({height:'120px'},500); 119 | ``` 120 | ### 维持代码的可读性 121 | 伴随着精简代码和使用链式的同时,可能带来代码的难以阅读。添加缩紧和换行能起到很好的效果。 122 | ```javascript 123 | // 糟糕 124 | 125 | $second.html(value); 126 | $second.on('click',function(){ 127 | alert('hello everybody'); 128 | }).fadeIn('slow').animate({height:'120px'},500); 129 | 130 | // 建议 131 | 132 | $second.html(value); 133 | $second 134 | .on('click',function(){ alert('hello everybody');}) 135 | .fadeIn('slow') 136 | .animate({height:'120px'},500); 137 | ``` 138 | ### 选择短路求值 139 | 短路求值是一个从左到右求值的表达式,用 &&(逻辑与)或 ||(逻辑或)操作符。 140 | ```javascript 141 | // 糟糕 142 | 143 | function initVar($myVar) { 144 | if(!$myVar) { 145 | $myVar = $('#selector'); 146 | } 147 | } 148 | 149 | // 建议 150 | 151 | function initVar($myVar) { 152 | $myVar = $myVar || $('#selector'); 153 | } 154 | ``` 155 | ### 选择捷径 156 | 精简代码的其中一种方式是利用编码捷径。 157 | ```javascript 158 | // 糟糕 159 | 160 | if(collection.length > 0){..} 161 | 162 | // 建议 163 | 164 | if(collection.length){..} 165 | ``` 166 | ### 繁重的操作中分离元素 167 | 如果你打算对DOM元素做大量操作(连续设置多个属性或css样式),建议首先分离元素然后在添加。 168 | ```javascript 169 | // 糟糕 170 | 171 | var 172 | $container = $("#container"), 173 | $containerLi = $("#container li"), 174 | $element = null; 175 | 176 | $element = $containerLi.first(); 177 | //... 许多复杂的操作 178 | 179 | // better 180 | 181 | var 182 | $container = $("#container"), 183 | $containerLi = $container.find("li"), 184 | $element = null; 185 | 186 | $element = $containerLi.first().detach(); 187 | //... 许多复杂的操作 188 | 189 | $container.append($element); 190 | ``` 191 | ### 熟记技巧 192 | 你可能对使用jQuery中的方法缺少经验,一定要查看的文档,可能会有一个更好或更快的方法来使用它。 193 | ```javascript 194 | // 糟糕 195 | 196 | $('#id').data(key,value); 197 | 198 | // 建议 (高效) 199 | 200 | $.data('#id',key,value); 201 | ``` 202 | ### 使用子查询缓存的父元素 203 | 正如前面所提到的,DOM遍历是一项昂贵的操作。典型做法是缓存父元素并在选择子元素时重用这些缓存元素。 204 | ```javascript 205 | // 糟糕 206 | 207 | var 208 | $container = $('#container'), 209 | $containerLi = $('#container li'), 210 | $containerLiSpan = $('#container li span'); 211 | 212 | // 建议 (高效) 213 | 214 | var 215 | $container = $('#container '), 216 | $containerLi = $container.find('li'), 217 | $containerLiSpan= $containerLi.find('span'); 218 | ``` 219 | ### 避免通用选择符 220 | 将通用选择符放到后代选择符中,性能非常糟糕。 221 | ```javascript 222 | // 糟糕 223 | 224 | $('.container > *'); 225 | 226 | // 建议 227 | 228 | $('.container').children(); 229 | ``` 230 | ### 避免隐式通用选择符 231 | 通用选择符有时是隐式的,不容易发现。 232 | ```javascript 233 | // 糟糕 234 | 235 | $('.someclass :radio'); 236 | 237 | // 建议 238 | 239 | $('.someclass input:radio'); 240 | ``` 241 | ### 优化选择符 242 | 例如,Id选择符应该是唯一的,所以没有必要添加额外的选择符。 243 | ```javascript 244 | // 糟糕 245 | 246 | $('div#myid'); 247 | $('div#footer a.myLink'); 248 | 249 | // 建议 250 | $('#myid'); 251 | $('#footer .myLink'); 252 | ``` 253 | ### 避免多个ID选择符 254 | 在此强调,ID 选择符应该是唯一的,不需要添加额外的选择符,更不需要多个后代ID选择符。 255 | ```javascript 256 | // 糟糕 257 | 258 | $('#outer #inner'); 259 | 260 | // 建议 261 | 262 | $('#inner'); 263 | ``` 264 | ### 坚持最新版本 265 | 新版本通常更好:更轻量级,更高效。显然,你需要考虑你要支持的代码的兼容性。例如,2.0版本不支持ie 6/7/8。 266 | 267 | ### 摒弃弃用方法 268 | 关注每个新版本的废弃方法是非常重要的并尽量避免使用这些方法。 269 | ```javascript 270 | // 糟糕 - live 已经废弃 271 | 272 | $('#stuff').live('click', function() { 273 | console.log('hooray'); 274 | }); 275 | 276 | // 建议 277 | $('#stuff').on('click', function() { 278 | console.log('hooray'); 279 | }); 280 | // 注:此处可能不当,应为live能实现实时绑定,delegate或许更合适 281 | ``` 282 | ### 利用CDN 283 | 284 | 谷歌的CND能保证选择离用户最近的缓存并迅速响应。(使用谷歌CND请自行搜索地址,此处地址以不能使用,推荐jquery官网提供的CDN)。 285 | 286 | ### 必要时组合jQuery和javascript原生代码 287 | 288 | 如上所述,jQuery就是javascript,这意味着用jQuery能做的事情,同样可以用原生代码来做。原生代码(或vanilla)的可读性和可维护性可能不如jQuery,而且代码更长。但也意味着更高效(通常更接近底层代码可读性越差,性能越高,例如:汇编,当然需要更强大的人才可以)。牢记没有任何框架能比原生代码更小,更轻,更高效(注:测试链接已失效,可上网搜索测试代码)。 289 | 290 | 鉴于vanilla 和 jQuery之间的性能差异,我强烈建议吸收两人的精华,使用(可能的话)和jQuery等价的原生代码。 291 | 292 | > via: http://www.codeceo.com/article/jquery-coding-high-qulity.html 293 | 294 | ---- 295 | 296 | ### 简易jQuery输入框模糊查询匹配select 297 | 298 | ```javascript 299 | $("#search").keyup(function(){ 300 | //过滤空 301 | var keyword = $(this).val().toLowerCase().replace(/(^\s*)|(\s*$)/g, ""); 302 | if (keyword) { 303 | //使用正则 304 | var reg = new RegExp(keyword,'i'); 305 | //遍历option 306 | $('option').each(function(key,val){ 307 | //定义要搜索的字符串 308 | var ref = $(this).attr('ref'); 309 | //如果搜到,设置select值 310 | if(ref && reg.test( ref ) ){ 311 | $("select").val($(val).val()); 312 | return false; 313 | } 314 | });//end each 315 | }//end if keyword 316 | }); 317 | ``` 318 | 319 | ---- 320 | 321 | ### 解决iframe自适应高度 322 | 下面的两种方法自选其一就行了。一个是放在和iframe同页面的,一个是放在test.html页面的。 323 | 注意别放错了地方。 324 | iframe的代码中,注意要写ID,没有ID查找不到 325 | 326 | ```html 327 | 328 | ``` 329 | 330 | 方法一: 331 | //注意:下面的代码是放在test.html调用 332 | 333 | ```javascript 334 | $(window.parent.document).find("#main").load(function(){ 335 | var main = $(window.parent.document).find("#main"); 336 | var thisheight = $(document).height()+30; 337 | main.height(thisheight); 338 | }); 339 | ``` 340 | 341 | 方法二: 342 | //注意:下面的代码是放在和iframe同一个页面调用 343 | 344 | ```javascript 345 | $("#main").load(function(){ 346 | var mainheight = $(this).contents().find("body").height()+30; 347 | $(this).height(mainheight); 348 | }); 349 | ``` 350 | 351 | ### jQuery全选/反选功能实例 352 | ```javascript 353 | $("#CheckAll").click(function(){ 354 | $("[name=items]:checkbox").attr("checked", true); 355 | }) 356 | $("#CheckNo").click(function(){ 357 | $("[name=items]:checkbox").attr("checked", false); 358 | }) 359 | $("#CheckRev").click(function(){ 360 | $("[name=items]:checkbox").each(function(){ 361 | //$(this).attr("checked", !$(this).attr("checked")); 362 | this.checked = !this.checked; 363 | }) 364 | }) 365 | $("#send").click(function(){ 366 | var str="你选中的是:\r\n"; 367 | $("[name=items]:checkbox:checked").each(function(){ 368 | str += $(this).val()+"\r\n"; 369 | }) 370 | alert(str); 371 | }) 372 | ``` 373 | 374 | --- 375 | 376 | ### 禁止右键 377 | ```javascript 378 | $(document).ready(function() { 379 | //catch the right-click context menu 380 | $(document).bind("contextmenu",function(e) { 381 | //warning prompt - optional 382 | alert("No right-clicking!"); 383 | 384 | //delete the default context menu 385 | return false; 386 | }); 387 | }); 388 | ``` 389 | 390 | ### 文本缩放 391 | ```javascript 392 | $(document).ready(function() { 393 | //find the current font size 394 | var originalFontSize = $('html').css('font-size'); 395 | 396 | //Increase the text size 397 | $(".increaseFont").click(function() { 398 | var currentFontSize = $('html').css('font-size'); 399 | var currentFontSizeNumber = parseFloat(currentFontSize, 10); 400 | 401 | var newFontSize = currentFontSizeNumber*1.2; 402 | $('html').css('font-size', newFontSize); 403 | return false; 404 | }); 405 | 406 | //Decrease the Text Size 407 | $(".decreaseFont").click(function() { 408 | var currentFontSize = $('html').css('font-size'); 409 | var currentFontSizeNum = parseFloat(currentFontSize, 10); 410 | 411 | var newFontSize = currentFontSizeNum*0.8; 412 | $('html').css('font-size', newFontSize); 413 | return false; 414 | }); 415 | 416 | // Reset Font Size 417 | $(".resetFont").click(function(){ 418 | $('html').css('font-size', originalFontSize); 419 | }); 420 | }); 421 | ``` 422 | 423 | ### 在新窗口打开链接 424 | ```javascript 425 | $(document).ready(function() { 426 | //select all anchor tags that have http in the href 427 | //and apply the target=_blank 428 | $("a[href^='http']").attr('target','_blank'); 429 | }); 430 | ``` 431 | 432 | ### 样式表切换 433 | ```javascript 434 | $(document).ready(function() { 435 | $("a.cssSwap").click(function() { 436 | //swap the link rel attribute with the value in the rel 437 | $('link[rel=stylesheet]').attr('href' , $(this).attr('rel')); 438 | }); 439 | }); 440 | ``` 441 | 442 | ### 回到顶部 443 | ```javascript 444 | $(document).ready(function() { 445 | //when the id="top" link is clicked 446 | $('#top').click(function() { 447 | //scoll the page back to the top 448 | $(document).scrollTo(0,500); 449 | } 450 | }); 451 | ``` 452 | 453 | ### 获取鼠标的 X、Y 坐标 454 | ```javascript 455 | $().mousemove(function(e){ 456 | //display the x and y axis values inside the P element 457 | $('p').html("X Axis : " + e.pageX + " | Y Axis " + e.pageY); 458 | }); 459 | ``` 460 | 461 | ### 检测当前鼠标的坐标 462 | ```javascript 463 | $(document).ready(function() { 464 | $().mousemove(function(e){ 465 | $('# MouseCoordinates ').html("X Axis Position = " + e.pageX + " and Y Axis Position = " + e.pageY); 466 | }); 467 | ``` 468 | 469 | ### 预加载图片 470 | ```javascript 471 | jQuery.preloadImagesInWebPage = function() { 472 | for(var ctr = 0; ctr from:(http://www.cnblogs.com/lhb25/p/useful-jquery-tips-and-tricks.html) 486 | 487 | --- 488 | 489 | 490 | 491 | -------------------------------------------------------------------------------- /markdown/README.md: -------------------------------------------------------------------------------- 1 | Markdown 语法说明 (简体中文版) 2 | ================ 3 | **声明:** 这份文档fork自[这](https://github.com/riku/Markdown-Syntax-CN/blob/master/syntax.md) 4 | 5 |

概述

6 | 7 |

宗旨

8 | 9 | Markdown 的目标是实现「易读易写」。 10 | 11 | 可读性,无论如何,都是最重要的。一份使用 Markdown 格式撰写的文件应该可以直接以纯文本发布,并且看起来不会像是由许多标签或是格式指令所构成。Markdown 语法受到一些既有 text-to-HTML 格式的影响,包括 [Setext] [1]、[atx] [2]、[Textile] [3]、[reStructuredText] [4]、[Grutatext] [5] 和 [EtText] [6],而最大灵感来源其实是纯文本电子邮件的格式。 12 | 13 | [1]: http://docutils.sourceforge.net/mirror/setext.html 14 | [2]: http://www.aaronsw.com/2002/atx/ 15 | [3]: http://textism.com/tools/textile/ 16 | [4]: http://docutils.sourceforge.net/rst.html 17 | [5]: http://www.triptico.com/software/grutatxt.html 18 | [6]: http://ettext.taint.org/doc/ 19 | 20 | 总之, Markdown 的语法全由一些符号所组成,这些符号经过精挑细选,其作用一目了然。比如:在文字两旁加上星号,看起来就像\*强调\*。Markdown 的列表看起来,嗯,就是列表。Markdown 的区块引用看起来就真的像是引用一段文字,就像你曾在电子邮件中见过的那样。 21 | 22 |

兼容 HTML

23 | 24 | Markdown 语法的目标是:成为一种适用于网络的*书写*语言。 25 | 26 | Markdown 不是想要取代 HTML,甚至也没有要和它相近,它的语法种类很少,只对应 HTML 标记的一小部分。Markdown 的构想*不是*要使得 HTML 文档更容易书写。在我看来, HTML 已经很容易写了。Markdown 的理念是,能让文档更容易读、写和随意改。HTML 是一种*发布*的格式,Markdown 是一种*书写*的格式。就这样,Markdown 的格式语法只涵盖纯文本可以涵盖的范围。 27 | 28 | 不在 Markdown 涵盖范围之内的标签,都可以直接在文档里面用 HTML 撰写。不需要额外标注这是 HTML 或是 Markdown;只要直接加标签就可以了。 29 | 30 | 要制约的只有一些 HTML 区块元素――比如 `
`、``、`
`、`

` 等标签,必须在前后加上空行与其它内容区隔开,还要求它们的开始标签与结尾标签不能用制表符或空格来缩进。Markdown 的生成器有足够智能,不会在 HTML 区块标签外加上不必要的 `

` 标签。 31 | 32 | 例子如下,在 Markdown 文件里加上一段 HTML 表格: 33 | 34 | 这是一个普通段落。 35 | 36 |

37 | 38 | 39 | 40 |
Foo
41 | 42 | 这是另一个普通段落。 43 | 44 | 请注意,在 HTML 区块标签间的 Markdown 格式语法将不会被处理。比如,你在 HTML 区块内使用 Markdown 样式的`*强调*`会没有效果。 45 | 46 | HTML 的区段(行内)标签如 ``、``、`` 可以在 Markdown 的段落、列表或是标题里随意使用。依照个人习惯,甚至可以不用 Markdown 格式,而直接采用 HTML 标签来格式化。举例说明:如果比较喜欢 HTML 的 `` 或 `` 标签,可以直接使用这些标签,而不用 Markdown 提供的链接或是图像标签语法。 47 | 48 | 和处在 HTML 区块标签间不同,Markdown 语法在 HTML 区段标签间是有效的。 49 | 50 |

特殊字符自动转换

51 | 52 | 在 HTML 文件中,有两个字符需要特殊处理: `<` 和 `&` 。 `<` 符号用于起始标签,`&` 符号则用于标记 HTML 实体,如果你只是想要显示这些字符的原型,你必须要使用实体的形式,像是 `<` 和 `&`。 53 | 54 | `&` 字符尤其让网络文档编写者受折磨,如果你要打「`AT&T`」 ,你必须要写成「`AT&T`」。而网址中的 `&` 字符也要转换。比如你要链接到: 55 | 56 | http://images.google.com/images?num=30&q=larry+bird 57 | 58 | 你必须要把网址转换写为: 59 | 60 | http://images.google.com/images?num=30&q=larry+bird 61 | 62 | 才能放到链接标签的 `href` 属性里。不用说也知道这很容易忽略,这也可能是 HTML 标准检验所检查到的错误中,数量最多的。 63 | 64 | Markdown 让你可以自然地书写字符,需要转换的由它来处理好了。如果你使用的 `&` 字符是 HTML 字符实体的一部分,它会保留原状,否则它会被转换成 `&`;。 65 | 66 | 所以你如果要在文档中插入一个版权符号 `©`,你可以这样写: 67 | 68 | © 69 | 70 | Markdown 会保留它不动。而若你写: 71 | 72 | AT&T 73 | 74 | Markdown 就会将它转为: 75 | 76 | AT&T 77 | 78 | 类似的状况也会发生在 `<` 符号上,因为 Markdown 允许 兼容 HTML ,如果你是把 `<` 符号作为 HTML 标签的定界符使用,那 Markdown 也不会对它做任何转换,但是如果你写: 79 | 80 | 4 < 5 81 | 82 | Markdown 将会把它转换为: 83 | 84 | 4 < 5 85 | 86 | 不过需要注意的是,code 范围内,不论是行内还是区块, `<` 和 `&` 两个符号都*一定*会被转换成 HTML 实体,这项特性让你可以很容易地用 Markdown 写 HTML code (和 HTML 相对而言, HTML 语法中,你要把所有的 `<` 和 `&` 都转换为 HTML 实体,才能在 HTML 文件里面写出 HTML code。) 87 | 88 | * * * 89 | 90 |

区块元素

91 | 92 | 93 |

段落和换行

94 | 95 | 一个 Markdown 段落是由一个或多个连续的文本行组成,它的前后要有一个以上的空行(空行的定义是显示上看起来像是空的,便会被视为空行。比方说,若某一行只包含空格和制表符,则该行也会被视为空行)。普通段落不该用空格或制表符来缩进。 96 | 97 | 「由一个或多个连续的文本行组成」这句话其实暗示了 Markdown 允许段落内的强迫换行(插入换行符),这个特性和其他大部分的 text-to-HTML 格式不一样(包括 Movable Type 的「Convert Line Breaks」选项),其它的格式会把每个换行符都转成 `
` 标签。 98 | 99 | 如果你*确实*想要依赖 Markdown 来插入 `
` 标签的话,在插入处先按入两个以上的空格然后回车。 100 | 101 | 的确,需要多费点事(多加空格)来产生 `
` ,但是简单地「每个换行都转换为 `
`」的方法在 Markdown 中并不适合, Markdown 中 email 式的 [区块引用][bq] 和多段落的 [列表][l] 在使用换行来排版的时候,不但更好用,还更方便阅读。 102 | 103 | [bq]: #blockquote 104 | [l]: #list 105 | 106 | 107 | 108 | Markdown 支持两种标题的语法,类 [Setext] [1] 和类 [atx] [2] 形式。 109 | 110 | 类 Setext 形式是用底线的形式,利用 `=` (最高阶标题)和 `-` (第二阶标题),例如: 111 | 112 | This is an H1 113 | ============= 114 | 115 | This is an H2 116 | ------------- 117 | 118 | 任何数量的 `=` 和 `-` 都可以有效果。 119 | 120 | 类 Atx 形式则是在行首插入 1 到 6 个 `#` ,对应到标题 1 到 6 阶,例如: 121 | 122 | # 这是 H1 123 | 124 | ## 这是 H2 125 | 126 | ###### 这是 H6 127 | 128 | 你可以选择性地「闭合」类 atx 样式的标题,这纯粹只是美观用的,若是觉得这样看起来比较舒适,你就可以在行尾加上 `#`,而行尾的 `#` 数量也不用和开头一样(行首的井字符数量决定标题的阶数): 129 | 130 | # 这是 H1 # 131 | 132 | ## 这是 H2 ## 133 | 134 | ### 这是 H3 ###### 135 | 136 | 137 |

区块引用 Blockquotes

138 | 139 | Markdown 标记区块引用是使用类似 email 中用 `>` 的引用方式。如果你还熟悉在 email 信件中的引言部分,你就知道怎么在 Markdown 文件中建立一个区块引用,那会看起来像是你自己先断好行,然后在每行的最前面加上 `>` : 140 | 141 | > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, 142 | > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. 143 | > Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. 144 | > 145 | > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse 146 | > id sem consectetuer libero luctus adipiscing. 147 | 148 | Markdown 也允许你偷懒只在整个段落的第一行最前面加上 `>` : 149 | 150 | > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, 151 | consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. 152 | Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. 153 | 154 | > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse 155 | id sem consectetuer libero luctus adipiscing. 156 | 157 | 区块引用可以嵌套(例如:引用内的引用),只要根据层次加上不同数量的 `>` : 158 | 159 | > This is the first level of quoting. 160 | > 161 | > > This is nested blockquote. 162 | > 163 | > Back to the first level. 164 | 165 | 引用的区块内也可以使用其他的 Markdown 语法,包括标题、列表、代码区块等: 166 | 167 | > ## 这是一个标题。 168 | > 169 | > 1. 这是第一行列表项。 170 | > 2. 这是第二行列表项。 171 | > 172 | > 给出一些例子代码: 173 | > 174 | > return shell_exec("echo $input | $markdown_script"); 175 | 176 | 任何像样的文本编辑器都能轻松地建立 email 型的引用。例如在 BBEdit 中,你可以选取文字后然后从选单中选择*增加引用阶层*。 177 | 178 |

列表

179 | 180 | Markdown 支持有序列表和无序列表。 181 | 182 | 无序列表使用星号、加号或是减号作为列表标记: 183 | 184 | * Red 185 | * Green 186 | * Blue 187 | 188 | 等同于: 189 | 190 | + Red 191 | + Green 192 | + Blue 193 | 194 | 也等同于: 195 | 196 | - Red 197 | - Green 198 | - Blue 199 | 200 | 有序列表则使用数字接着一个英文句点: 201 | 202 | 1. Bird 203 | 2. McHale 204 | 3. Parish 205 | 206 | 很重要的一点是,你在列表标记上使用的数字并不会影响输出的 HTML 结果,上面的列表所产生的 HTML 标记为: 207 | 208 |
    209 |
  1. Bird
  2. 210 |
  3. McHale
  4. 211 |
  5. Parish
  6. 212 |
213 | 214 | 如果你的列表标记写成: 215 | 216 | 1. Bird 217 | 1. McHale 218 | 1. Parish 219 | 220 | 或甚至是: 221 | 222 | 3. Bird 223 | 1. McHale 224 | 8. Parish 225 | 226 | 你都会得到完全相同的 HTML 输出。重点在于,你可以让 Markdown 文件的列表数字和输出的结果相同,或是你懒一点,你可以完全不用在意数字的正确性。 227 | 228 | 如果你使用懒惰的写法,建议第一个项目最好还是从 1. 开始,因为 Markdown 未来可能会支持有序列表的 start 属性。 229 | 230 | 列表项目标记通常是放在最左边,但是其实也可以缩进,最多 3 个空格,项目标记后面则一定要接着至少一个空格或制表符。 231 | 232 | 要让列表看起来更漂亮,你可以把内容用固定的缩进整理好: 233 | 234 | * Lorem ipsum dolor sit amet, consectetuer adipiscing elit. 235 | Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, 236 | viverra nec, fringilla in, laoreet vitae, risus. 237 | * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. 238 | Suspendisse id sem consectetuer libero luctus adipiscing. 239 | 240 | 但是如果你懒,那也行: 241 | 242 | * Lorem ipsum dolor sit amet, consectetuer adipiscing elit. 243 | Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, 244 | viverra nec, fringilla in, laoreet vitae, risus. 245 | * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. 246 | Suspendisse id sem consectetuer libero luctus adipiscing. 247 | 248 | 如果列表项目间用空行分开,在输出 HTML 时 Markdown 就会将项目内容用 `

` 249 | 标签包起来,举例来说: 250 | 251 | * Bird 252 | * Magic 253 | 254 | 会被转换为: 255 | 256 |

    257 |
  • Bird
  • 258 |
  • Magic
  • 259 |
260 | 261 | 但是这个: 262 | 263 | * Bird 264 | 265 | * Magic 266 | 267 | 会被转换为: 268 | 269 |
    270 |
  • Bird

  • 271 |
  • Magic

  • 272 |
273 | 274 | 列表项目可以包含多个段落,每个项目下的段落都必须缩进 4 个空格或是 1 个制表符: 275 | 276 | 1. This is a list item with two paragraphs. Lorem ipsum dolor 277 | sit amet, consectetuer adipiscing elit. Aliquam hendrerit 278 | mi posuere lectus. 279 | 280 | Vestibulum enim wisi, viverra nec, fringilla in, laoreet 281 | vitae, risus. Donec sit amet nisl. Aliquam semper ipsum 282 | sit amet velit. 283 | 284 | 2. Suspendisse id sem consectetuer libero luctus adipiscing. 285 | 286 | 如果你每行都有缩进,看起来会看好很多,当然,再次地,如果你很懒惰,Markdown 也允许: 287 | 288 | * This is a list item with two paragraphs. 289 | 290 | This is the second paragraph in the list item. You're 291 | only required to indent the first line. Lorem ipsum dolor 292 | sit amet, consectetuer adipiscing elit. 293 | 294 | * Another item in the same list. 295 | 296 | 如果要在列表项目内放进引用,那 `>` 就需要缩进: 297 | 298 | * A list item with a blockquote: 299 | 300 | > This is a blockquote 301 | > inside a list item. 302 | 303 | 如果要放代码区块的话,该区块就需要缩进*两次*,也就是 8 个空格或是 2 个制表符: 304 | 305 | * 一列表项包含一个列表区块: 306 | 307 | <代码写在这> 308 | 309 | 310 | 当然,项目列表很可能会不小心产生,像是下面这样的写法: 311 | 312 | 1986. What a great season. 313 | 314 | 换句话说,也就是在行首出现*数字-句点-空白*,要避免这样的状况,你可以在句点前面加上反斜杠。 315 | 316 | 1986\. What a great season. 317 | 318 |

代码区块

319 | 320 | 和程序相关的写作或是标签语言原始码通常会有已经排版好的代码区块,通常这些区块我们并不希望它以一般段落文件的方式去排版,而是照原来的样子显示,Markdown 会用 `
` 和 `` 标签来把代码区块包起来。
321 | 
322 | 要在 Markdown 中建立代码区块很简单,只要简单地缩进 4 个空格或是 1 个制表符就可以,例如,下面的输入:
323 | 
324 |     这是一个普通段落:
325 | 
326 |         这是一个代码区块。
327 | 
328 | Markdown 会转换成:
329 | 
330 |     

这是一个普通段落:

331 | 332 |
这是一个代码区块。
333 |     
334 | 335 | 这个每行一阶的缩进(4 个空格或是 1 个制表符),都会被移除,例如: 336 | 337 | Here is an example of AppleScript: 338 | 339 | tell application "Foo" 340 | beep 341 | end tell 342 | 343 | 会被转换为: 344 | 345 |

Here is an example of AppleScript:

346 | 347 |
tell application "Foo"
348 |         beep
349 |     end tell
350 |     
351 | 352 | 一个代码区块会一直持续到没有缩进的那一行(或是文件结尾)。 353 | 354 | 在代码区块里面, `&` 、 `<` 和 `>` 会自动转成 HTML 实体,这样的方式让你非常容易使用 Markdown 插入范例用的 HTML 原始码,只需要复制贴上,再加上缩进就可以了,剩下的 Markdown 都会帮你处理,例如: 355 | 356 | 359 | 360 | 会被转换为: 361 | 362 |
<div class="footer">
363 |         &copy; 2004 Foo Corporation
364 |     </div>
365 |     
366 | 367 | 代码区块中,一般的 Markdown 语法不会被转换,像是星号便只是星号,这表示你可以很容易地以 Markdown 语法撰写 Markdown 语法相关的文件。 368 | 369 |

分隔线

370 | 371 | 你可以在一行中用三个以上的星号、减号、底线来建立一个分隔线,行内不能有其他东西。你也可以在星号或是减号中间插入空格。下面每种写法都可以建立分隔线: 372 | 373 | * * * 374 | 375 | *** 376 | 377 | ***** 378 | 379 | - - - 380 | 381 | --------------------------------------- 382 | 383 | 384 | * * * 385 | 386 |

区段元素

387 | 388 | 389 | 390 | Markdown 支持两种形式的链接语法: *行内式*和*参考式*两种形式。 391 | 392 | 不管是哪一种,链接文字都是用 [方括号] 来标记。 393 | 394 | 要建立一个*行内式*的链接,只要在方块括号后面紧接着圆括号并插入网址链接即可,如果你还想要加上链接的 title 文字,只要在网址后面,用双引号把 title 文字包起来即可,例如: 395 | 396 | This is [an example](http://example.com/ "Title") inline link. 397 | 398 | [This link](http://example.net/) has no title attribute. 399 | 400 | 会产生: 401 | 402 |

This is 403 | an example inline link.

404 | 405 |

This link has no 406 | title attribute.

407 | 408 | 如果你是要链接到同样主机的资源,你可以使用相对路径: 409 | 410 | See my [About](/about/) page for details. 411 | 412 | *参考式*的链接是在链接文字的括号后面再接上另一个方括号,而在第二个方括号里面要填入用以辨识链接的标记: 413 | 414 | This is [an example][id] reference-style link. 415 | 416 | 你也可以选择性地在两个方括号中间加上一个空格: 417 | 418 | This is [an example] [id] reference-style link. 419 | 420 | 接着,在文件的任意处,你可以把这个标记的链接内容定义出来: 421 | 422 | [id]: http://example.com/ "Optional Title Here" 423 | 424 | 链接内容定义的形式为: 425 | 426 | * 方括号(前面可以选择性地加上至多三个空格来缩进),里面输入链接文字 427 | * 接着一个冒号 428 | * 接着一个以上的空格或制表符 429 | * 接着链接的网址 430 | * 选择性地接着 title 内容,可以用单引号、双引号或是括弧包着 431 | 432 | 下面这三种链接的定义都是相同: 433 | 434 | [foo]: http://example.com/ "Optional Title Here" 435 | [foo]: http://example.com/ 'Optional Title Here' 436 | [foo]: http://example.com/ (Optional Title Here) 437 | 438 | **请注意:**有一个已知的问题是 Markdown.pl 1.0.1 会忽略单引号包起来的链接 title。 439 | 440 | 链接网址也可以用方括号包起来: 441 | 442 | [id]: "Optional Title Here" 443 | 444 | 你也可以把 title 属性放到下一行,也可以加一些缩进,若网址太长的话,这样会比较好看: 445 | 446 | [id]: http://example.com/longish/path/to/resource/here 447 | "Optional Title Here" 448 | 449 | 网址定义只有在产生链接的时候用到,并不会直接出现在文件之中。 450 | 451 | 链接辨别标签可以有字母、数字、空白和标点符号,但是并*不*区分大小写,因此下面两个链接是一样的: 452 | 453 | [link text][a] 454 | [link text][A] 455 | 456 | *隐式链接标记*功能让你可以省略指定链接标记,这种情形下,链接标记会视为等同于链接文字,要用隐式链接标记只要在链接文字后面加上一个空的方括号,如果你要让 "Google" 链接到 google.com,你可以简化成: 457 | 458 | [Google][] 459 | 460 | 然后定义链接内容: 461 | 462 | [Google]: http://google.com/ 463 | 464 | 由于链接文字可能包含空白,所以这种简化型的标记内也许包含多个单词: 465 | 466 | Visit [Daring Fireball][] for more information. 467 | 468 | 然后接着定义链接: 469 | 470 | [Daring Fireball]: http://daringfireball.net/ 471 | 472 | 链接的定义可以放在文件中的任何一个地方,我比较偏好直接放在链接出现段落的后面,你也可以把它放在文件最后面,就像是注解一样。 473 | 474 | 下面是一个参考式链接的范例: 475 | 476 | I get 10 times more traffic from [Google] [1] than from 477 | [Yahoo] [2] or [MSN] [3]. 478 | 479 | [1]: http://google.com/ "Google" 480 | [2]: http://search.yahoo.com/ "Yahoo Search" 481 | [3]: http://search.msn.com/ "MSN Search" 482 | 483 | 如果改成用链接名称的方式写: 484 | 485 | I get 10 times more traffic from [Google][] than from 486 | [Yahoo][] or [MSN][]. 487 | 488 | [google]: http://google.com/ "Google" 489 | [yahoo]: http://search.yahoo.com/ "Yahoo Search" 490 | [msn]: http://search.msn.com/ "MSN Search" 491 | 492 | 上面两种写法都会产生下面的 HTML。 493 | 494 |

I get 10 times more traffic from Google than from 496 | Yahoo 497 | or MSN.

498 | 499 | 下面是用行内式写的同样一段内容的 Markdown 文件,提供作为比较之用: 500 | 501 | I get 10 times more traffic from [Google](http://google.com/ "Google") 502 | than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or 503 | [MSN](http://search.msn.com/ "MSN Search"). 504 | 505 | 参考式的链接其实重点不在于它比较好写,而是它比较好读,比较一下上面的范例,使用参考式的文章本身只有 81 个字符,但是用行内形式的却会增加到 176 个字元,如果是用纯 HTML 格式来写,会有 234 个字元,在 HTML 格式中,标签比文本还要多。 506 | 507 | 使用 Markdown 的参考式链接,可以让文件更像是浏览器最后产生的结果,让你可以把一些标记相关的元数据移到段落文字之外,你就可以增加链接而不让文章的阅读感觉被打断。 508 | 509 |

强调

510 | 511 | Markdown 使用星号(`*`)和底线(`_`)作为标记强调字词的符号,被 `*` 或 `_` 包围的字词会被转成用 `` 标签包围,用两个 `*` 或 `_` 包起来的话,则会被转成 ``,例如: 512 | 513 | *single asterisks* 514 | 515 | _single underscores_ 516 | 517 | **double asterisks** 518 | 519 | __double underscores__ 520 | 521 | 会转成: 522 | 523 | single asterisks 524 | 525 | single underscores 526 | 527 | double asterisks 528 | 529 | double underscores 530 | 531 | 你可以随便用你喜欢的样式,唯一的限制是,你用什么符号开启标签,就要用什么符号结束。 532 | 533 | 强调也可以直接插在文字中间: 534 | 535 | un*frigging*believable 536 | 537 | 但是**如果你的 `*` 和 `_` 两边都有空白的话,它们就只会被当成普通的符号**。 538 | 539 | 如果要在文字前后直接插入普通的星号或底线,你可以用反斜线: 540 | 541 | \*this text is surrounded by literal asterisks\* 542 | 543 |

代码

544 | 545 | 如果要标记一小段行内代码,你可以用反引号把它包起来(`` ` ``),例如: 546 | 547 | Use the `printf()` function. 548 | 549 | 会产生: 550 | 551 |

Use the printf() function.

552 | 553 | 如果要在代码区段内插入反引号,你可以用多个反引号来开启和结束代码区段: 554 | 555 | ``There is a literal backtick (`) here.`` 556 | 557 | 这段语法会产生: 558 | 559 |

There is a literal backtick (`) here.

560 | 561 | 代码区段的起始和结束端都可以放入一个空白,起始端后面一个,结束端前面一个,这样你就可以在区段的一开始就插入反引号: 562 | 563 | A single backtick in a code span: `` ` `` 564 | 565 | A backtick-delimited string in a code span: `` `foo` `` 566 | 567 | 会产生: 568 | 569 |

A single backtick in a code span: `

570 | 571 |

A backtick-delimited string in a code span: `foo`

572 | 573 | 在代码区段内,`&` 和方括号**都**会被自动地转成 HTML 实体,这使得插入 HTML 原始码变得很容易,Markdown 会把下面这段: 574 | 575 | Please don't use any `` tags. 576 | 577 | 转为: 578 | 579 |

Please don't use any <blink> tags.

580 | 581 | 你也可以这样写: 582 | 583 | `—` is the decimal-encoded equivalent of `—`. 584 | 585 | 以产生: 586 | 587 |

&#8212; is the decimal-encoded 588 | equivalent of &mdash;.

589 | 590 | 591 | 592 |

图片

593 | 594 | 很明显地,要在纯文字应用中设计一个「自然」的语法来插入图片是有一定难度的。 595 | 596 | Markdown 使用一种和链接很相似的语法来标记图片,同样也允许两种样式: *行内式*和*参考式*。 597 | 598 | 行内式的图片语法看起来像是: 599 | 600 | ![Alt text](/path/to/img.jpg) 601 | 602 | ![Alt text](/path/to/img.jpg "Optional title") 603 | 604 | 详细叙述如下: 605 | 606 | * 一个惊叹号 `!` 607 | * 接着一个方括号,里面放上图片的替代文字 608 | * 接着一个普通括号,里面放上图片的网址,最后还可以用引号包住并加上 609 | 选择性的 'title' 文字。 610 | 611 | 参考式的图片语法则长得像这样: 612 | 613 | ![Alt text][id] 614 | 615 | 「id」是图片参考的名称,图片参考的定义方式则和连结参考一样: 616 | 617 | [id]: url/to/image "Optional title attribute" 618 | 619 | 到目前为止, Markdown 还没有办法指定图片的宽高,如果你需要的话,你可以使用普通的 `` 标签。 620 | 621 | * * * 622 | 623 |

其它

624 | 625 | 626 | 627 | Markdown 支持以比较简短的自动链接形式来处理网址和电子邮件信箱,只要是用方括号包起来, Markdown 就会自动把它转成链接。一般网址的链接文字就和链接地址一样,例如: 628 | 629 | 630 | 631 | Markdown 会转为: 632 | 633 | http://example.com/ 634 | 635 | 邮址的自动链接也很类似,只是 Markdown 会先做一个编码转换的过程,把文字字符转成 16 进位码的 HTML 实体,这样的格式可以糊弄一些不好的邮址收集机器人,例如: 636 | 637 | 638 | 639 | Markdown 会转成: 640 | 641 | address@exa 644 | mple.com 645 | 646 | 在浏览器里面,这段字串(其实是 `address@example.com`)会变成一个可以点击的「address@example.com」链接。 647 | 648 | (这种作法虽然可以糊弄不少的机器人,但并不能全部挡下来,不过总比什么都不做好些。不管怎样,公开你的信箱终究会引来广告信件的。) 649 | 650 |

反斜杠

651 | 652 | Markdown 可以利用反斜杠来插入一些在语法中有其它意义的符号,例如:如果你想要用星号加在文字旁边的方式来做出强调效果(但不用 `` 标签),你可以在星号的前面加上反斜杠: 653 | 654 | \*literal asterisks\* 655 | 656 | Markdown 支持以下这些符号前面加上反斜杠来帮助插入普通的符号: 657 | 658 | \ 反斜线 659 | ` 反引号 660 | * 星号 661 | _ 底线 662 | {} 花括号 663 | [] 方括号 664 | () 括弧 665 | # 井字号 666 | + 加号 667 | - 减号 668 | . 英文句点 669 | ! 惊叹号 670 | 671 |

感谢

672 | 673 | 感谢 [leafy7382][] 协助翻译,[hlb][]、[Randylien][] 帮忙润稿,[ethantw][] 的[汉字标准格式・CSS Reset][], [WM][] 回报文字错误。 674 | 675 | [leafy7382]:https://twitter.com/#!/leafy7382 676 | [hlb]:http://iamhlb.com/ 677 | [Randylien]:http://twitter.com/randylien 678 | [ethantw]:https://twitter.com/#!/ethantw 679 | [汉字标准格式・CSS Reset]:http://ethantw.net/projects/han/ 680 | [WM]:http://kidwm.net/ 681 | 682 | 感谢 [fenprace][],[addv][]。 683 | 684 | [fenprace]:https://github.com/fenprace 685 | [addv]:https://github.com/addv 686 | 687 | ---------- 688 |

Markdown 免费编辑器

689 | 690 | Windows 平台 691 | 692 | * [MarkdownPad](http://markdownpad.com/) 693 | * [MarkPad](http://code52.org/DownmarkerWPF/) 694 | 695 | Linux 平台 696 | 697 | * [ReText](http://sourceforge.net/p/retext/home/ReText/) 698 | 699 | Mac 平台 700 | 701 | * [Mou](http://mouapp.com/) 702 | 703 | 在线编辑器 704 | 705 | * [Markable.in](http://markable.in/) 706 | * [Dillinger.io](http://dillinger.io/) 707 | 708 | 浏览器插件 709 | 710 | * [MaDe](https://chrome.google.com/webstore/detail/oknndfeeopgpibecfjljjfanledpbkog) (Chrome) 711 | 712 | 高级应用 713 | 714 | * [Sublime Text 2](http://www.sublimetext.com/2) + [MarkdownEditing](http://ttscoff.github.com/MarkdownEditing/) / [教程](http://lucifr.com/2012/07/12/markdownediting-for-sublime-text-2/) 715 | 716 | \*** 如有更好的 Markdown 免费编辑器推荐,请到[这里反馈](https://gitcafe.com/riku/Markdown-Syntax-CN/tickets/1),谢谢! 717 | -------------------------------------------------------------------------------- /mysql/README.md: -------------------------------------------------------------------------------- 1 | 2 | ### mysql核心军规小结 3 | * 尽量不在数据库做运算 4 | * 控制单表数据量 5 | * 保持表身段苗条 6 | * 平衡范式不冗余 7 | * 拒绝3B(大SQL/大事务/大批量) 8 | 9 | ### 字段类军规小结 10 | * 用好数值字段类型 11 | * 将字符转化为数字 12 | * 优先使用枚丼ENUM/SET 13 | * 避免使用NULL字段 14 | * 少用幵拆分TEXT/BLOB 15 | * 不在数据库里存图片 16 | 17 | ### 索引类军规小结 18 | * 谨慎合理添加索引 19 | * 字符字段必须建前缀索引 20 | * 不在索引列做运算 21 | * 自增列或全局ID做INNODB主键 22 | * 尽量不用外键 23 | 24 | ### SQL类军规小结 25 | * SQL语句尽可能简单 26 | * 保持事务(连接)短小 27 | * 尽可能避免使用SP/TRIG/FUNC 28 | * 尽量不用 SELECT * 29 | * 改写OR语句 30 | * 避免负向查询和% 前缀模糊查询 31 | * 减少COUNT(*) 32 | * LIMIT的高效分页 33 | * 用UNION ALL 而非 UNION 34 | * 分解联接保证高幵发 35 | * GROUP BY 去除排序 36 | * 同数据类型的列值比较 37 | * Load data导数据 38 | * 打散大批量更新 39 | * Know Every SQL! 40 | 41 | ### 约定类军规小结 42 | * 隔离线上线下 43 | * 禁止未经DBA确认的子查询上线 44 | * 永远不在程序端显式加锁 45 | * 统一字符集为UTF8 46 | * 统一命名规范 47 | 48 | > 作者:石展@赶集 http://weibo.com/wushizhan 49 | -------------------------------------------------------------------------------- /mysql/batch-update.md: -------------------------------------------------------------------------------- 1 | ### 一条sql语句实现批量更新 2 | 3 | ```mysql 4 | UPDATE categories 5 | SET display_order = CASE id 6 | WHEN 1 THEN 3 7 | WHEN 2 THEN 4 8 | WHEN 3 THEN 5 9 | END 10 | WHERE id IN (1,2,3) 11 | ``` 12 | 这句sql的意思是,更新display_order 字段,如果id=1 则display_order 的值为3,如果id=2 则 display_order 的值为4,如果id=3 则 display_order 的值为5。 13 | 如果更新多个值的话,只需要稍加修改: 14 | 15 | ```mysql 16 | UPDATE categories 17 | SET display_order = CASE id 18 | WHEN 1 THEN 3 19 | WHEN 2 THEN 4 20 | WHEN 3 THEN 5 21 | END, 22 | title = CASE id 23 | WHEN 1 THEN 'New Title 1' 24 | WHEN 2 THEN 'New Title 2' 25 | WHEN 3 THEN 'New Title 3' 26 | END 27 | WHERE id IN (1,2,3) 28 | ``` 29 | 但是要在业务中运用,需要结合服务端语言,这里以php为例,构造这条mysql语句: 30 | 31 | ```mysql 32 | $display_order = array( 33 | 1 => 4, 34 | 2 => 1, 35 | 3 => 2, 36 | 4 => 3, 37 | 5 => 9, 38 | 6 => 5, 39 | 7 => 8, 40 | 8 => 9 41 | ); 42 | $ids = implode(',', array_keys($display_order)); 43 | $sql = "UPDATE categories SET display_order = CASE id "; 44 | foreach ($display_order as $id => $ordinal) { 45 | $sql .= sprintf("WHEN %d THEN %d ", $id, $ordinal); 46 | } 47 | $sql .= "END WHERE id IN ($ids)"; 48 | echo $sql; 49 | ``` 50 | 这个例子,有8条记录进行更新 51 | 52 | ### 性能分析 53 | 当我使用上万条记录利用mysql批量更新,发现使用最原始的批量update发现性能很差,将网上看到的总结一下一共有以下三种办法: 54 | 55 | * 批量update,一条记录update一次,性能很差 56 | 57 | ```mysql 58 | update test_tbl set dr='2' where id=1; 59 | ``` 60 | * replace into 或者insert into ...on duplicate key update 61 | 62 | ```mysql 63 | replace into test_tbl (id,dr) values (1,'2'),(2,'3'),...(x,'y'); 64 | 或者使用 65 | insert into test_tbl (id,dr) values (1,'2'),(2,'3'),...(x,'y') on duplicate key update dr=values(dr); 66 | ``` 67 | * 创建临时表,先更新临时表,然后从临时表中update 68 | 69 | ```mysql 70 | create temporary table tmp(id int(4) primary key,dr varchar(50)); 71 | insert into tmp values (0,'gone'), (1,'xx'),...(m,'yy'); 72 | update test_tbl, tmp set test_tbl.dr=tmp.dr where test_tbl.id=tmp.id; 73 | ``` 74 | 注意:这种方法需要用户有temporary 表的create 权限。 75 | 76 | ---- 77 | 78 | -------------------------------------------------------------------------------- /mysql/error-code.md: -------------------------------------------------------------------------------- 1 | ### 错误码列表 2 | 3 | ``` 4 | 1005:创建表失败 5 | 1006:创建数据库失败 6 | 1007:数据库已存在,创建数据库失败 7 | 1008:数据库不存在,删除数据库失败 8 | 1009:不能删除数据库文件导致删除数据库失败 9 | 1010:不能删除数据目录导致删除数据库失败 10 | 1011:删除数据库文件失败 11 | 1012:不能读取系统表中的记录 12 | 1020:记录已被其他用户修改 13 | 1021:硬盘剩余空间不足,请加大硬盘可用空间 14 | 1022:关键字重复,更改记录失败 15 | 1023:关闭时发生错误 16 | 1024:读文件错误 17 | 1025:更改名字时发生错误 18 | 1026:写文件错误 19 | 1032:记录不存在 20 | 1036:数据表是只读的,不能对它进行修改 21 | 1037:系统内存不足,请重启数据库或重启服务器 22 | 1038:用于排序的内存不足,请增大排序缓冲区 23 | 1040:已到达数据库的最大连接数,请加大数据库可用连接数 24 | 1041:系统内存不足 25 | 1042:无效的主机名 26 | 1043:无效连接 27 | 1044:当前用户没有访问数据库的权限 28 | 1045:不能连接数据库,用户名或密码错误 29 | 1048:字段不能为空 30 | 1049:数据库不存在 31 | 1050:数据表已存在 32 | 1051:数据表不存在 33 | 1054:字段不存在 34 | 1062:字段值重复,入库失败 35 | 1065:无效的SQL语句,SQL语句为空 36 | 1081:不能建立Socket连接 37 | 1114:数据表已满,不能容纳任何记录 38 | 1116:打开的数据表太多 39 | 1129:数据库出现异常,请重启数据库 40 | 1130:连接数据库失败,没有连接数据库的权限 41 | 1133:数据库用户不存在 42 | 1141:当前用户无权访问数据库 43 | 1142:当前用户无权访问数据表 44 | 1143:当前用户无权访问数据表中的字段 45 | 1146:数据表不存在 46 | 1147:未定义用户对数据表的访问权限 47 | 1149:SQL语句语法错误 48 | 1158:网络错误,出现读错误,请检查网络连接状况 49 | 1159:网络错误,读超时,请检查网络连接状况 50 | 1160:网络错误,出现写错误,请检查网络连接状况 51 | 1161:网络错误,写超时,请检查网络连接状况 52 | 1169:字段值重复,更新记录失败 53 | 1177:打开数据表失败 54 | 1180:提交事务失败 55 | 1181:回滚事务失败 56 | 1203:当前用户和数据库建立的连接已到达数据库的最大连接数,请增大可用的数据库连接数或重启数据库 57 | 1205:加锁超时 58 | 1211:当前用户没有创建用户的权限 59 | 1216:外键约束检查失败,更新子表记录失败 60 | 1217:外键约束检查失败,删除或修改主表记录失败 61 | 1226:当前用户使用的资源已超过所允许的资源,请重启数据库或重启服务器 62 | 1227:权限不足,您无权进行此操作 63 | 1235:MySQL版本过低,不具有本功能 64 | ``` 65 | -------------------------------------------------------------------------------- /mysql/explain.md: -------------------------------------------------------------------------------- 1 | ```mysql 2 | EXPLAIN SELECT `surname`,`first_name` FORM `a`,`b` WHERE `a`.`id`=`b`.`id` 3 | ``` 4 | 5 | #### EXPLAIN列的解释: 6 | | 列 | 描述 | 7 | | :-------- | :----- | 8 | | table | 显示这一行的数据是关于哪张表的。 | 9 | | type | 这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为 const、eq_reg、ref、range、index和ALL。 | 10 | | possible_keys | 显示可能应用在这张表中的索引。如果为空,没有可能的索引。可以为相关的域从WHERE语句中选择一个合适的语句。 | 11 | | key | 实际使用的索引。如果为NULL,则没有使用索引。很少的情况下,MySQL会选择优化不足的索引。这种情况下,可以在SELECT语句中使用USE INDEX(indexname) 来强制使用一个索引或者用IGNORE INDEX(indexname)来强制MySQL忽略索引。 | 12 | | key_len | 使用的索引的长度。在不损失精确性的情况下,长度越短越好。 | 13 | | ref | 显示索引的哪一列被使用了,如果可能的话,是一个常数。 | 14 | | rows | MySQL认为必须检查的用来返回请求数据的行数。 | 15 | | Extra | 关于MySQL如何解析查询的额外信息。将在表4.3中讨论,但这里可以看到的坏的例子是Using temporary和Using filesort,意思MySQL根本不能使用索引,结果是检索会很慢。 | 16 | | extra | 列返回的描述的意义 | 17 | 18 | | 值 | 意义 | 19 | | :-------- | :----- | 20 | | Distinct | 一旦MySQL找到了与行相联合匹配的行,就不再搜索了。| 21 | | Not exists | MySQL优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行,就不再搜索了。| 22 | | Range checked for each Record(index map:#) | 没有找到理想的索引,因此对于从前面表中来的每一个行组合,MySQL检查使用哪个索引,并用它来从表中返回行。这是使用索引的最慢的连接之一。| 23 | | Using filesort | 看到这个的时候,查询就需要优化了。MySQL需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行。| 24 | | Using index | 列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候。| 25 | | Using temporary | 看到这个的时候,查询需要优化了。这里,MySQL需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDER BY上,而不是GROUP BY上。| 26 | | Where used | 使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。如果不想返回表中的全部行,并且连接类型ALL或index,这就会发生,或者是查询有问题不同连接类型的解释(按照效率高低的顺序排序)。| 27 | | system | 表只有一行 system 表。这是const连接类型的特殊情况 。| 28 | | const | 表中的一个记录的最大值能够匹配这个查询(索引可以是主键或惟一索引)。因为只有一行,这个值实际就是常数,因为MySQL先读这个值然后把它当做常数来对待。| 29 | | eq_ref | 在连接中,MySQL在查询时,从前面的表中,对每一个记录的联合都从表中读取一个记录,它在查询使用了索引为主键或惟一键的全部时使用。| 30 | | ref | 这个连接类型只有在查询使用了不是惟一或主键的键或者是这些类型的部分(比如,利用最左边前缀)时发生。对于之前的表的每一个行联合,全部记录都将从表中读出。这个类型严重依赖于根据索引匹配的记录多少—越少越好。| 31 | | range | 这个连接类型使用索引返回一个范围中的行,比如使用>或<查找东西时发生的情况。| 32 | | index | 这个连接类型对前面的表中的每一个记录联合进行完全扫描(比ALL更好,因为索引一般小于表数据)。| 33 | | ALL | 这个连接类型对于前面的每一个记录联合进行完全扫描,这一般比较糟糕,应该尽量避免。| 34 | -------------------------------------------------------------------------------- /mysql/used.md: -------------------------------------------------------------------------------- 1 | ### 查询某表的所有字段 2 | ```mysql 3 | select column_name from information_schema.columns where table_schema='库名' and table_name='表名' order by column_name; 4 | ``` 5 | -------------------------------------------------------------------------------- /nosql/README.md: -------------------------------------------------------------------------------- 1 | ### Redis11种Web应用场 2 | * 在主页中显示最新的项目列表。 3 | * Redis使用的是常驻内存的缓存,速度非常快。LPUSH用来插入一个内容ID,作为关键字存储在列表头部。LTRIM用来限制列表中的项目数最多为5000。如果用户需要的检索的数据量超越这个缓存容量,这时才需要把请求发送到数据库。 4 | * 删除和过滤。 5 | * 如果一篇文章被删除,可以使用LREM从缓存中彻底清除掉。 6 | * 排行榜及相关问题。 7 | * 排行榜(leader board)按照得分进行排序。ZADD命令可以直接实现这个功能,而ZREVRANGE命令可以用来按照得分来获取前100名的用户,ZRANK可以用来获取用户排名,非常直接而且操作容易。 8 | * 按照用户投票和时间排序。 9 | * 这就像Reddit的排行榜,得分会随着时间变化。LPUSH和LTRIM命令结合运用,把文章添加到一个列表中。一项后台任务用来获取列表,并重新计算列表的排序,ZADD命令用来按照新的顺序填充生成列表。列表可以实现非常快速的检索,即使是负载很重的站点。 10 | * 过期项目处理。 11 | * 使用unix时间作为关键字,用来保持列表能够按时间排序。对current_time和time_to_live进行检索,完成查找过期项目的艰巨任务。另一项后台任务使用ZRANGE...WITHSCORES进行查询,删除过期的条目。 12 | * 计数。 13 | * 进行各种数据统计的用途是非常广泛的,比如想知道什么时候封锁一个IP地址。INCRBY命令让这些变得很容易,通过原子递增保持计数;GETSET用来重置计数器;过期属性用来确认一个关键字什么时候应该删除。 14 | * 特定时间内的特定项目。 15 | * 这是特定访问者的问题,可以通过给每次页面浏览使用SADD命令来解决。SADD不会将已经存在的成员添加到一个集合。 16 | * 实时分析正在发生的情况,用于数据统计与防止垃圾邮件等。 17 | * 使用Redis原语命令,更容易实施垃圾邮件过滤系统或其他实时跟踪系统。 18 | * Pub/Sub。 19 | * 在更新中保持用户对数据的映射是系统中的一个普遍任务。Redis的pub/sub功能使用了SUBSCRIBE、UNSUBSCRIBE和PUBLISH命令,让这个变得更加容易。 20 | * 队列。 21 | * 在当前的编程中队列随处可见。除了push和pop类型的命令之外,Redis还有阻塞队列的命令,能够让一个程序在执行时被另一个程序添加到队列。你也可以做些更有趣的事情,比如一个旋转更新的RSS feed队列。 22 | * 缓存。 23 | * Redis缓存使用的方式与memcache相同。网络应用不能无休止地进行模型的战争,看看这些Redis的原语命令,尽管简单但功能强大,把它们加以组合,所能完成的就更无法想象。当然,你可以专门编写代码来完成所有这些操作,但Redis实现起来显然更为轻松。 24 | -------------------------------------------------------------------------------- /open-source/README.md: -------------------------------------------------------------------------------- 1 | ### blog 2 | * [WordPress](https://github.com/WordPress/WordPress) 3 | * [typecho](https://github.com/typecho/typecho) 4 | 5 | ### cms 6 | * [joomla](https://github.com/joomla/joomla-cms) 7 | * [drupal](https://github.com/drupal/drupal) 8 | * [PhalconEye](https://github.com/PhalconEye/cms) 9 | * [october](https://github.com/octobercms/october) 10 | 11 | -------------------------------------------------------------------------------- /open-source/sublime-text.md: -------------------------------------------------------------------------------- 1 | ### 配置 2 | 3 | ```json 4 | { 5 | "color_scheme": "Packages/Theme - Spacegray/base16-eighties.dark.tmTheme", 6 | "theme": "Spacegray Eighties.sublime-theme", 7 | "open_files_in_new_window": false, 8 | "default_line_ending": "unix", 9 | "update_check": false, 10 | "word_wrap": "true", 11 | "wrap_width": 100, 12 | "font_size": 12, 13 | "tab_size": 4, 14 | "ignored_packages": 15 | [ 16 | "Vintage" 17 | ] 18 | } 19 | ``` 20 | 21 | ### 插件 22 | * ColorPicker //颜色选择器 23 | * DocBlockr //注释 24 | * Git //版本控制 25 | * GitGutter //GitGutter 更好的帮助开发者查看文件之前的改动和差异,提升开发效率 26 | * jQuery //提示 27 | * Markdown Preview //预览 28 | * Theme - Spacegray //模版和配色方案 29 | * Ctags //代码搜索 30 | * Emmet //html+css快速编写 31 | * AllAutocomplete //搜索全部打开的标签页 32 | * AutoFileName //自动补全文件路径 33 | * SideBarEnhancements //侧边栏添加很多额外的功能 34 | * SublimeREPL //允许你在 Sublime Texxt 中运行各种语言 35 | * Blade Snippets //提供 Blade 模板自动补全 36 | * Laravel 4 Blade Highlighter //提供 Blade 关键字高亮 37 | -------------------------------------------------------------------------------- /php/README.md: -------------------------------------------------------------------------------- 1 | ### 自动加载类 2 | 3 | ```php 4 | 18 | ``` 19 | 20 | ---- 21 | 22 | ### 验证邮件地址 23 | 24 | ```php 25 | 32 | ``` 33 | 34 | ---- 35 | 36 | ### 净化 HTML 输入和输出 37 | 38 | ```php 39 | Mua-ha-ha! Twiddling my evil mustache...
'; 42 | 43 | // Use the ENT_QUOTES flag to make sure both single and double quotes are escaped. 44 | // Use the UTF-8 character encoding if you've stored the text as UTF-8 (as you should have). 45 | // See the UTF-8 section in this document for more details. 46 | $safeHtml = htmlentities($evilHtml, ENT_QUOTES, 'UTF-8'); 47 | // $safeHtml is now fully escaped HTML. You can output $safeHtml to your users without fear! 48 | ?> 49 | ``` 50 | 51 | ---- 52 | 53 | ### 检测一个值是否为 null 或 false 54 | 55 | ```php 56 | 81 | ``` 82 | 83 | ---- 84 | 85 | ### 让项目支持laravel一样的自动环境检测(by [overtrue](https://github.com/overtrue)) 86 | 87 | 代码在**开发**机器上自动调用开发配置,当为产品环境自动调用产品环境配置,让你的应用自动化识别运行环境的方法: 88 | 89 | 1. 添加环境列表: 90 | 91 | app/env.php: 92 | ```php 93 | [hostname1, hostname2, ...] , 环境名请通过shell命令: hostname 得到 97 | 'local' => ['overtrue', 'domain.local'], 98 | 'production' => ['*'], // 除了local的机器外,其它为产品环境 99 | ]; 100 | ``` 101 | 2. 环境识别函数: 102 | 103 | ```php 104 | /** 105 | * 获取应用运行环境 106 | * 107 | * @return string 108 | */ 109 | function env($test = null) 110 | { 111 | $envs = include __DIR__ . '/env.php'; 112 | foreach ($envs as $env => $hostnames) { 113 | if (in_array(gethostname(), $hostnames) || in_array('*', $hostnames)) { 114 | return $test ? $env == $test : $env; 115 | } 116 | } 117 | 118 | return $test ? 'production' === $test : 'production'; 119 | } 120 | ``` 121 | 3. 根据环境值读取对应的配置: 122 | 123 | ```php 124 | $env = env(); // local 125 | // do you things. 126 | 127 | ``` 128 | 得到了环境名,就拿他去读取相应的配置文件吧,更多可以参考:https://github.com/overtrue/rester 129 | 130 | ---- 131 | 132 | ### 生成唯一订单号 133 | 134 | ```php 135 | // 有人反映下面代码,不靠谱,冲撞率极高,这里就仅做学习,不推荐正式环境使用了 136 | /** 137 | * 138 | * uniqid - 官方是这样说的: 139 | * Gets a prefixed unique identifier based on the current time in microseconds. 140 | */ 141 | function build_order_no() 142 | { 143 | return date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8); 144 | } 145 | 146 | // 补充:来自ECSHOP订单号生成函数:/includes/lib_order.php文件中的get_order_sn() 147 | /** 148 | * 得到新订单号 149 | * @return string 150 | */ 151 | function build_order_no() 152 | { 153 | /* 选择一个随机的方案 */ 154 | // Note: 自 PHP 4.2.0 起,不再需要用 srand() 或 mt_srand() 给随机数发生器播种 ,因为现在是由系统自动完成的。 155 | mt_srand((double) microtime() * 1000000); 156 | 157 | return date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT); 158 | } 159 | ``` 160 | 161 | 162 | ---- 163 | 164 | ### 5行vs9行 不用递归实现无限分类数据的树形格式化 165 | 166 | ```php 167 | array('id' => 1, 'pid' => 0, 'name' => '江西省'), 199 | 2 => array('id' => 2, 'pid' => 0, 'name' => '黑龙江省'), 200 | 3 => array('id' => 3, 'pid' => 1, 'name' => '南昌市'), 201 | 4 => array('id' => 4, 'pid' => 2, 'name' => '哈尔滨市'), 202 | 5 => array('id' => 5, 'pid' => 2, 'name' => '鸡西市'), 203 | 6 => array('id' => 6, 'pid' => 4, 'name' => '香坊区'), 204 | 7 => array('id' => 7, 'pid' => 4, 'name' => '南岗区'), 205 | 8 => array('id' => 8, 'pid' => 6, 'name' => '和兴路'), 206 | 9 => array('id' => 9, 'pid' => 7, 'name' => '西大直街'), 207 | 10 => array('id' => 10, 'pid' => 8, 'name' => '东北林业大学'), 208 | 11 => array('id' => 11, 'pid' => 9, 'name' => '哈尔滨工业大学'), 209 | 12 => array('id' => 12, 'pid' => 8, 'name' => '哈尔滨师范大学'), 210 | 13 => array('id' => 13, 'pid' => 1, 'name' => '赣州市'), 211 | 14 => array('id' => 14, 'pid' => 13, 'name' => '赣县'), 212 | 15 => array('id' => 15, 'pid' => 13, 'name' => '于都县'), 213 | 16 => array('id' => 16, 'pid' => 14, 'name' => '茅店镇'), 214 | 17 => array('id' => 17, 'pid' => 14, 'name' => '大田乡'), 215 | 18 => array('id' => 18, 'pid' => 16, 'name' => '义源村'), 216 | 19 => array('id' => 19, 'pid' => 16, 'name' => '上坝村'), 217 | ); 218 | 219 | header("Content-Type: text/html; charset=utf-8"); 220 | echo "
";
221 | print_r(genTree5($items));
222 | print_r(genTree9($items));
223 | echo "
"; 224 | ``` 225 | 226 | >via:http://levi.cg.am/archives/2115 227 | 228 | --- 229 | 230 | ### 解决中文用base64_decode解密的时候,出现乱码 231 | * 利用PHP函数设置页面的头文件编码 232 | 233 | ```php 234 | header("Content-Type:text/html;charset=utf-8"); 235 | ``` 236 | 237 | * 有一些中文字符,用GET形式传过来的时候,+号会被替换成空格. 238 | 239 | ```php 240 | $key = base64_decode(str_replace(" ","+",$_GET['key'])); 241 | ``` 242 | 243 | ---- 244 | 245 | ### 缓冲区刷新 246 | 247 | ```php 248 | function flush_buffers() 249 | { 250 | ob_end_flush(); 251 | ob_flush(); 252 | flush(); 253 | ob_start('ob_callback'); 254 | } 255 | 256 | function ob_callback($buffer) 257 | { 258 | return $buffer . str_repeat(' ', max(0, 4097 - strlen($buffer))); 259 | } 260 | ``` 261 | 262 | ---- 263 | 264 | ### 简单的页面缓存 265 | 如果你的项目不是基于 CMS 系统或框架,打造一个简单的缓存系统将会非常实在。下面的代码很简单,但是对小网站而言能切切实实解决问题 266 | 267 | ```php 268 | 281 | 282 | output all your html here. 283 | 284 | 292 | ``` 293 | 294 | > via: http://wesbos.com/simple-php-page-caching-technique/ 295 | 296 | ---- 297 | 298 | ### 在 PHP 中计算距离 299 | 这是一个非常有用的距离计算函数,利用纬度和经度计算从 A 地点到 B地点的距离。该函数可以返回英里,公里,海里三种单位类型的距离。 300 | 301 | ```php 302 | function distance($lat1, $lon1, $lat2, $lon2, $unit) { 303 | $theta = $lon1 - $lon2; 304 | $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta)); 305 | $dist = acos($dist); 306 | $dist = rad2deg($dist); 307 | $miles = $dist * 60 * 1.1515; 308 | $unit = strtoupper($unit); 309 | 310 | if ($unit == "K") { 311 | return ($miles * 1.609344); 312 | } else if ($unit == "N") { 313 | return ($miles * 0.8684); 314 | } else { 315 | return $miles; 316 | } 317 | } 318 | 319 | //使用方法: 320 | echo distance(32.9697, -96.80322, 29.46786, -98.53506, "k")." kilometers"; 321 | ``` 322 | 323 | ---- 324 | 325 | ###将秒数转换为时间(年、月、日、小时…) 326 | 这个有用的函数能将秒数表示的事件转换为年、月、日、小时等时间格式。 327 | 328 | ```php 329 | function Sec2Time($time){ 330 | if(is_numeric($time)){ 331 | $value = array( 332 | "years" => 0, "days" => 0, "hours" => 0, 333 | "minutes" => 0, "seconds" => 0, 334 | ); 335 | if($time >= 31556926){ 336 | $value["years"] = floor($time/31556926); 337 | $time = ($time%31556926); 338 | } 339 | if($time >= 86400){ 340 | $value["days"] = floor($time/86400); 341 | $time = ($time%86400); 342 | } 343 | if($time >= 3600){ 344 | $value["hours"] = floor($time/3600); 345 | $time = ($time%3600); 346 | } 347 | if($time >= 60){ 348 | $value["minutes"] = floor($time/60); 349 | $time = ($time%60); 350 | } 351 | $value["seconds"] = floor($time); 352 | return (array) $value; 353 | }else{ 354 | return (bool) FALSE; 355 | } 356 | } 357 | ``` 358 | 359 | ---- 360 | 361 | ### 强制下载文件 362 | 一些诸如 mp3 类型的文件,通常会在客户端浏览器中直接被播放或使用。如果你希望它们强制被下载,也没问题。可以使用以下代码: 363 | 364 | ```php 365 | function downloadFile($file){ 366 | $file_name = $file; 367 | $mime = 'application/force-download'; 368 | header('Pragma: public'); // required 369 | header('Expires: 0'); // no cache 370 | header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 371 | header('Cache-Control: private',false); 372 | header('Content-Type: '.$mime); 373 | header('Content-Disposition: attachment; filename="'.basename($file_name).'"'); 374 | header('Content-Transfer-Encoding: binary'); 375 | header('Connection: close'); 376 | readfile($file_name); // push it out 377 | exit(); 378 | } 379 | ``` 380 | ---- 381 | 382 | ### PHP加密解密 383 | PHP加密和解密函数可以用来加密一些有用的字符串存放在数据库里,并且通过可逆解密字符串,该函数使用了base64和MD5加密和解密。 384 | 385 | ```php 386 | function encryptDecrypt($key, $string, $decrypt){ 387 | if($decrypt){ 388 | $decrypted = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($string), MCRYPT_MODE_CBC, md5(md5($key))), "12"); 389 | return $decrypted; 390 | }else{ 391 | $encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $string, MCRYPT_MODE_CBC, md5(md5($key)))); 392 | return $encrypted; 393 | } 394 | } 395 | ``` 396 | 397 | ---- 398 | 399 | ### PHP获取文件大小并格式化 400 | 401 | ```php 402 | function formatSize($size) { 403 | $sizes = array(" Bytes", " KB", " MB", " GB", " TB", " PB", " EB", " ZB", " YB"); 404 | if ($size == 0) { 405 | return('n/a'); 406 | } else { 407 | return (round($size/pow(1024, ($i = floor(log($size, 1024)))), 2) . $sizes[$i]); 408 | } 409 | } 410 | ``` 411 | 412 | ### PHP获取当前页面URL 413 | 414 | ```php 415 | function curPageURL() { 416 | $pageURL = 'http'; 417 | if (!empty($_SERVER['HTTPS'])) {$pageURL .= "s";} 418 | $pageURL .= "://"; 419 | if ($_SERVER["SERVER_PORT"] != "80") { 420 | $pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"]; 421 | } else { 422 | $pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"]; 423 | } 424 | return $pageURL; 425 | } 426 | ``` 427 | 428 | ---- 429 | 430 | ### PHP强制下载文件 431 | 432 | ---- 433 | 434 | ```php 435 | function download($filename){ 436 | if ((isset($filename))&&(file_exists($filename))){ 437 | header("Content-length: ".filesize($filename)); 438 | header('Content-Type: application/octet-stream'); 439 | header('Content-Disposition: attachment; filename="' . $filename . '"'); 440 | readfile("$filename"); 441 | } else { 442 | echo "Looks like file does not exist!"; 443 | } 444 | } 445 | ``` 446 | 447 | ### PHP截取字符串长度 448 | 我们经常会遇到需要截取字符串(含中文汉字)长度的情况,比如标题显示不能超过多少字符,超出的长度用...表示,以下函数可以满足你的需求。 449 | 450 | ```php 451 | /* 452 | Utf-8、gb2312都支持的汉字截取函数 453 | cut_str(字符串, 截取长度, 开始长度, 编码); 454 | 编码默认为 utf-8 455 | 开始长度默认为 0 456 | */ 457 | function cutStr($string, $sublen, $start = 0, $code = 'UTF-8'){ 458 | if($code == 'UTF-8'){ 459 | $pa = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/"; 460 | preg_match_all($pa, $string, $t_string); 461 | 462 | if(count($t_string[0]) - $start > $sublen) return join('', array_slice($t_string[0], $start, $sublen))."..."; 463 | return join('', array_slice($t_string[0], $start, $sublen)); 464 | }else{ 465 | $start = $start*2; 466 | $sublen = $sublen*2; 467 | $strlen = strlen($string); 468 | $tmpstr = ''; 469 | 470 | for($i=0; $i<$strlen; $i++){ 471 | if($i>=$start && $i<($start+$sublen)){ 472 | if(ord(substr($string, $i, 1))>129){ 473 | $tmpstr.= substr($string, $i, 2); 474 | }else{ 475 | $tmpstr.= substr($string, $i, 1); 476 | } 477 | } 478 | if(ord(substr($string, $i, 1))>129) $i++; 479 | } 480 | if(strlen($tmpstr)<$strlen ) $tmpstr.= "..."; 481 | return $tmpstr; 482 | } 483 | } 484 | ``` 485 | 486 | ---- 487 | 488 | ### PHP获取客户端真实IP 489 | 490 | ```php 491 | //获取用户真实IP 492 | function getIp() { 493 | if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown")) 494 | $ip = getenv("HTTP_CLIENT_IP"); 495 | else 496 | if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown")) 497 | $ip = getenv("HTTP_X_FORWARDED_FOR"); 498 | else 499 | if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown")) 500 | $ip = getenv("REMOTE_ADDR"); 501 | else 502 | if (isset ($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown")) 503 | $ip = $_SERVER['REMOTE_ADDR']; 504 | else 505 | $ip = "unknown"; 506 | return ($ip); 507 | } 508 | ``` 509 | 510 | ---- 511 | 512 | ### PHP防止SQL注入 513 | 514 | ```php 515 | function injCheck($sql_str) { 516 | $check = preg_match('/select|insert|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile/', $sql_str); 517 | if ($check) { 518 | echo '非法字符!!'; 519 | exit; 520 | } else { 521 | return $sql_str; 522 | } 523 | } 524 | ``` 525 | 526 | ---- 527 | 528 | ### PHP页面提示与跳转 529 | 530 | ```php 531 | function message($msgTitle,$message,$jumpUrl){ 532 | $str = ''; 533 | $str .= ''; 534 | $str .= ''; 535 | $str .= ''; 536 | $str .= '页面提示'; 537 | $str .= ''; 540 | $str .= ''; 541 | $str .= ''; 542 | $str .= '
'; 543 | $str .= '

'.$msgTitle.'

'; 544 | $str .= '
'; 545 | $str .= '

'.$message.'

'; 546 | $str .= '

系统将在 3 秒后自动跳转,如果不想等待,直接点击 这里 跳转

'; 547 | $str .= ""; 548 | $str .= '
'; 549 | $str .= '
'; 550 | $str .= ''; 551 | $str .= ''; 552 | echo $str; 553 | } 554 | ``` 555 | 556 | ---- 557 | 558 | ### PHP计算时长 559 | 560 | ```php 561 | function changeTimeType($seconds) { 562 | if ($seconds > 3600) { 563 | $hours = intval($seconds / 3600); 564 | $minutes = $seconds % 3600; 565 | $time = $hours . ":" . gmstrftime('%M:%S', $minutes); 566 | } else { 567 | $time = gmstrftime('%H:%M:%S', $seconds); 568 | } 569 | return $time; 570 | } 571 | ``` 572 | 573 | ---- 574 | 575 | ### PHP打印数组 576 | 577 | ```php 578 | function cf_dd(){ 579 | array_map(function($x) { var_dump($x); }, func_get_args()); die; 580 | } 581 | ``` 582 | 583 | ---- 584 | 585 | ### 遍历删除目录和目录下所有文件 586 | 587 | ```php 588 | function cf_del_dir($dir){ 589 | if (!is_dir($dir)){ 590 | return false; 591 | } 592 | $handle = opendir($dir); 593 | while (($file = readdir($handle)) !== false){ 594 | if ($file != "." && $file != ".."){ 595 | is_dir("$dir/$file")? cf_del_dir("$dir/$file"):@unlink("$dir/$file"); 596 | } 597 | } 598 | if (readdir($handle) == false){ 599 | closedir($handle); 600 | @rmdir($dir); 601 | } 602 | } 603 | ``` 604 | 605 | ---- 606 | 607 | ### 纠正不完整HTML(by [overtrue](https://github.com/overtrue)) 608 | 609 | ```php 610 | function force_balance_tags( $text ) { 611 | $tagstack = array(); 612 | $stacksize = 0; 613 | $tagqueue = ''; 614 | $newtext = ''; 615 | // Known single-entity/self-closing tags 616 | $single_tags = array( 'area', 'base', 'basefont', 'br', 'col', 'command', 'embed', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param', 'source' ); 617 | // Tags that can be immediately nested within themselves 618 | $nestable_tags = array( 'blockquote', 'div', 'object', 'q', 'span' ); 619 | 620 | // WP bug fix for comments - in case you REALLY meant to type '< !--' 621 | $text = str_replace('< !--', '< !--', $text); 622 | // WP bug fix for LOVE <3 (and other situations with '<' before a number) 623 | $text = preg_replace('#<([0-9]{1})#', '<$1', $text); 624 | 625 | while ( preg_match("/<(\/?[\w:]*)\s*([^>]*)>/", $text, $regex) ) { 626 | $newtext .= $tagqueue; 627 | 628 | $i = strpos($text, $regex[0]); 629 | $l = strlen($regex[0]); 630 | 631 | // clear the shifter 632 | $tagqueue = ''; 633 | // Pop or Push 634 | if ( isset($regex[1][0]) && '/' == $regex[1][0] ) { // End Tag 635 | $tag = strtolower(substr($regex[1],1)); 636 | // if too many closing tags 637 | if( $stacksize <= 0 ) { 638 | $tag = ''; 639 | // or close to be safe $tag = '/' . $tag; 640 | } 641 | // if stacktop value = tag close value then pop 642 | else if ( $tagstack[$stacksize - 1] == $tag ) { // found closing tag 643 | $tag = ''; // Close Tag 644 | // Pop 645 | array_pop( $tagstack ); 646 | $stacksize--; 647 | } else { // closing tag not at top, search for it 648 | for ( $j = $stacksize-1; $j >= 0; $j-- ) { 649 | if ( $tagstack[$j] == $tag ) { 650 | // add tag to tagqueue 651 | for ( $k = $stacksize-1; $k >= $j; $k--) { 652 | $tagqueue .= ''; 653 | $stacksize--; 654 | } 655 | break; 656 | } 657 | } 658 | $tag = ''; 659 | } 660 | } else { // Begin Tag 661 | $tag = strtolower($regex[1]); 662 | 663 | // Tag Cleaning 664 | 665 | // If it's an empty tag "< >", do nothing 666 | if ( '' == $tag ) { 667 | // do nothing 668 | } 669 | // ElseIf it presents itself as a self-closing tag... 670 | elseif ( substr( $regex[2], -1 ) == '/' ) { 671 | // ...but it isn't a known single-entity self-closing tag, then don't let it be treated as such and 672 | // immediately close it with a closing tag (the tag will encapsulate no text as a result) 673 | if ( ! in_array( $tag, $single_tags ) ) 674 | $regex[2] = trim( substr( $regex[2], 0, -1 ) ) . "> 0 && !in_array($tag, $nestable_tags) && $tagstack[$stacksize - 1] == $tag ) { 684 | $tagqueue = ''; 685 | $stacksize--; 686 | } 687 | $stacksize = array_push( $tagstack, $tag ); 688 | } 689 | 690 | // Attributes 691 | $attributes = $regex[2]; 692 | if( ! empty( $attributes ) && $attributes[0] != '>' ) 693 | $attributes = ' ' . $attributes; 694 | 695 | $tag = '<' . $tag . $attributes . '>'; 696 | //If already queuing a close tag, then put this tag on, too 697 | if ( !empty($tagqueue) ) { 698 | $tagqueue .= $tag; 699 | $tag = ''; 700 | } 701 | } 702 | $newtext .= substr($text, 0, $i) . $tag; 703 | $text = substr($text, $i + $l); 704 | } 705 | 706 | // Clear Tag Queue 707 | $newtext .= $tagqueue; 708 | 709 | // Add Remaining text 710 | $newtext .= $text; 711 | 712 | // Empty Stack 713 | while( $x = array_pop($tagstack) ) 714 | $newtext .= ''; // Add remaining tags to close 715 | 716 | // WP fix for the bug with HTML comments 717 | $newtext = str_replace("< !--","