首页
留言
友链
关于
Search
1
思源笔记docker私有化部署及使用体验分享
2,879 阅读
2
windows11 远程提示:为安全考虑,已锁定该用户帐户,原因是登录尝试或密码更改尝试过多。
1,230 阅读
3
解决 nginxProxyManager 申请证书时的SSL失败问题
882 阅读
4
Pointer-Focus:一款功能强大的教学、录屏辅助软件
857 阅读
5
使用cspell对项目做拼写规范检查
720 阅读
Web前端
CSS
JavaScript
交互
Vue
小程序
后端
Java
运维
项目
生活
其他
转载
软件
职场
登录
Search
标签搜索
docker
DevOps
magic-boot
Linux
酷壳
frp
RabbitMQ
gitlab
Node
git
工具
MybatisPlus
clickhouse
Syncthing
规范
前端
产品
nginx
markdown
axios
朱治龙
累计撰写
153
篇文章
累计收到
10
条评论
首页
栏目
Web前端
CSS
JavaScript
交互
Vue
小程序
后端
Java
运维
项目
生活
其他
转载
软件
职场
页面
留言
友链
关于
搜索到
153
篇与
朱治龙
的结果
2017-09-07
基于nodejs的微服务的注册与发现机制实现的调研
https://github.com/lehoangduc/node-registrify基于hapi和redis的服务注册,同时提供命令行操作被设计为一个注册中心,注册服务和服务发现由客户端通过RESTAPI去获取优点:代码逻辑比较清晰,接口比较全问题:github星:22颗 参考价值:4分 接口全https://github.com/samuelkitazume/nodeservices基于express和nedb,包括服务注册与服务发现,提供命令行操作。被设计为一个注册中心。优点:代码简洁,问题:没有健康检查github星:1颗 参考价值:5分https://github.com/Digipolitan/yemma-discoveryhttps://github.com/Digipolitan/yemma基于express、mongoDB、socket.io,被设计为子应用(客户端)调用,通过token鉴权。优点:有心跳机制,有服务token鉴权,注册服务非常简单。问题:要配合yemma框架,代码不直观github星:1颗 参考价值:3分https://github.com/ParthaBoocha/service-registry基于glue(glue)基于hapi,看代码迁移到express也很容易,用的json文件存储数据对跨域有处理,被设计为一个注册中心。优点:代码简洁问题:对微服务没有特别的处理,例如没有心跳机制,只是一个简单的数据存储读取github星:0颗 参考价值:5分 json文件存数据https://github.com/express-components/registry基于 express、nedb、socket.io的,基于udp协议的服务注册,有健康检查,健康检查没使用数据训的TTL特性,是用的时间比较,然后主支去请求各服务的状态,看来是被设计为一个注册中心。服务发现由客户端通过RESTAPI去获取。优点:基于udp协议,有健康检查问题:github星:0颗 参考价值:7分 udp协议与健康检查https://github.com/RCT-Solutions/rct-nars基于express,处理了跨域情况,使用自己写的迷你内存数据库,有健康检查接口(待客户端去调用),注册和服务发现都是由客户端通过RESTAPI去获取,看来是设计为一个注册中心优点:模块分的比较细,对心跳包等的数据结构定义规范问题:模块分的比较细,健康检查没示例github星:0颗 参考价值:6分 内存数据库,https://github.com/nswbmw/etcd-proxy基于koa和etcd的,有服务注册,本身的实现为子应用(客户端),非注册中心,注册中心即为数据库,心跳机制为每5秒去更新etcd里的过期时间(TTL,即Time To Life),服务发现由客户端通过RESTAPI去获取通过不断地注册来作心跳,通过工具库ip获取ip,通过工具库get-port获取可用端口,好像是相同的应用名允许注册多个,返回时随机取一个优点:121行代码,代码简洁,功能完备,赞问题:依赖etcd,使用了etcd的过期机制TTLgithub星:3颗 参考价值:8分 代码简洁https://github.com/koalazak/redis-registry基于redis,有服务注册,本身的实现为子应用(客户端),非注册中心,注册中心即为数据库,心跳机制为每5秒去更新redis里的过期时间,服务发现由客户端通过查询redis去获取通过工具库network-address获取,好像是相同的应用名允许注册多个,返回时随机取一个优点:174行代码,代码简洁,问题:依赖redis,使用了redis的过期机制expiregithub星:3颗 参考价值:7分 代码简洁{name: 'my-service-name',port: 8080,hostname: '192.168.1.10',host: '192.168.1.10:8080',url: 'http://192.168.1.10:8080'}发现几个工具包https://www.npmjs.com/package/get-port获得一个没有被占用的端口https://www.npmjs.com/package/network-address获取本地iphttps://www.npmjs.com/package/ip获取ip,及掩码等,功能比network-address多https://www.npmjs.com/package/network-address获取机器ip或ipv6https://www.npmjs.com/package/nedb-promisehttps://github.com/louischatriot/nedbjs数据库,执久或内存数据库,API为MongoDB子集https://www.npmjs.com/package/glue管理hapi.js创建的服务https://www.npmjs.com/package/hapi知名web服务框架https://github.com/coreos/etcdgo语言写的分布式高可用键值对数据库https://www.npmjs.com/package/request-promise
2017年09月07日
22 阅读
0 评论
0 点赞
30分钟教你入门Git
Git近些年的火爆程度非同一般,这个版本控制系统被广泛地用在大型开源项目(比如Linux),不同规模的团队开发,以及独立开发者,甚至学生之中。初学者非常容易被git里的 各种命令、参数 吓得不愿意继续去学。但实际上刚上手的时候,你并不需要了解所有命令的用途。你可以从掌握一些简单、常用又强大的命令开始,然后逐步去学习。这就是我们这篇文章要讲的内容。让我们快开始吧!基本了解Git是一些命令行工具的集合,可以用来跟踪、记录文件的变动,经常用于开源代码。比如你可以进行旧版本恢复、比对、分析、合并等等。这个过程被称之为版本控制。已经有一系列的版本控制系统,比如SVN、Mercurial、Perforce、CVS、Bitkeepe等等。Git是分布式的,这意味着它并不依赖于中心服务器来保存你文件的旧版本。任何一台机器都可以有一个本地版本的控制系统,其实就是一个硬盘上的文件,我们称之为仓库(repository)。如果是多人协作的话,你还需要一个线上仓库,用来同步代码等信息。这就是GitHub、Gitlab、Gittee、BitBucket等网站做的工作。安装Git在你的机器上安装git非常简单:Linux – 打开终端,然后通过包管理安装,在Ubuntu上命令是: sudo apt-get install gitWindows – 推荐使用 git for windows ,它包括了图形工具以及命令行模拟器。OS X – 最简单的方式是使用 homebrew 安装,命令行执行brew install git如果你是新手,推荐使用图形工具 Github desktop、 TortoiseGit 和 Sourcetree 。不过即使使用图形界面的应用,知道一些基本的git命令依然很重要。接下来的内容我们集中在命令行控制上。2.配置Git安装完git,首要任务是做一些简单的配置,最重要的是用户名及邮箱,打开终端,执行以下命令。$ git config --global user.name "My Name" $ git config --global user.email myEmail@example.com配置好这两项,Git就能记录下来是谁做的动作,一切都更有组织性了。3.创建一个新仓库 – git initgit会把所有文件以及历史记录直接记录成一个文件夹保存在你的项目中。创建一个新的仓库,首先要去到项目路径下,执行git init。这时Git会创建一个隐藏的文件夹.git,所有的历史和配置信息都储存在其中。比如我们在桌面创建一个文件夹 git_exercise, 打开终端,输入:$ cd Desktop/git_exercise/ $ git init命令行会出现类似于如下的提示信息Initialized empty Git repository in /home/user/Desktop/git_exercise/.git/这说明我们的仓库已经建立好了,但现在是空的,试着新建一个hello.txt文本文件到这个文件夹里。4.检查状态 – git statusGit status是另一个非常重要的命令,它反馈给我们仓库当前状态的信息:是否为最新代码,有什么更新等等。在我们新建的仓库中执行git status会得到以下内容:$ git status On branch master Initial commit Untracked files: (use "git add ..." to include in what will be committed) hello.txt反馈信息告诉我们,hello.txt尚未跟踪,这是说这个文件是新的,git不知道是应该跟踪它的变动还是直接忽略。为了跟踪我们的新文件,我们需要暂存它。5.暂存 – git addGit有个概念叫“暂存区“,你可以把它看成一块空白的画布,包裹着所有你可能会提交的变动。它一开始是空的,可以通过 git add 命令添加内容,最后使用 git commit 提交(创建一个快照)。这个例子中只有一个文件,让我们先add它:$ git add hello.txt如果需要提交目录下的所有内容,可以这样做:$ git add -A再次使用git status查看状态试试:$ git status On branch master Initial commit Changes to be committed: (use "git rm --cached ..." to unstage) new file: hello.txt我们的文件已经准备好可以提交了。状态信息还告诉我们暂存区文件发生了什么变动,这里我们新增了一个文件,同样可以做修改和删除。取决于我们在上一次git add之后发生了什么。6.提交 – git commit一次提交代表着我们的仓库到了一个新的状态,就像是一个快照,允许我们像使用时光机一样回到之前的某个时间点。创建提交,需要我们至少在到暂存区有一次修改(刚才我们做了git add),然后输入命令:$ git commit -m "Initial commit."这就创建了一次从暂存区的提交(加入hello.txt),-m “Initial commit.”是用户对这次提交的描述,建议写成有意义的描述性信息。远程仓库到目前为止,我们的操作都是在本地的——只存在于.git文件中。为了能够协同开发,我们需要把代码部署到远程仓库服务器上。1.链接远程仓库 – git remote add为了能够上传到远程仓库,我们需要先建立起链接。在这篇教程中,我们远程仓库的地址为:https://github.com/igeekbar/awesome-project。但你应该自己在Github、或BitBucket上搭建仓库,自己一步一步尝试。把本地仓库链接到Github上,在命令行执行以下内容:# This is only an example. Replace the URI with your own repository address. $ git remote add origin https://github.com/igeekbar/awesome-project.git一个项目可以同时拥有好几个远程仓库,为了区分通常会起不同的名字。通常主要的远程仓库被称为origin。2.上传到服务器 – git push把本地的提交传送到服务器的动作叫做push。每次我们要提交修改到服务器上时,都会使用到git push。git push命令有两个参数,远程仓库的名字,以及分支的名字:$ git push origin master Counting objects: 3, done. Writing objects: 100% (3/3), 212 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To https://github.com/igeekbar/awesome-project.git * [new branch] master -> master取决于你使用的服务器,push过程中你可能需要验证身份(输入用户名、密码,请先在网站上进行注册)。如果没有出差错,现在用浏览器看你的远程仓库上已经有hello.txt了。3.克隆仓库 – git clone其他人可以看到你放在Github上的开源项目,他们可以用git clone命令下载到本地。$ git clone https://github.com/igeekbar/awesome-project.git本地也会创建一个新的仓库,并自动将github上的版本设为远程仓库。4.从服务器上获得修改 – git pull如果你更新了远程仓库上的内容,其他人可以通过git pull命令拉取你的变动:$ git pull origin master From https://github.com/igeekbar/awesome-project * branch master -> FETCH_HEAD Already up-to-date.因为在我们git clone之后还没有提交过修改,所有没有任何变动。分支当你在做一个新功能的时候,最好是在一个独立的区域上开发(原始项目的拷贝),通常称之为分支。分支之间相互独立,并且拥有自己的历史记录,直到你决定把他们合并到一起。这样做的原因是:已经可以运行的稳定版本的代码不会被破坏不同的功能可以由不同开发者同时开发开发者可以专注于自己的分支,不用担心被其他人破坏在不确定哪个版本更好之前,同一个特性可以在不同的分支上创建多个版本,便于比较1.创建新分支 – git branch每一个仓库的默认分支都叫master, 创建新分支可以用git branch <name>命令:$ git branch amazing_new_feature创建了一个名为amazing_new_feature的新分支,它目前和master分支是一样的内容。2.切换分支 – git checkout使用git branch,可以查看分支状态:$ git branch amazing_new_feature * master号表示当前活跃分支为master,现在我们想在新分支上开发新的特性,使用git checkout切换分支。有一个参数表示要切换到的分支。$ git checkout amazing_new_feature3.合并分支 – git merge我们在“amazing_new_feature”分支想添加一个feature.txt。和之前一样我们来创建文件、添加到暂存区、提交。$ git add feature.txt $ git commit -m "New feature complete."新分支任务完成了,回到master分支。$ git checkout master现在去查看文件夹内容,你会惊奇地发现之前刚刚创建的feature.txt文件不见了,因为我们现在回到了master分支上,这里并没有feature.txt。想把文件添加到这里,我们需要使用git merge把amazing_new_feature分支合并到master上。$ git merge amazing_new_feature现在master分支是最新的了,amazing_new_feature分支可以删掉了。$ git branch -d amazing_new_feature进阶功能在这篇教程的最后一节,我们来看一些高级并且实用的技巧。1.比对两个不同提交之间的差别每次提交都有一个标识id,查看所有历史提交和他们的id,可以使用 git log:$ git log commit ba25c0ff30e1b2f0259157b42b9f8f5d174d80d7 Author: igeekbar Date: Fri July 29 17:15:28 2016 +0300 New feature complete commit b10cc1238e355c02a044ef9f9860811ff605c9b4 Author: igeekbar Date: Fri July 29 16:30:04 2016 +0300 Added content to hello.txt commit 09bd8cc171d7084e78e4d118a2346b7487dca059 Author: igeekbar Date: Thu July 28 17:52:14 2016 +0300 Initial commitid很长,但是当使用它的时候你并不需要复制整个字符串,前几个字符就够了。查看某一次提交更新了什么,使用 git show [commit]:$ git show b10cc123 commit b10cc1238e355c02a044ef9f9860811ff605c9b4 Author: igeekbar Date: Fri July 29 16:30:04 2016 +0300 Added content to hello.txt diff --git a/hello.txt b/hello.txt index e69de29..b546a21 100644 --- a/hello.txt +++ b/hello.txt @@ -0,0 +1 @@ +Nice weather today, isn't it?查看两次提交的不同,可以使用git diff [commit-from]..[commit-to]:$ git diff 09bd8cc..ba25c0ff diff --git a/feature.txt b/feature.txt new file mode 100644 index 0000000..e69de29 diff --git a/hello.txt b/hello.txt index e69de29..b546a21 100644 --- a/hello.txt +++ b/hello.txt @@ -0,0 +1 @@ +Nice weather today, isn't it?比较首次提交和最后一次提交,我们可以看到中间所有的更改。使用git difftool命令可以用图形化界面查看所有更改。2.回滚某个文件到之前的版本Git允许我们将某个特定的文件回滚到特定的提交,使用的也是 git checkout命令。下面我们将hello.txt回滚到最初的状态,需要指定回滚到哪个提交(以id作为参数),以及文件的全路径。$ git checkout 09bd8cc1 hello.txt3.回滚提交如果你发现最新的一次提交忘记加入某个文件,或是信息输入的不正确,你可以通过 git commit --amend来改正,它会把最新的提交打回暂存区,并尝试重新提交。如果是更复杂的情况,比如不是最新的提交除了问题,你可以使用git revert。最新的一次提交别名也叫HEAD。$ git revert HEAD其他提交需要指明id:$ git revert b10cc123回滚提交时,发生冲突是非常频繁的。比如文件被指定回滚的提交之后的某次提交修改过,git不能正确回滚。4.解决合并冲突冲突经常出现在合并分支或者是拉取别人的代码。有些时候git能自动处理冲突,其他时候需要我们手动处理。我们来看以下的例子,John 和 Tim 分别在各自的分支上写了一段代码,来显示一个数组中所有的元素。John使用了for循环:// Use a for loop to console.log contents. for(var i=0; i<arr.length; i++) { console.log(arr[i]); }Tim使用forEach:// Use forEach to console.log contents. arr.forEach(function(item) { console.log(item); });它们都提交了代码到各自的分支上,现在假设John尝试合并Tim的代码:$ git merge tim_branch Auto-merging print_array.js CONFLICT (content): Merge conflict in print_array.js Automatic merge failed; fix conflicts and then commit the result.这时候git并不能自动解决冲突,于是它在代码中插入冲突标记。<<<<<<< HEAD // Use a for loop to console.log contents. for(var i=0; i<arr.length; i++) { console.log(arr[i]); } ======= // Use forEach to console.log contents. arr.forEach(function(item) { console.log(item); }); >>>>>>> Tim’s commit.==== 号上方是当前最新一次提交,下方是冲突的代码。这样我们可以清晰地看出区别,决定使用哪一个版本,或者重新写一个。假设我们对于这两个版本都不满意,我们把代码改成以下代码:// Not using for loop or forEach. // Use Array.toString() to console.log contents. console.log(arr.toString());好了,再提交一下:$ git add -A $ git commit -m "Array printing conflict resolved." ··· 在大型项目中,我们可能在合并过程中出现很多冲突,大部分开发者会借助GUI工具来获得帮助,运行推行界面可以使用git mergetool命令。 ### 5.配置 .gitignore 大部分项目中,会有些文件、文件夹是我们不想提交的。为了防止使用git add -A时不小心提交,我们可以利用.gitignore文件: - 在项目根目录创建.gitignore文件 - 在文件中列出不需要提交的文件名、文件夹名,每个一行 - .gitignore文件需要像普通文件一样add、commit和push 通常会被ignore的文件有: - log文件 - task runner builds - node.js项目中的node_modules文件夹 - IDEs比如NetBeans和IntelliJ生成的文件 - 个人笔记 以下是一个.gitignore文件的例子: *.logbuild/node_modules/.idea/my_notes.txt“/”说明是一个文件夹,里面的所有内容都被递归忽略 ------------ Git教程到这里就结束啦! Git很复杂,还有很多的特性和技巧等着你去挖掘,这篇教程只涵盖了冰山一角,希望你不要因为太多繁琐的命令而停下前进的脚步!加油! 再推荐一个学习git分支的在线交互网站: [Learn Git Branching](https://learngitbranching.js.org/?locale=zh_CN) via: [tutorialzine.com](https://tutorialzine.com/2016/06/learn-git-in-30-minutes)
2017年08月10日
35 阅读
0 评论
0 点赞
2017-06-28
Git常用命令
前言Git,是一个开源的分布式版本控制系统,用以有效、高速的处理从很小到非常大的项目版本管理。支持克隆/下载。Git教程: Git Book 官方中文文档Git GUI客户端: TortoiseGit(Windows)Git常用命令仓库# 在当前目录新建一个Git代码库 $ git init # 新建一个目录,将其初始化为Git代码库 $ git init [project-name] # 下载一个项目和它的整个代码历史 $ git clone [url]配置# 显示当前的Git配置 $ git config --list # 编辑Git配置文件 $ git config -e [--global] # 设置提交代码时的用户信息 $ git config [--global] user.name "[name]" $ git config [--global] user.email "[email address]"增加/删除文件# 添加指定文件到暂存区 $ git add [file1] [file2] ... # 添加指定目录到暂存区,包括子目录 $ git add [dir] # 添加当前目录的所有文件到暂存区 $ git add . # 添加每个变化前,都会要求确认 # 对于同一个文件的多处变化,可以实现分次提交 $ git add -p # 删除工作区文件,并且将这次删除放入暂存区 $ git rm [file1] [file2] ... # 停止追踪指定文件,但该文件会保留在工作区 $ git rm --cached [file] # 改名文件,并且将这个改名放入暂存区 $ git mv [file-original] [file-renamed]代码提交# 提交暂存区到仓库区 $ git commit -m [message] # 提交暂存区的指定文件到仓库区 $ git commit [file1] [file2] ... -m [message] # 提交工作区自上次commit之后的变化,直接到仓库区 $ git commit -a # 提交时显示所有diff信息 $ git commit -v # 使用一次新的commit,替代上一次提交 # 如果代码没有任何新变化,则用来改写上一次commit的提交信息 $ git commit --amend -m [message] # 重做上一次commit,并包括指定文件的新变化 $ git commit --amend [file1] [file2] ...分支# 列出所有本地分支 $ git branch # 列出所有远程分支 $ git branch -r # 列出所有本地分支和远程分支 $ git branch -a # 新建一个分支,但依然停留在当前分支 $ git branch [branch-name] # 新建一个分支,并切换到该分支 $ git checkout -b [branch] # 新建一个分支,指向指定commit $ git branch [branch] [commit] # 新建一个分支,与指定的远程分支建立追踪关系 $ git branch --track [branch] [remote-branch] # 切换到指定分支,并更新工作区 $ git checkout [branch-name] # 切换到上一个分支 $ git checkout - # 建立追踪关系,在现有分支与指定的远程分支之间 $ git branch --set-upstream [branch] [remote-branch] # 合并指定分支到当前分支 $ git merge [branch] # 选择一个commit,合并进当前分支 $ git cherry-pick [commit] # 删除分支 $ git branch -d [branch-name] # 删除远程分支 $ git push origin --delete [branch-name] $ git branch -dr [remote/branch]标签# 列出所有tag $ git tag # 新建一个tag在当前commit $ git tag [tag] # 新建一个tag在指定commit $ git tag [tag] [commit] # 删除本地tag $ git tag -d [tag] # 删除远程tag $ git push origin :refs/tags/[tagName] # 查看tag信息 $ git show [tag] # 提交指定tag $ git push [remote] [tag] # 提交所有tag $ git push [remote] --tags # 新建一个分支,指向某个tag $ git checkout -b [branch] [tag]查看信息# 显示有变更的文件 $ git status # 显示当前分支的版本历史 $ git log # 显示commit历史,以及每次commit发生变更的文件 $ git log --stat # 搜索提交历史,根据关键词 $ git log -S [keyword] # 显示某个commit之后的所有变动,每个commit占据一行 $ git log [tag] HEAD --pretty=format:%s # 显示某个commit之后的所有变动,其"提交说明"必须符合搜索条件 $ git log [tag] HEAD --grep feature # 显示某个文件的版本历史,包括文件改名 $ git log --follow [file] $ git whatchanged [file] # 显示指定文件相关的每一次diff $ git log -p [file] # 显示过去5次提交 $ git log -5 --pretty --oneline # 显示所有提交过的用户,按提交次数排序 $ git shortlog -sn # 显示指定文件是什么人在什么时间修改过 $ git blame [file] # 显示暂存区和工作区的差异 $ git diff # 显示暂存区和上一个commit的差异 $ git diff --cached [file] # 显示工作区与当前分支最新commit之间的差异 $ git diff HEAD # 显示两次提交之间的差异 $ git diff [first-branch]...[second-branch] # 显示今天你写了多少行代码 $ git diff --shortstat "@{0 day ago}" # 显示某次提交的元数据和内容变化 $ git show [commit] # 显示某次提交发生变化的文件 $ git show --name-only [commit] # 显示某次提交时,某个文件的内容 $ git show [commit]:[filename] # 显示当前分支的最近几次提交 $ git reflog远程同步# 下载远程仓库的所有变动 $ git fetch [remote] # 显示所有远程仓库 $ git remote -v # 显示某个远程仓库的信息 $ git remote show [remote] # 增加一个新的远程仓库,并命名 $ git remote add [shortname] [url] # 取回远程仓库的变化,并与本地分支合并 $ git pull [remote] [branch] # 上传本地指定分支到远程仓库 $ git push [remote] [branch] # 强行推送当前分支到远程仓库,即使有冲突 $ git push [remote] --force # 推送所有分支到远程仓库 $ git push [remote] --all撤销# 恢复暂存区的指定文件到工作区 $ git checkout [file] # 恢复某个commit的指定文件到暂存区和工作区 $ git checkout [commit] [file] # 恢复暂存区的所有文件到工作区 $ git checkout . # 重置暂存区的指定文件,与上一次commit保持一致,但工作区不变 $ git reset [file] # 重置暂存区与工作区,与上一次commit保持一致 $ git reset --hard # 重置当前分支的指针为指定commit,同时重置暂存区,但工作区不变 $ git reset [commit] # 重置当前分支的HEAD为指定commit,同时重置暂存区和工作区,与指定commit一致 $ git reset --hard [commit] # 重置当前HEAD为指定commit,但保持暂存区和工作区不变 $ git reset --keep [commit] # 新建一个commit,用来撤销指定commit # 后者的所有变化都将被前者抵消,并且应用到当前分支 $ git revert [commit] # 暂时将未提交的变化移除,稍后再移入 $ git stash $ git stash pop其他# 生成一个可供发布的压缩包 $ git archive
2017年06月28日
123 阅读
0 评论
0 点赞
2017-04-23
git命令之git branch系列
1、git branch查看本地当前所在分支,并且在当前分支前面加“*”号标记2、git branch -r查看远程分支,r 是 remote 的简写3、git checkout -b production origin/production取远程分支 并 分化一个新的分支到本地;然后此刻,本地已经切换到了该新分支,执行 git pull ,将代码拉下来,本地才有了完整的对应分支;前提:先查看远程分支情况,执行 git branch -r例子:git checkout -b hotfix_v2003 origin/hotfix_v20034、git branch -a列出本地分支和远程分支5、git branch 分支名创建一个新的本地分支,需要注意,此处只是创建分支,不进行分支切换;git checkout -b 分支名 创建一个新的本地分支,同时切换到刚新建的分支上。6、git branch -m | -M oldbranch newbranch重命名分支,如果newbranch名字已经存在,则需要使用-M强制重命名,否则,使用-m进行重命名。7、git branch -d | -D branchname删除branchname分支,D表示强制删除7.1、git branch -d mybranch删除分支7.2、git branch -D mybranch强制删除分支8、git branch -d -r branchname删除远程 branchname 分支,通知还需要执行 push 命令,才能真正删除:git push origin:branchname补充:如果不执行 push 命令,虽然通过git branch -r已经看不到 branchname 了,但在GitHub的网页上依然能看到branchname,而且执行git fetch命令后,再git branch -r,由可以看到branchname,说明如果不push没有真正删除远程分支。9、git branch -v查看各个分支最后一次提交10、git branch -merged查看哪些分支合并入当前分支11、git branch -no-merged查看哪些分支未合并入当前分支12、git fetch origin更新远程库到本地13、git push origin mybranch推送分支14、git merged origin/mybranch去远程分支合并到本地15、git push origin:mybranch删除远程分支
2017年04月23日
91 阅读
0 评论
0 点赞
2016-06-07
链接应该在新窗口打开吗
从易用性的观点来说,强制在新窗口打开链接,违反了一个用户界面设计的基础原则:应该让用户对他们正在交互的界面有控制权。 一个友好并且实际有效的界面设计,在用户做操作的时候,总是能让他们按自己的意志做出决定。当用户在使用界面元素的时候,他们必须知道、理解、并且能预料到什么将会发生。这才是以用户为中心的设计。 有经验的用户,非常强烈的希望由他们来操控整个系统,系统对他们的行为产生回应。 我自己的浏览习惯是,使用多标签式浏览器,找到要浏览的信息列表页,例如论坛的一个版块,或搜索引擎返回的结果页,然后连续拖拽好几个自己感兴趣的链接让页面在新标签非激活状态打开,然后切换到最选装载完成的标签来查看内容。 强制新窗口打开链接的主要问题是,没有强制新窗口打开的链接用户可以通过右键菜单或按shift键(在一些浏览器里可以是拖拽)这种比较容易的方法来在新窗口打开,而强制在新窗口打开的链接要让用户在本身窗口打开却不容易(可以拖动链接到地址栏来在当前窗口打开链接),所以强制新窗口打开链接,超越了用户自己的决定,剥夺了用户的控制权。 对于浏览网站比较熟练的国内用户来说有几个特点: 1、就算是浏览目的很明确的浏览者,也未必能立即找到完全满足自己需要的信息,搜寻和比较必不可少; 2、目前的网速和国内的网页体积来说,网页很少能够即点即开般在一两秒钟内打开,所以许多人习惯一次点开多个页面,让等待页面加载的时间集中在一起。 3、非常讨厌意料之外的弹出窗口。 我记得在2000年,我刚接触网络的时候,机器配置都比较差,网速却又很慢,一方面我不能打开太多窗口以免占用大多资源让机器反应变慢,另一方面我又不时地打开新窗口,以便同时加载多个页面,选择最先加载完成的页面浏览。 为了比较准确地控制窗口的数量,我希望每个链接都能够由我来控制是在自身窗口打开或是新窗口打开。 我的意见是,谨慎地使用新开窗口,并且新开窗口要给予适当的暗示。一个链接是不是在新窗口打开,尽量交给用户来决定。如果他们想在新窗口打开他们会自己去做,不要低估他们的智力帮他们去做决定什么的。 当你的鼠标移到一个链接上的时候,浏览器并不会提示你是自身窗口打开或是新窗口打开。 1、要么给新窗口打开的链接一种特殊的颜色或图标;采用ICON通知访问者外部链接是一种很常见的做法。使用css属性选择器或javascript都可以实现对链接的筛选、外观修改。 2、大部分链接让用户自己按shift键(在一些浏览器里是拖拽)来决定在新窗口打开链接。 考虑到有一部分刚接触网络的用户,使用浏览器还不熟练,甚至也不知道使用shift键(或拖拽)来新开窗口,所以在一些必需的情况下还是应该强制在新窗口打开链接。 在以下几种情况下,强制在新窗口打开链接是比较合适的: 1、链接指向一个本域名之外的网站:如友情链接一 般使用新窗口,新的网站新的窗口,基本上是可预料的。 2、提供帮助类的链接:如一个购物页面上对支付方式的帮助说明可以新开窗口,如果内容不多的话使用弹出层比新窗口更好。 3、页面跳转有可能打断一个正在进行的进程:如在注册页面上指向免责条款、版权声明等页面的链接,页面跳转会导致用户正在填写的注册信息丢失。 4、链接指向一个非HTML文件。例如指向一个pdf文件的链接最好使用新窗口,也许这个pdf会在新窗口直接浏览,也许会弹出文件下载对话框。
2016年06月07日
143 阅读
0 评论
0 点赞
2016-06-07
IE6/7下的console.log()
相信很多人和我一样,在firefox下常常用console.log()输出一些对象或变量的值,在ie6/7里常常用alert()弹出一些对象或变量的值,来作调试。有时候忘记了删除console.log()语句(或alert语句),结果在ie6/7(或没有开启firebug控制台的firefox下也会)下弹出了错误信息。 我常常在自己的common.js里加入以下代码来容错:if(!window.console){ window.console={} window.console.log=function(){return;} } 当然,能够在ie下使用console.log的调试功能当然是最好的,哪怕只是最简单的一个变量值的输出也比alert友好一些,于是有了下面这个简易版的console.log<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>ie下的console.log</title> <style> body {background: #ffffff; color: #444;} a{ color: #08e; text-decoration: none; border: 0; background-color: transparent;} body,div,q,iframe,form,h5{ margin: 0; padding: 0;} a img,fieldset { border: none 0; } body,td,textarea { word-break: break-all; word-wrap: break-word; line-height:1.5;} body,input,textarea,select,button { margin: 0; font-size: 12px; font-family: Tahoma, SimSun, sans-serif;} div,p,table,th,td { font-size:1em; font-family:inherit; line-height:inherit;} </style> <script type="text/javascript"> var debug=true; var $id = function (id) {//避免与jQuery的$函数冲突 return typeof id == "string" ? document.getElementById(id) : id; }; if(!$){var $=$id;} if(!window.console){ window.console={} window.console.cache=[]; window.console.constr=function(_value){ if(!_value)return; var result = []; if (_value instanceof Function){ result.push(_value); }else if(_value!=undefined&&Boolean(_value.nodeName)&&Boolean(_value.nodeType)){ result.push(_value.nodeName.toLowerCase()); result.push(_value.getAttribute("id")?"id="+_value.getAttribute("id"):""); result.push(_value.getAttribute("className")?"class="+_value.getAttribute("className"):""); return "<"+result.join(" ")+">"; }else if(_value instanceof Array){ for(var i=0; i< _value.length; i++) result.push(_value[i]); return "["+result.join(", ")+"]"; }else if(typeof _value == "object"){ for (var p in _value){ if(_value.hasOwnProperty(p) && p!='prototype'){ result.push("'"+p+"':"+_value[p]); } }; return "{"+result.join(", ")+"}"; }else if(typeof _value == 'string'){ return "\""+_value+"\""; }else if(typeof _value == 'number' && isFinite(_value)){ result.push(_value); }else{ result.push(_value); } return result.join(""); } window.console.log=function(outputValue){ if(!debug)return; if(!outputValue)return null; var bgColor=bgColor||"#fff"; consoleDiv =$id("_console"); if(!consoleDiv){ consoleDiv=document.createElement("div"); consoleDiv.id="_console"; consoleDiv.style.cssText="position:absolute; z-index:9999; left:0%;top:"+Math.max(document.documentElement.scrollTop, document.body.scrollTop)+"px; width:62%; background-color:#fff; border:1px solid #359; opacity:0.9; filter:alpha(opacity=90); padding:4px;" consoleDiv.innerHTML='<div id="_consoleHead" style="background-color:#cde; height:20px; color:#000; font-size:12px; line-height:20px; cursor:move;"><a style="color:#123; float:right; text-decoration:none; margin:1px 2px 0;" href="javascript:$id(\'_console\').style.display=\'none\';void(0);">[关闭]</a><a style="color:#123; float:right; text-decoration:none; margin:1px 2px 0;" href="javascript:$id(\'_consoleBody\').innerHTML=\'\';void(0);">[清空]</a></div>'; consoleDivBody=document.createElement("div"); consoleDivBody.id="_consoleBody"; consoleDivBody.style.cssText="font-size:12px; line-height:1.5;color:#333; width:100%; max-height:150px; overflow:auto;" consoleDivBody.innerHTML=''; consoleDiv.appendChild(consoleDivBody); document.getElementsByTagName("BODY")[0].appendChild(consoleDiv); if(Drag) Drag.init(consoleDiv,consoleDiv);//注册拖拽方法,可以使用自己的拖拽方法来代替,以减少代码量 } consoleDiv.style.display=""; var consoleDivTop=consoleDiv.style.top.replace(/\D/gi,""); if(consoleDivTop<Math.max(document.documentElement.scrollTop, document.body.scrollTop)||consoleDivTop>Math.max(document.documentElement.scrollTop, document.body.scrollTop)+(document.compatMode == "BackCompat"?document.body.clientHeight:document.documentElement.clientHeight)) consoleDiv.style.top=Math.max(document.documentElement.scrollTop, document.body.scrollTop)+"px"; var newItem=document.createElement("div"); newItem.style.cssText="border-top:1px solid #cde; padding:3px;font-family:'Courier New'; font-size:13px; background-color:"+bgColor; var content = []; for(var i=0, len=arguments.length; i<len; i++){ content.push( window.console.constr(arguments[i]) ); } newItem.innerHTML= content.join(" "); $id("_consoleBody").appendChild(newItem); $id("_consoleBody").scrollTop=9999; }; } /***小巧的拖拽类***/ var Drag={ "obj":null, "init":function(handle, dragBody, e){ if (e == null) { handle.onmousedown=Drag.start; } handle.root = dragBody; if(isNaN(parseInt(handle.root.style.left)))handle.root.style.left="0px"; if(isNaN(parseInt(handle.root.style.top)))handle.root.style.top="0px"; handle.root.onDragStart=new Function(); handle.root.onDragEnd=new Function(); handle.root.onDrag=new Function(); if (e !=null) { var handle=Drag.obj=handle; e=Drag.fixe(e); var top=parseInt(handle.root.style.top); var left=parseInt(handle.root.style.left); handle.root.onDragStart(left,top,e.pageX,e.pageY); handle.lastMouseX=e.pageX; handle.lastMouseY=e.pageY; document.onmousemove=Drag.drag; document.onmouseup=Drag.end; } }, "start":function(e){ var handle=Drag.obj=this; e=Drag.fixEvent(e); var top=parseInt(handle.root.style.top); var left=parseInt(handle.root.style.left); //alert(left) handle.root.onDragStart(left,top,e.pageX,e.pageY); handle.lastMouseX=e.pageX; handle.lastMouseY=e.pageY; document.onmousemove=Drag.drag; document.onmouseup=Drag.end; return false; }, "drag":function(e){ e=Drag.fixEvent(e); var handle=Drag.obj; var mouseY=e.pageY; var mouseX=e.pageX; var top=parseInt(handle.root.style.top); var left=parseInt(handle.root.style.left); if(document.all){Drag.obj.setCapture();}else{e.preventDefault();};//作用是将所有鼠标事件捕获到handle对象,对于firefox,以用preventDefault来取消事件的默认动作: var currentLeft,currentTop; currentLeft=left+mouseX-handle.lastMouseX; currentTop=top+(mouseY-handle.lastMouseY); handle.root.style.left=currentLeft +"px"; handle.root.style.top=currentTop+"px"; handle.lastMouseX=mouseX; handle.lastMouseY=mouseY; handle.root.onDrag(currentLeft,currentTop,e.pageX,e.pageY); return false; }, "end":function(){ if(document.all){Drag.obj.releaseCapture();};//取消所有鼠标事件捕获到handle对象 document.onmousemove=null; document.onmouseup=null; Drag.obj.root.onDragEnd(parseInt(Drag.obj.root.style.left),parseInt(Drag.obj.root.style.top)); Drag.obj=null; }, "fixEvent":function(e){//格式化事件参数对象 var sl = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft); var st = Math.max(document.documentElement.scrollTop, document.body.scrollTop); if(typeof e=="undefined")e=window.event; if(typeof e.layerX=="undefined")e.layerX=e.offsetX; if(typeof e.layerY=="undefined")e.layerY=e.offsetY; if(typeof e.pageX == "undefined")e.pageX = e.clientX + sl - document.body.clientLeft; if(typeof e.pageY == "undefined")e.pageY = e.clientY + st - document.body.clientTop; return e; } }; /***测试***/ function sometext(ele,n){ var strArr=["可","以","清","心","也"]; var writeStr="" for(i=0;i<n;i++){ index=parseInt(Math.random()*5); for(j=0;j<5;j++){ str=index+j>4?index+j-5:index+j; writeStr+=strArr[str]; } } $(ele).innerHTML=writeStr; } function test1(){ console.log("这是一个js对象:",{w:100,h:50,area:function(){return this.w*this.h}}) } function test2(){ console.log("这是一个dom对象:",$id("div1")) } function test3(){ var arr=function(w,h){return w*h;} console.log("这是一个js函数:",arr) } function test4(){ var arr=[1,2.2,"a","abc",true,false,new Date(),/<[^>]*>/,function(){alert(0);}] console.log("这是一个数组:",arr) } </script> </head> <body> <div id="div1" class="style1"></div> <p><input type="button" value="返回一个object" onclick="test1()" /> <input type="button" value="返回一个element" onclick="test2()" /> <input type="button" value="返回一个function" onclick="test3()" /> <input type="button" value="返回一个arrary" onclick="test4()" /> </p> <div id="div2" class="style1"></div> <script>sometext("div1",200);sometext("div2",200);</script> </body> </html>如果不要自带的drag方法(大家的js库里一般都有自己的drag方法吧)的话,代码大约60行,方便调试,也不会让你的js库变得臃肿。
2016年06月07日
53 阅读
0 评论
0 点赞
2016-05-29
Web前端常用的JavaScript方法封装
1、输入一个值,返回其数据类型function type(para) { return Object.prototype.toString.call(para) }2、数组去重function unique1(arr) { return [...new Set(arr)] } function unique2(arr) { var obj = {}; return arr.filter(ele => { if (!obj[ele]) { obj[ele] = true; return true; } }) } function unique3(arr) { var result = []; arr.forEach(ele => { if (result.indexOf(ele) == -1) { result.push(ele) } }) return result; }3、字符串去重String.prototype.unique = function () { var obj = {}, str = '', len = this.length; for (var i = 0; i < len; i++) { if (!obj[this[i]]) { str += this[i]; obj[this[i]] = true; } } return str; } //去除连续的字符串 function uniq(str) { return str.replace(/(\w)\1+/g, '$1') }4、深拷贝 浅拷贝//深克隆(深克隆不考虑函数) function deepClone(obj, result) { var result = result || {}; for (var prop in obj) { if (obj.hasOwnProperty(prop)) { if (typeof obj[prop] == 'object' && obj[prop] !== null) { // 引用值(obj/array)且不为null if (Object.prototype.toString.call(obj[prop]) == '[object Object]') { // 对象 result[prop] = {}; } else { // 数组 result[prop] = []; } deepClone(obj[prop], result[prop]) } else { // 原始值或func result[prop] = obj[prop] } } } return result; } // 深浅克隆是针对引用值 function deepClone(target) { if (typeof (target) !== 'object') { return target; } var result; if (Object.prototype.toString.call(target) == '[object Array]') { // 数组 result = [] } else { // 对象 result = {}; } for (var prop in target) { if (target.hasOwnProperty(prop)) { result[prop] = deepClone(target[prop]) } } return result; } // 无法复制函数 var o1 = jsON.parse(jsON.stringify(obj1));5、reverse底层原理和扩展// 改变原数组 Array.prototype.myReverse = function () { var len = this.length; for (var i = 0; i < len; i++) { var temp = this[i]; this[i] = this[len - 1 - i]; this[len - 1 - i] = temp; } return this; }6、圣杯模式的继承function inherit(Target, Origin) { function F() {}; F.prototype = Origin.prototype; Target.prototype = new F(); Target.prototype.constructor = Target; // 最终的原型指向 Target.prop.uber = Origin.prototype; }7、找出字符串中第一次只出现一次的字母String.prototype.firstAppear = function () { var obj = {}, len = this.length; for (var i = 0; i < len; i++) { if (obj[this[i]]) { obj[this[i]]++; } else { obj[this[i]] = 1; } } for (var prop in obj) { if (obj[prop] == 1) { return prop; } } }8、找元素的第n级父元素function parents(ele, n) { while (ele && n) { ele = ele.parentElement ? ele.parentElement : ele.parentNode; n--; } return ele; }9、返回元素的第n个兄弟节点function retSibling(e, n) { while (e && n) { if (n > 0) { if (e.nextElementSibling) { e = e.nextElementSibling; } else { for (e = e.nextSibling; e && e.nodeType !== 1; e = e.nextSibling); } n--; } else { if (e.previousElementSibling) { e = e.previousElementSibling; } else { for (e = e.previousElementSibling; e && e.nodeType !== 1; e = e.previousElementSibling); } n++; } } return e; }10、封装mychildren,解决浏览器的兼容问题function myChildren(e) { var children = e.childNodes, arr = [], len = children.length; for (var i = 0; i < len; i++) { if (children[i].nodeType === 1) { arr.push(children[i]) } } return arr; }11、判断元素有没有子元素function hasChildren(e) { var children = e.childNodes, len = children.length; for (var i = 0; i < len; i++) { if (children[i].nodeType === 1) { return true; } } return false; }12、我一个元素插入到另一个元素的后面Element.prototype.insertAfter = function (target, elen) { var nextElen = elen.nextElenmentSibling; if (nextElen == null) { this.appendChild(target); } else { this.insertBefore(target, nextElen); } }13、返回当前的时间(年月日时分秒)function getDateTime() { var date = new Date(), year = date.getFullYear(), month = date.getMonth() + 1, day = date.getDate(), hour = date.getHours() + 1, minute = date.getMinutes(), second = date.getSeconds(); month = checkTime(month); day = checkTime(day); hour = checkTime(hour); minute = checkTime(minute); second = checkTime(second); function checkTime(i) { if (i < 10) { i = "0" + i; } return i; } return "" + year + "年" + month + "月" + day + "日" + hour + "时" + minute + "分" + second + "秒" }14、获得滚动条的滚动距离function getScrollOffset() { if (window.pageXOffset) { return { x: window.pageXOffset, y: window.pageYOffset } } else { return { x: document.body.scrollLeft + document.documentElement.scrollLeft, y: document.body.scrollTop + document.documentElement.scrollTop } } }15、获得视口的尺寸function getViewportOffset() { if (window.innerWidth) { return { w: window.innerWidth, h: window.innerHeight } } else { // ie8及其以下 if (document.compatMode === "BackCompat") { // 怪异模式 return { w: document.body.clientWidth, h: document.body.clientHeight } } else { // 标准模式 return { w: document.documentElement.clientWidth, h: document.documentElement.clientHeight } } } }16、获取任一元素的任意属性function getStyle(elem, prop) { return window.getComputedStyle ? window.getComputedStyle(elem, null)[prop] : elem.currentStyle[prop] }17、绑定事件的兼容代码function addEvent(elem, type, handle) { if (elem.addEventListener) { //非ie和非ie9 elem.addEventListener(type, handle, false); } else if (elem.attachEvent) { //ie6到ie8 elem.attachEvent('on' + type, function () { handle.call(elem); }) } else { elem['on' + type] = handle; } }18、解绑事件function removeEvent(elem, type, handle) { if (elem.removeEventListener) { //非ie和非ie9 elem.removeEventListener(type, handle, false); } else if (elem.detachEvent) { //ie6到ie8 elem.detachEvent('on' + type, handle); } else { elem['on' + type] = null; } }19、取消冒泡的兼容代码function stopBubble(e) { if (e && e.stopPropagation) { e.stopPropagation(); } else { window.event.cancelBubble = true; } }20、检验字符串是否是回文function isPalina(str) { if (Object.prototype.toString.call(str) !== '[object String]') { return false; } var len = str.length; for (var i = 0; i < len / 2; i++) { if (str[i] != str[len - 1 - i]) { return false; } } return true; }21、检验字符串是否是回文function isPalindrome(str) { str = str.replace(/\W/g, '').toLowerCase(); console.log(str) return (str == str.split('').reverse().join('')) }22、兼容getElementsByClassName方法Element.prototype.getElementsByClassName = Document.prototype.getElementsByClassName = function (_className) { var allDomArray = document.getElementsByTagName('*'); var lastDomArray = []; function trimSpace(strClass) { var reg = /\s+/g; return strClass.replace(reg, ' ').trim() } for (var i = 0; i < allDomArray.length; i++) { var classArray = trimSpace(allDomArray[i].className).split(' '); for (var j = 0; j < classArray.length; j++) { if (classArray[j] == _className) { lastDomArray.push(allDomArray[i]); break; } } } return lastDomArray; }23、运动函数function animate(obj, json, callback) { clearInterval(obj.timer); var speed, current; obj.timer = setInterval(function () { var lock = true; for (var prop in json) { if (prop == 'opacity') { current = parseFloat(window.getComputedStyle(obj, null)[prop]) * 100; } else { current = parseInt(window.getComputedStyle(obj, null)[prop]); } speed = (json[prop] - current) / 7; speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); if (prop == 'opacity') { obj.style[prop] = (current + speed) / 100; } else { obj.style[prop] = current + speed + 'px'; } if (current != json[prop]) { lock = false; } } if (lock) { clearInterval(obj.timer); typeof callback == 'function' ? callback() : ''; } }, 30) }24、弹性运动function ElasticMovement(obj, target) { clearInterval(obj.timer); var iSpeed = 40, a, u = 0.8; obj.timer = setInterval(function () { a = (target - obj.offsetLeft) / 8; iSpeed = iSpeed + a; iSpeed = iSpeed * u; if (Math.abs(iSpeed) <= 1 && Math.abs(a) <= 1) { console.log('over') clearInterval(obj.timer); obj.style.left = target + 'px'; } else { obj.style.left = obj.offsetLeft + iSpeed + 'px'; } }, 30); }25、封装自己的forEach方法Array.prototype.myForEach = function (func, obj) { var len = this.length; var _this = arguments[1] ? arguments[1] : window; // var _this=arguments[1]||window; for (var i = 0; i < len; i++) { func.call(_this, this[i], i, this) } }26、封装自己的filter方法Array.prototype.myFilter = function (func, obj) { var len = this.length; var arr = []; var _this = arguments[1] || window; for (var i = 0; i < len; i++) { func.call(_this, this[i], i, this) && arr.push(this[i]); } return arr; }27、数组map方法Array.prototype.myMap = function (func) { var arr = []; var len = this.length; var _this = arguments[1] || window; for (var i = 0; i < len; i++) { arr.push(func.call(_this, this[i], i, this)); } return arr; }28、数组every方法Array.prototype.myEvery = function (func) { var flag = true; var len = this.length; var _this = arguments[1] || window; for (var i = 0; i < len; i++) { if (func.apply(_this, [this[i], i, this]) == false) { flag = false; break; } } return flag; }29、数组reduce方法Array.prototype.myReduce = function (func, initialValue) { var len = this.length, nextValue, i; if (!initialValue) { // 没有传第二个参数 nextValue = this[0]; i = 1; } else { // 传了第二个参数 nextValue = initialValue; i = 0; } for (; i < len; i++) { nextValue = func(nextValue, this[i], i, this); } return nextValue; }30、获取url中的参数function getWindonHref() { var sHref = window.location.href; var args = sHref.split('?'); if (args[0] === sHref) { return ''; } var hrefarr = args[1].split('#')[0].split('&'); var obj = {}; for (var i = 0; i < hrefarr.length; i++) { hrefarr[i] = hrefarr[i].split('='); obj[hrefarr[i][0]] = hrefarr[i][1]; } return obj; }31、数组排序// 快排 [left] + min + [right] function quickArr(arr) { if (arr.length <= 1) { return arr; } var left = [], right = []; var pIndex = Math.floor(arr.length / 2); var p = arr.splice(pIndex, 1)[0]; for (var i = 0; i < arr.length; i++) { if (arr[i] <= p) { left.push(arr[i]); } else { right.push(arr[i]); } } // 递归 return quickArr(left).concat([p], quickArr(right)); } // 冒泡 function bubbleSort(arr) { for (var i = 0; i < arr.length - 1; i++) { for (var j = i + 1; j < arr.length; j++) { if (arr[i] > arr[j]) { var temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } return arr; } function bubbleSort(arr) { var len = arr.length; for (var i = 0; i < len - 1; i++) { for (var j = 0; j < len - 1 - i; j++) { if (arr[j] > arr[j + 1]) { var temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } return arr; }32、遍历Dom树// 给定页面上的DOM元素,将访问元素本身及其所有后代(不仅仅是它的直接子元素) // 对于每个访问的元素,函数讲元素传递给提供的回调函数 function traverse(element, callback) { callback(element); var list = element.children; for (var i = 0; i < list.length; i++) { traverse(list[i], callback); } }33、原生js封装ajaxfunction ajax(method, url, callback, data, flag) { var xhr; flag = flag || true; method = method.toUpperCase(); if (window.XMLHttpRequest) { xhr = new XMLHttpRequest(); } else { xhr = new ActiveXObject('Microsoft.XMLHttp'); } xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { console.log(2) callback(xhr.responseText); } } if (method == 'GET') { var date = new Date(), timer = date.getTime(); xhr.open('GET', url + '?' + data + '&timer' + timer, flag); xhr.send() } else if (method == 'POST') { xhr.open('POST', url, flag); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.send(data); } }34、异步加载scriptfunction loadScript(url, callback) { var oscript = document.createElement('script'); if (oscript.readyState) { // ie8及以下版本 oscript.onreadystatechange = function () { if (oscript.readyState === 'complete' || oscript.readyState === 'loaded') { callback(); } } } else { oscript.onload = function () { callback() }; } oscript.src = url; document.body.appendChild(oscript); }35、cookie管理var cookie = { set: function (name, value, time) { document.cookie = name + '=' + value + '; max-age=' + time; return this; }, remove: function (name) { return this.setCookie(name, '', -1); }, get: function (name, callback) { var allCookieArr = document.cookie.split('; '); for (var i = 0; i < allCookieArr.length; i++) { var itemCookieArr = allCookieArr[i].split('='); if (itemCookieArr[0] === name) { return itemCookieArr[1] } } return undefined; } }36、实现bind()方法Function.prototype.myBind = function (target) { var target = target || window; var _args1 = [].slice.call(arguments, 1); var self = this; var temp = function () {}; var F = function () { var _args2 = [].slice.call(arguments, 0); var parasArr = _args1.concat(_args2); return self.apply(this instanceof temp ? this : target, parasArr) } temp.prototype = self.prototype; F.prototype = new temp(); return F; }37、实现call()方法Function.prototype.myCall = function () { var ctx = arguments[0] || window; ctx.fn = this; var args = []; for (var i = 1; i < arguments.length; i++) { args.push(arguments[i]) } var result = ctx.fn(...args); delete ctx.fn; return result; }38、实现apply()方法Function.prototype.myApply = function () { var ctx = arguments[0] || window; ctx.fn = this; if (!arguments[1]) { var result = ctx.fn(); delete ctx.fn; return result; } var result = ctx.fn(...arguments[1]); delete ctx.fn; return result; }39、防抖function debounce(handle, delay) { var timer = null; return function () { var _self = this, _args = arguments; clearTimeout(timer); timer = setTimeout(function () { handle.apply(_self, _args) }, delay) } }40、节流function throttle(handler, wait) { var lastTime = 0; return function (e) { var nowTime = new Date().getTime(); if (nowTime - lastTime > wait) { handler.apply(this, arguments); lastTime = nowTime; } } }41、requestAnimFrame兼容性方法window.requestAnimFrame = (function () { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) { window.setTimeout(callback, 1000 / 60); }; })();42、cancelAnimFrame兼容性方法window.cancelAnimFrame = (function () { return window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || function (id) { window.clearTimeout(id); }; })();43、jsonp底层方法function jsonp(url, callback) { var oscript = document.createElement('script'); if (oscript.readyState) { // ie8及以下版本 oscript.onreadystatechange = function () { if (oscript.readyState === 'complete' || oscript.readyState === 'loaded') { callback(); } } } else { oscript.onload = function () { callback() }; } oscript.src = url; document.body.appendChild(oscript); }44、获取url上的参数function getUrlParam(sUrl, sKey) { var result = {}; sUrl.replace(/(\w+)=(\w+)(?=[&|#])/g, function (ele, key, val) { if (!result[key]) { result[key] = val; } else { var temp = result[key]; result[key] = [].concat(temp, val); } }) if (!sKey) { return result; } else { return result[sKey] || ''; } }45、格式化时间function formatDate(t, str) { var obj = { yyyy: t.getFullYear(), yy: ("" + t.getFullYear()).slice(-2), M: t.getMonth() + 1, MM: ("0" + (t.getMonth() + 1)).slice(-2), d: t.getDate(), dd: ("0" + t.getDate()).slice(-2), H: t.getHours(), HH: ("0" + t.getHours()).slice(-2), h: t.getHours() % 12, hh: ("0" + t.getHours() % 12).slice(-2), m: t.getMinutes(), mm: ("0" + t.getMinutes()).slice(-2), s: t.getSeconds(), ss: ("0" + t.getSeconds()).slice(-2), w: ['日', '一', '二', '三', '四', '五', '六'][t.getDay()] }; return str.replace(/([a-z]+)/ig, function ($1) { return obj[$1] }); }46、验证邮箱的正则表达式function isAvailableEmail(sEmail) { var reg = /^([\w+\.])+@\w+([.]\w+)+$/ return reg.test(sEmail) }47、函数柯里化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术function curryIt(fn) { var length = fn.length, args = []; var result = function (arg) { args.push(arg); length--; if (length <= 0) { return fn.apply(this, args); } else { return result; } } return result; }48、大数相加function sumBigNumber(a, b) { var res = '', //结果 temp = 0; //按位加的结果及进位 a = a.split(''); b = b.split(''); while (a.length || b.length || temp) { //~~按位非 1.类型转换,转换成数字 2.~~undefined==0 temp += ~~a.pop() + ~~b.pop(); res = (temp % 10) + res; temp = temp > 9; } return res.replace(/^0+/, ''); }49、单例模式function getSingle(func) { var result; return function () { if (!result) { result = new func(arguments); } return result; } }50、前端随机字符串var uuid = Date.now().toString(36) + Math.random().toString(36).substr(4)51、检测浏览器是否支持transformlet isSuportsTransform = false; (function () { if (typeof CSS === 'object' && typeof CSS.supports === 'function') { isSuportsTransform = CSS.supports('transform:scale(1.2)'); } else if('transform' in document.body.style){ isSuportsTransform = true } })();52、获取当前js文件的路径 var getCurrentScript = function (base) { if (document.currentScript) { return document.currentScript.src // FF,Chrome } var stack try { a.b.c() // 强制报错,以便捕获e.stack } catch (e) { // safari的错误对象只有line,sourceId,sourceURL stack = e.stack if (!stack && window.opera) { // opera 9没有e.stack,但有e.Backtrace,但不能直接取得,需要对e对象转字符串进行抽取 stack = (String(e).match(/of linked script \S+/g) || []).join(' ') } } if (stack) { stack = stack.split(/[@ ]/g).pop() // 取得最后一行,最后一个空格或@之后的部分 stack = stack[0] === '(' ? stack.slice(1, -1) : stack.replace(/\s/, '') // 去掉换行符 return stack.replace(/(:\d+)?:\d+$/i, '') // 去掉行号与或许存在的出错字符起始位置 } var nodes = (base ? document : head).getElementsByTagName('script') // 只在head标签中寻找 for (var i = nodes.length, node; (node = nodes[--i]);) { if (node.readyState === 'interactive') { return node.src } } var node = nodes[nodes.length - 1] return node.hasAttribute ? node.src : node.getAttribute('src', 4) } var jsPath = getCurrentScript(true) var cssPath = jsPath.substr(0, jsPath.lastIndexOf('/')) + '/xxxx.css' // 获取同目录的css文件
2016年05月29日
14 阅读
0 评论
0 点赞
2016-05-09
产品经理-常用工具
产品经理一定要有敏锐的市场洞察力,而敏锐的洞察力一方面来源于直觉和经验,更重要的则是来源于市场调查和数据分析。所以在这里可以看到使用Excel进行最基本的数据分析和图表分析是必备技能,如果需要对数据进行多个维度的分析和分类汇总,则数据透视图是必须要使用的功能。 对于产品方案,技术建议书,产品规划报告,产品需求说明书等体现形式仍然是Word文档格式居多。因此Word的使用又是通用技能,包括最常用的模板使用 和排版,表格的设计,格式的调整等。当这些内容都上升到组织级Word模板后其实很多问题就简单化了,剩下的重点仍然是文档结构的组织和思维。 对于产品方案介绍往往又需要经常去给客户演示,因此PPT的使用又是必备的技能。产品经理需要形成一套适合自己使用的模板库,配色标准等。剩下的问题仍然是结构化思维,静态呈现和动态呈现的问题。演进的好坏,PPT制作的好坏直接影响到是否都打动客户。 很多产品经理没有认识到这些办公软件的重要性,很多文档化的工作,数据的整理和分析不可能完全交给他人来做,因此产品经理就需要随时关注这些通用技能,否则很多时间都将浪费在这些工具的使用上,浪费在重复上,而这些时间完全应该节约出来用到结构化思维上面。 对于产品经理而言最重要的就是随时的理清思维和细化构思,因此对于理清静态思维借我们说的搞清楚事物的组成结构和分解事物,最常用的工具当然是 MindManager思维导图。而对于动态思维,如在业务流程分析,产品需求,用户需求中都大量的涉及到流程和阶段发展等概念。因此对于流程图制作软件 如Visio的使用又是我们必备的技能。对于Visio很多模板都讲经常用到,如流程图制作特别是带职能带的标准化流程图,数据模型(E-R)图,部署 图,架构图,组成结构图等。这些图都适合使用Visio来完成。 产品经理一个重要职能就是要通过市场调研和分析,加上对客户群的分析和技术发展的预测,来考虑产品的构思,而产品的构思是需要快速的原型展现。因此对于不 同的行业都需要熟练的使用快速的原型展现工具。在IT开发中也有很多原型开发工具,如DreamWeaver,Visual Studio.net IDE等都可以快速的开发原型。或者使用专门的原型工具,如Axure RP等。在现阶段我们更加强调的是快速的原型开发,而且最好能够开发高仿真的原型。有这种原型是和客户间进行沟通和需求确认最好的方法。 对于个人时间管理方面最重要的就是凡事有记录,凡事有计划。这里有两个比较好的组合,一个是电子日记本Ediary+Google日历+Gmail就完全 够用了,这个可以在网上免费下载到。另外一个是Outlook+OneNote的组合,这个也是网上很多人推荐的组合。在这里最重要的还是电子日记本,体 现每天事情都有记录,首先要成记录的习惯。 为什么要掌握一种工具,这里我的一个重要理解就是由于没有借助工具,我们在一些事情上浪费了大量的时间。而这些时间本应该是节约出来进行思考用的。 产品经理本身也可以理解为大的项目经理,因此做产品规划和版本计划的工作是少不了的,因此项目管理工具的使用仍然是必须要掌握的工具,如微软的Project,通过Project要能够安排出详细的进度计划和资源计划,同时进行任务的跟踪和监控。{lamp/}替代project的软件:GanttProject项目管理工具:dotProject、 http://www.kingrein.com/cn/h-col-155.html原型工具:Axure产品经理的计划管理工具:GOOGLE日历、Project、Todolist 均可以产品经理的思考工具:Mindmanager 或者 txt产品经理的流程工具:Visio产品经理对于Office的使用频率会很高,特别提醒,一个优秀的产品经理,写汇报材料的能力会很强。
2016年05月09日
33 阅读
0 评论
0 点赞
2016-05-07
前端工作中保证设计质量的规范
对设计质量的保证设计前先讨论,确定一下布局、风格、颜色设计稿中需要设计出鼠标交互的各种状态,可标明在页面空白处或者设置为隐藏图层等等,提升网站的用户体验。如:导航的当前点击状态、焦点图切换、链接文字和图片、按钮、Tab切换、表单和表格的交互、弹出层、浮动层等等。网站各页面布局、风格要保持一致且清晰美观,字体的大小、颜色要相同,禁止出现模糊、虚边、锯齿等细节问题。设计后发给客户前要给设计总监看一下根据客户的修改意见作出的后续修改,给客户发修改稿时,邮件抄送给设计总监前端制作前,和设计确认页面上的下拉菜单、翻转按钮等的效果,确认焦点图、tab页签等交互的表现方式页面中有特殊字体或者大于16px的常规字体(内容标题除外),需制作人员切为图片。前端切片后,模板置标前要让设计师确认一下是否和设计稿一致,设计师审核后方可继续下一工作。布署在外网上,填充了模拟数据之后要设计确认一下是否同设计预期。
2016年05月07日
49 阅读
0 评论
0 点赞
2013-04-07
JIS与湖南CA整合经验分享
一、背景说明湖南省政府互动(JCAT)及相关应用(JCMS, TRSWCM等应用也有可能会进行整合)后期准备使用JIS统一登录入口,省政府目前使用的内容管理平台(TRSWCM)为安全着想,已全部采用CA登录的形式进行后台管理,本次整合主要是针对各部门原有的证书在本系统继续正常使用。经过清明节两天假期时间对CA及JIS的学习和程序修改以及n次拷贝和n次重启tomcat不断及坚持不懈的调试,今天终于把省政府这边的JIS跟湖南CA一块整合成功了.在此先感谢韩洋的指导。怕隔夜以后就没那么清晰 ,所以趁现在还清楚就先跟大家分享一下。二、实现思路在login.jsp中新增代码获取CA登录的开关,如果该开关为开状态则进行CA登录验证,如果为关状态则继续原有的登录。修改merp_pub_user用户信息表,在该表中使用现有的vc_cardid字段存储CA编号信息,新增c_caname字段(CA证书绑定的用户姓名),c_caBandTime(存储绑定操作的系统时间),c_capwdStr(用于CA绑定时存储用户的明文密码,系统在登录时将密码的明文存储在了session中,而且在系统中发现在不少应用跳转时用到了,所以这里也就直接存储明文,便于跟系统原有登录相对接)新增一个有关CA登录操作相关的类,在该方法中书写CA登录相关实现方法.新增ca_login.jsp页面,在该页面中新增CA登录相关功能实现,原有的系统登录功能不变.新增ca/ca_rem.jsp页面,该页面根据CA编号删除CA与系统的绑定关系.三、相关代码CALogin.java /** * 根据CA编号判断是否有用户存在 * @param caId CA编号 * @return 如果该编号存在则返回true,否则返回false */ public static boolean chkUserByCaId(String caId) /*** * * 根据用户名和CA编号将CA编号绑定到用户信息中 * @param loginId 用户登录名称 * @param caId CA编号 * @param strCAUserName CA证书中的用户姓名 * @param c_capwdStr 用户密码,第一次绑定时记录用户密码,在不少场合需要用到明文密码,故单独存储起来. * @return 是否绑定成功,绑定成功返回true,否则返回false */ public static boolean updUserByCaId(String loginId,String caId,String strCAUserName,String c_capwdStr) /** * 根据CA编号获取用户基本信息 * @param caId CA编号 * @return 用户基本信息 */ public static String[][] getUserInfoByCaId(String caId) /*** * 通过CA编号取消掉CA跟统一登录的绑定关系. * @param caId * @return 节次关系是否成功 */ public static boolean removeCaRelationByCaId(String caId)## ca_login.jsp//CA证书相关数据获取 Cookie[] cookies = request.getCookies(); if(cookies == null) cookies = new Cookie[0]; String name = ""; String CA_NO = "";//CA编号 String ca_LoginId="";//JIS系统用户名 String ca_userPwd="";//JIS系统登录密码_明文 boolean bandResult = false;//绑定结果 boolean loginByCA =false;//判断用户进行CA绑定时,将CA编号跟账号绑定 boolean isLoginByForm = false;//是否是提交表单访问本页面,主要用于JS判断,避免二次绑定提示对话框 int nResult=0; for(int i = 0; i < cookies.length; i ++) { Cookie cookie = cookies[i]; if("KOAL_CERT_SERIAL_NUMBER".equals(cookie.getName())) CA_NO = cookie.getValue(); else continue; } if(CALogin.chkUserByCaId(CA_NO)){ //后台存在用户,则获取用户相关信息并登录 String[][] userInfo = CALogin.getUserInfoByCaId(CA_NO); if(userInfo!=null){ ca_LoginId = userInfo[0][1]; ca_userPwd = userInfo[0][2]; loginByCA=true; } } //修改获取用户名密码的方式,如果不是从表单中提交的则获取CA中的用户名和密码信息 String strUser = Convert.getParameter(request, "userid",ca_LoginId,true,true); String strPassword = Convert.getParameter(request, "userpassword",ca_userPwd); //如果不是使用CA直接登录的,则进行CA跟系统用户的绑定 if(loginByCA==false){ bandResult = CALogin.updUserByCaId(strUser,CA_NO,strCAUserName,strPassword); } //JS相关判断及提示. var JS_CA_NO = "<%=CA_NO%>"; if("<%=isCa%>"=="false"){ var turnURL = ""; if(window.location.href.indexOf("59.231.1")>0){ turnURL = "http://59.231.1.222/jis/"; }else{ turnURL = "http://act.hunan.gov.cn/jis/"; } window.location.href=turnURL+"login.jsp"; } if(JS_CA_NO==""){ alert(" \n 请插入证书并数据正确的CA密码登录 \n "); var turnURL = "https://113.240.233.86:452/jis/"; if(window.location.href.indexOf("59.231.1")>0){ turnURL = "https://59.231.1.100:452/jis/"; }else{ turnURL = "https://113.240.233.86:452/jis/"; } window.location.href=turnURL+"ca_login.jsp"; } if("<%=CALogin.chkUserByCaId(CA_NO) %>"=="false"&&"<%=isLoginByForm%>"=="false"){ alert(" \n 证书尚未绑定,请执行系统登录操作进行系统绑定 \n "); } if("<%=bandResult%>"=="true"){ alert("恭喜您,绑定成功!\n即将跳转到系统界面") }# 四、相关截图{gird column="2" gap="10"}{gird-item}{mtitle title="第一次登录提示绑定账号"/}{/gird-item}{gird-item}{mtitle title="基于系统的登录逻辑登录登录成功则进行绑定操作"/}{/gird-item}{gird-item}{mtitle title="登录成功后进行绑定无误后提示绑定成功"/}{/gird-item}{gird-item}{mtitle title="系统登录成功后进入应用主界面"/}{/gird-item}{/gird}五、实施收获很多事情没有第一次做,本身就存在一种畏惧的意识,总感觉不知如何下手才好,经过本次实施,感觉很多方面的东西只要把思路理清了,技术实现都是很容易的事。
2013年04月07日
1 阅读
0 评论
0 点赞
2011-12-31
朱治龙2011年年终工作总结
一、工作基本总结 :今年主要从事的是基于TRSWCM相关的Web实施工作,展望走过的这一年的时间。工作上以相关公司制度严格要求自己;技术上关注最新最实用的技术文档,在项目追求更好更优的问题解决方案;服务上以客户为中心为客户提供及时的能力范围内最周到的服务。(一)芙蓉区政府(3天)承担的工作 :民生直通车,初始化相关的元数据、视图以及栏目(3天) 突出贡献 :无 工作失误 :无(二)中国湘西网-湘西州政府门户(66天)承担的工作 :项目管理、栏目结构梳理(3天)、服务器和TRS产品环境部署(1天)、数据迁移(3天)、站内检索(7天) 、模板制作(网站首页[7天]、走进湘西[7天]、信息公开[14天]、公共服务[7天]、投资湘西[7天]、湘西旅游 [7天])、培训及后期指导(3天) 突出贡献 :无 工作失误 :无(三)长沙市政府门户网站2011改版(37天)承担的工作 :模板制作(信息公开 [7天]、走进长沙[2天]、规范性文件[2天]、公共模板 [3天]、园区信息[3天]、在线办事栏目的指导和维护[3天]、公共服务中的交通服务,证件办理服务,资质认定服务,经营纳税服务 [7天]) 突出贡献 :完成项目中不少公共、核心的代码及模板的书写。灵活的运用所学的前端技术为客户解决了传统意义上无法解决的问题。 工作失误 :数据迁移后执行了“完全发布这个站点”操作,操作前不知谁将状态为“新稿”的文档也设置为了可发,便将所有的数据都直接发布出来了。由于该操作是不可逆的,导致客户由于这个事对我们工作的提出了严厉的指责,对这个工作中的疏忽在此表示真诚的歉意。(四)湖南省政府(27天)承担的工作 :主要负责后期的部分维护(包括WCM、WAS、网关、server等的基本维护及客户咨询指导问题指导、以及部分模板的修改工作[15天])、部分专题栏目(站点)的建设(省政府党建90周年专题制作[3天]、在线法律咨询[5天]、中共湖南省第十届党代会[2天]、湖南省工程建设领域项目信息和信用信息公开共享专栏[2天]) 突出贡献 :对TRS整体产品架构的熟悉后,对相关产品的实施和维护有了清晰的意识和思路,在解决问题的过程中得到客户的认可。 工作失误 :无(五)南方电网舆情项目(1天)承担的工作 :TRS相关产品测试环境部署及相关产品基本操作的培训指导(1天) 突出贡献 :无 工作失误 :无(六)三一知识库(12天)承担的工作 :知识库英文版(10天) 、知识库群测试项目部署(2天) 突出贡献 :无 工作失误 :无(七)湖南省卫生厅(1天)承担的工作 :卫生厅门户网站的检索功能实现,基于省政府的WAS实现。 (1天) 突出贡献 :无 工作失误 :无(八)湖南省科技厅(7天)承担的工作 :科技厅门户网站改版模板制作。 (7天) 突出贡献 :无 工作失误 :无(九)其他子站建设(55天)1.长沙市安监局(7天)2.长沙市运管处(4天)3.长沙市外侨办(7天)4.长沙市地震局(7天)5.长沙市食药监局(4天)6.长沙市林业局(4天)7.长沙市职工服务网(7天)8.芙蓉资讯网(8天)9.芙蓉区CBD(1天)10.芙蓉区城乡建设网(2天)11.长沙市档案局(4天)二、学习(一)TRS产品的学习:通过一年多的学习,对TRS相关产品有了大体的了解,也有了一些自己的见解。纵观TRS整个产品体系主要是以内容为核心,拓展出内容采集、内容挖掘、内容传输转换、内容分析处理,从而针对不同的应用领域根据相应的业务需求进行不同的展现。TRS的每一个产品都是根据相应的需求应运而生,都是为核心的内容而服务。上半年根据公司发展需要,对舆情做了些较为深入的学习,舆情项目的搭建集聚了公司的三大产品(ServerInforadarOM)的完美融合。但是发现相关的产品并不像销售资料说的那么具有魔力,随着后期其他相关项目的实施,逐渐的淡出了视线。接下来是知识库相关产品的学习,该产品前台漂亮页面的展现后面几乎汇聚了所有TRS产品的核心技术以及部分第三方产品。为分析知识之间的关系,实现相关知识关联图谱的展现,改系统需要跟CKM进行无缝的集成;为实现系统强大的搜索功能,系统跟TRS Server进行了完美的整合;为了能将关系型数据跟TRS Server数据的同步,而且还运用到了TRS Gateway在中间搭桥牵线。通过对知识库的学习,个人认为在后期发展的过程中,在知识沉淀这些无形资产被越来越为企业所看重的将来,在企业内部越来越有发挥她的价值时候。剩下的就是更多的WCM相关的项目实施工作了。在今年的项目中,对政府门户中的信息公开有了一个整体的认识以及相关成功的实施;并且在项目的使用过程中有了不少的实施以及使用经验能够较为权威的解答客户的一些问题。(二)其他技术的学习:在今年的工作中着重学习了Flex和HTML5以及对jQuery部分源码的研究。对于Flex的学习,主要是由于前期省图书馆提出的加密的需求,当时使用flash实现了,但是在后期相关技术的调研中如果能使用Flex实现会更为灵活。今年HTML5的技术被吹捧得很高,在刚火起来的时候也进行了较为系统的学习。但是在实际的项目里面根本无从得以施展。由于国内的整体浏览器仍然以IE为主流,即便IE9对HTML5的支持力度都是几乎所有主流浏览器里面最差的,所以该技术目前主要也就是在国外比较流行,在国内主要也就是在一些技术交流社区以及小部分指定浏览器的Web应用中运用。三、其他售前支持1、砂子塘大作文项目售前环境搭建与改造,给客户做演示后,客户反馈产品太贵,遂无果。2、省政府内容防窃取功能实现及客户演示,客户反馈实现方式及效果不错,但一直没有进一步的消息。
2011年12月31日
2 阅读
0 评论
0 点赞
2011-01-28
2011年履职意愿反馈(朱治龙)
一、请描述您具备哪些突出的工作能力。1、较强的学习能力。在技术上乐于接收并学习新技术,在学习的过程中不断地充实自己。在工作中学习能力是很重要的,尤其是做技术这一行,不能老拿三五年前的技术老底吃老本行,IT行业是一个与时俱进、日新月异的行业,只有具备充足的精神和十足的学习劲头才能立于行业的风尖浪头。2、具备一定的项目研发能力,对java相关主流框架技术有一定实际运用经验。3、有多年web前端技术运用经验。4、具备一定的项目管理相关的经验。这跟之前在北京所从事的工作有密不可分的关联。二、请说明2011年您愿意在银信公司具体承担哪一方面(或哪些方面)的工作,您的工作将帮助公司解决哪些问题?带来哪些利益?主要的工作可能还是项目的具体实施相关的工作,通过2010年的积累,相信在以后的工作中,类似的实施工作能较为轻松的胜任。并且在后期根据项目需要进行一些小型项目的开发工作。在2011年我还可以承担公司内部相关前沿技术的学习推广工作。通过学习、钻研,然后将所学的知识授之与众,实为人生之一乐事。三、请描述您2011年的个人职业目标以及它们和公司经营管理目标(根据您自己的理解)之间的关系。我的个人职业目标:努力为公司创造更多的价值。在实际的技术工作中我感觉自己是一个不那么善于表达的人,但这并不说明我缺乏自己对工作的主观想法。一直以来我都是一个乐于奉献的人,很多时候认为自己多付出些也是应该的。个人职位方面相关事项服从领导安排。四、您认为公司应该采取哪些措施帮助您实现个人目标?在项目不算繁忙的时间里,可以建议同事自发的学习一些基于工作上需要的东西。然后再进行相关学习经验的分享。尤其是技术方面,一个人闭门造车式的学习是没有多大长进的,只有通过分享、交流并进行实际应用才能最大化的将所学的技术为我所用。
2011年01月28日
0 阅读
0 评论
0 点赞
2010-12-31
朱治龙2010年年终工作总结
2010年5月24日入职,前6天入职培训(公司产品学习,WCM基本原理、流程),在本年度实施过的项目如下:省政府网站2010改版:从7月20日开始,到11月22日。工作时间大概85个工作日。项目中主要负责以下栏目及事项:公共服务、投资湖南、个性化定制、历史上的今天以及历史站点数据的迁移。相关子网站:湘江长沙枢纽 :进入公司在勇哥指点下做的第一个子网站,从中掌握了WCM常用置标的使用,以及基于WAS进行站内搜索的功能实现。 长沙市国资委 :首页由勇哥制作,但在后期的改进中仍花了不少时间。 长沙市交通局 :负责整个网站的模板制作,该项目在国庆期间时间最紧的时候完成,客户属于高标准要求的那种,通过本项目较多的跟客户进行沟通,也让我学会了跟客户的和谐沟通。 长沙市法制办 :主要负责整个网站的模板制作,整站基于DIV+CSS制作,客户比较好相处。参与过的项目:水利厅:2天政研室:3天芙蓉区雷达配置:10天三一知识管理年终感言:在公司半年多的时间里,主要实施项目是湖南省政府门户2010改版。在项目过程中学到了不少的东西,也为了适应工作的需要,阅读了不少有关前端实施相关的技术书籍。在浏览器兼容性调试、DIV+CSS布局、javaScript、jQuery等前台代码的编写上有了不少的提升。入职半年多的时间里,一直都是在同事们的细心帮助下渐渐的成长着,工作中同事间相处得都非常的融洽,互帮互助。在业余时间组织的一些活动中,也进一步的增进了同事之间的了解。工作期间阅读过如下技术相关的书籍:《javascript动态网页开发详解》《photoshop色彩构成与应用》《变换之美DIV+CSS网页布局揭秘(案例实战篇)》《深入浅出javascript》《JavaScript编程循序渐进》《网页设计·爱上jQuery》《高性能网站建设指南》《网站重构与Web标准设计》
2010年12月31日
0 阅读
0 评论
0 点赞
1
...
7
8