Blog
Blog copied to clipboard
博客(内附简历)
### 标记的很完善的一张图  ### 补充说明 上面的图已经标记的已经很明显了,我再稍微补充几点: - `offsetTop`, `offsetLeft`:只读属性。要确定的这两个属性的值,首先得确定元素的`offsetParent`。`offsetParent`指的是距该元素最近的`position`不为static的祖先元素,如果没有则指向`body`元素。确定了`offsetParent`,`offsetLeft`指的是元素左侧偏移`offsetParent`的距离,同理`offsetTop`指的是上侧偏移的距离。 - `offsetHeight`, `offsetWidth`:只读属性。这两个属性返回的是元素的高度或宽度,包括元素的**边框、内边距和滚动条**。返回值是一个经过四舍五入的整数。如下图:  - `scrollHeight`, `scrollWidth`:只读属性。返回元素内容的整体尺寸,包括元素看不见的部分(需要滚动才能看见的)。返回值**包括padding,但不包括margin和border**。如下图:  - `scrollTop`, `scrollLeft`:图中已经表示的很明白了。如果元素不能被滚动,则为0。 - `window.innerWidth`, `window.innerHeight`:只读。视口(viewport)的尺寸,包含滚动条 - `clientHeight`, `clientWidth`:包括padding,但**不包括border, margin和滚动条**。如下图:  - `Element.getBoundingClientRect()`:只读,返回浮点值。这个方法非常有用,常用于确定元素相对于视口的位置。该方法会返回一个[DOMRect](https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMClientRect)对象,包含left,...
作为一个前端工程师,平常写一些小demo或项目时会遇到这样的情况:我想把这个html页面呈现给别人看看,又不想把整个工程项目发给他,这样太麻烦,要是有个能在线演示demo的平台就好了。OK,github可以帮我们,一切都不是问题。 把github上的index.html文件作为网页展示我目前知道两种方法,下面道来: 1、随便在github找一个html文件,例如[这个](https://github.com/pramper/Demos/blob/master/JS-Demos/ResponsiveTable/index.html),然后在其url地址前加上`http://htmlpreview.github.com/?`,变成了 `http://htmlpreview.github.com/?https://github.com/pramper/Demos/blob/master/JS-Demos/ResponsiveTable/index.html` 访问这个地址即可。 不过这种方法有个缺陷,打开浏览器调试工具,会发现莫名多了几个``标签。感觉不爽,下面重点说说第二种方法。 2、利用`gh-pages`,步骤很简单,如下: - 创建`gh-pages`分支:如果一开始是在master分支下工作,工作完成后,输入命令`git checkout -b gh-pages`,此命令会新建一个`gh-pages`分支并切换到该分支 - 推送`gh-pages`分支到github:输入命令`git push origin master:gh-pages`,此命令会把 - 如果你在本地是在`master`分支下工作,工作完成后,输入命令`git push origin master:gh-pages`,此命令的意思是把本地`master`分支的内容推送到远程的`gh-pages`。如果远程没有`gh-pages`分支的话,会自动创建该分支 - 通过访问`http://[用户名].github.io/[index.html所在目录]`,这样就会访问到项目目录下的`index.html`文件。还是方法一种那个例子,其访问地址为`http://pramper.github.io/Demos/Vue-Demos/questionnaire/dist` **ps**:又知道的了一种更简单的方法,不需要gh-pages分支,是我目前所知最简单的方法: 打开仓库的setting,然后这个[设置](https://github.com/blog/2228-simpler-github-pages-publishing),简单粗暴!!
随着对JavaScript学习的深入和实践经验的积累,一些原理和底层的东西也开始逐渐了解。早先也看过一些关于js单线程和事件循环的文章,不过当时看的似懂非懂,只留了一个大概的印象:浏览器中的js程序z执行是单线程的。嗯,就这么点印象。当时也有些疑问:既然是单线程的,那异步调用是怎么实现的?计时器是靠谁来计时的,这单线程总不能一边执行程序一边计时吧?那些耗时的I/O操作为啥没把线程阻塞,不是说好的单线程么?相信很多不了解JavaScript单线程的同学也有过类似的疑问。 今天看了不少相关的资料,就详细地总结一下,希望能帮到大家,同时自己也梳理一下知识点,理解是一回事,能写下来是另一回事。好了,开始正文。 ### 一、JavaScript单线程 在浏览器的一个页面中,该页面的JS程序只有一个线程,故曰单线程。因为是单线程,所以程序的执行顺序就是从上到下依次执行,同一时间内只能有一段代码被执行。那为什么不用多线程,这样不是更能充分利用CPU,提高效率么? 早期的网页内容非常简单,单线程足以应付,所以在设计之初,估计设计者就没考虑使用多线程。另外,JavaScript主要用来处理用户与页面产生的交互,以及操作DOM;如果以多线程的方式来操作DOM,一个线程要求删除该DOM,另一个要求修改DOM样式,那么浏览器该听谁的?这大大增加了程序设计的复杂度,本来前端都不好学,不是么~~~简简单单多好。 虽然JavaScript是单线程的,**可是浏览器内部不是单线程的**。你的一些I/O操作、定时器的计时和事件监听(click, keydown...)等都是由浏览器提供的其他线程来完成的。 如果想利用多线程处理一些耗时较长的任务,可以使用HTML5提出的Web Worker。 ### 二、任务队列和事件循环 提到异步机制,不得不说到任务队列和事件循环,这是理解JS异步机制的要点。 首先理解浏览器的并发模型,来看下面这个图:  左边的栈存储的是同步任务,所谓同步的任务就是那些能立即执行、不耗时的任务,如变量和函数的初始化、事件的绑定等等那些不需要回调函数的操作都可归为这一类。右边的堆用来存储声明的变量、对象。下面的队列就是**任务队列**,一旦某个异步任务有了响应就会被推入队列中。如用户的点击事件、浏览器收到服务的响应和后面提到的setTimeout插入的事件。每个异步任务都和一个回调函数相关联。 一个js程序的单线程用来执行栈中的同步任务,当**所有同步任务执行完毕后**,栈被清空,然后读取任务队列中的一个待处理任务,并把相关回调函数压入栈中,单线程开始执行新的同步任务,执行完毕。 单线程从任务队列中读取任务是不断循环的,每次栈被清空后,都会在任务队列中读取新的任务,如果没有新的任务,就会等待,直到有新的任务,这就叫任务循环。因为每个任务都由一个事件所触发,所以也叫**事件循环**。 ### 三、异步机制 有了上面两节做铺垫,理解异步机制就容易多了。拿ajax来说,当页面的单线程执行`xhr.send()`之后,对于页面来说发送任务已经完成了。怎么发送,那是浏览器的事,和单线程无关;什么时候响应,这事说不准。为了及时地得到响应的内容,在单线程中注册相应的事件就好`xhr.onreadystatechange = fn() {...}`。注册之后,浏览器会在内部的其他线程中自动地帮我们监听该事件。直到该事件被触发,浏览器会在任务队列中添加一个任务等待该单线程执行。 ### 四、定时器 setTimeout的作用是在间隔一定的时间后,将回调函数插入任务队列中,等栈中的同步任务都执行完毕后,再执行。因为栈中的同步任务也会耗时,所以间隔的时间一般会大于等于指定的时间。 `setTimeout(fn, 0)`的意思是,将回调函数fn**立刻插入任务队列,等待执行**,而不是立即执行。看一个例子: ```...
- 文章 - [HTTP 协议入门-阮一峰](http://www.ruanyifeng.com/blog/2016/08/http.html) - [写给前端面试者](https://github.com/amfe/article/issues/5) - [Debouncing and Throttling Explained Through Examples](https://css-tricks.com/debouncing-throttling-explained-examples/) - [十大经典排序算法总结(JavaScript描述)](http://gold.xitu.io/post/57dcd394a22b9d00610c5ec8?utm_source=gold_browser_extension) - 项目 - [从零开始学编程 系列汇总(从α到Ω)](https://github.com/justjavac/Programming-Alpha-To-Omega) - [简单的dht爬虫](https://github.com/beilunyang/dhtCrawler) - [ DHT 爬虫 + BT 客户端的结合体](https://github.com/dontcontactme/p2pspider)
斐波那契数列数列:0 1 1 2 3 5 8 13...,用数学公式表示为:`fn(n)=fn(n-1)+fn(n-2), n>1`。下面我们用js程序来实现这个算,并一步步优化它。一下程序均在Node.js v6.2.0下实现、测试。 ### 简单的JS程序 实现斐波那契数列的程序非常简单,如下: ``` javascript var count = 0 // 记录函数被调用的次数 function fib(n) { count++ if(n
本[主页](http://ylcui.top)基于github,使用[hexo](https://hexo.io/zh-cn/)搭建,主题为[maupassant](https://www.haomwei.com/technology/maupassant-hexo.html) ### 一些问题 博客搭建过程中遇到了一些问题,现把问题和解决方案归纳如下: - `hexo deploy`出错,无法部署到github,报错信息如下: `FATAL fatal: remote error: You can't push to git://github.com/pramper/pramper.github.io.git Use https://github.com/pramper/pramper.github.io.git` 意思是你不能使用SSH的方式部署到github,应该使用HTTPS的方式部署。由于使用HTTPS的方式进行部署,每次都得输入账号、密码,很麻烦,所以选择SSH方便些。步骤如下: 1. 创建一个SHH Key:一般SSH Key在windows系统中存放在`C:\Users\你的用户名\.ssh`下,一般会有`id_rsa`和`id_rsa.pub`两个文件,前者是私钥,后者公钥;如果存在着两个文件则不需要创建SHH Key了;如果不存在,在命令行输入`ssh-keygen -t rsa -C "[email protected]"`,`-t`指定密钥类型,这里使用rsa,`-C`注释文字; 2. 在github上添加deploy...
转自 [同人于野](http://www.geekonomics10000.com/519) 随着畅销书《异类》的流行,“练习一万小时成天才”这个口号现在是尽人皆知。也许仍然有不少人相信那些不世出的天才必有天生的神秘能力,但科学家通过大量的调查研究已经达成共识,那就是所有顶级高手都是练出来的。不但如此,最近几年的科学进展,人们可能第一次拥有了一个关于怎样炼成天才的统一理论。 好消息是除了某些体育项目对天生的身高和体型有特殊要求之外,神秘的天生素质并不存在,也就是说人人都有可能成为顶级高手。早在20多年以前,芝加哥大学的教育学家 Benjamin Bloom 就曾经深入考察过120名从音乐到数学多个领域内的精英人物,发现他们幼年时代没有任何特别之处。后人的研究更证明,在多个领域内,就连智商都跟一个人能不能达到专家水平没关系。 有个匈牙利心理学家很早就相信只要方法得当,任何一个人都可以被训练成任何一个领域内的高手。为了证明这一点,他选择了一个传统上女性不擅长的项目,也就是国际象棋。结果他和妻子把自己的三个女儿都训练成了国际象棋世界大师,这就是著名的波尔加三姐妹。这个实验甚至证明哪怕你不爱好这个领域,也能被训练成这个领域的大师,因为三姐妹中的一个并不怎么喜欢国际象棋。 而坏消息是成为大师需要长时间的苦练。每天练三小时,完成一万小时需要十年时间,但这只是达到世界水平的最低要求。统计表明对音乐家而言,世界级水平要求的训练时间是十五到二十五年。但最关键的并不是练习的时间,而是练习的方法。 天才是怎样炼成的?中国传统思维比较强调一个“苦”字,冬练三九夏练三伏,甚至是头悬梁锥刺股。而近代生活条件越来越好,人们则开始强调一个“爱”字,说兴趣是最好的老师,强调寓教于乐,“哈佛女孩”的家长们纷纷写书,介绍自己的孩子如何一路玩进名校。 很多励志故事和流行的成功学书籍最爱强调的似乎是“顿悟”,认为一个人之所以不成功是因为他没想通,他没有认识到真正的自己!好像一旦一个人顿悟到了真正的自己,他就会非常简单地在本来应该属于自己的领域成为天才人物。一个销售员可能认为真正的自己其实是个小说家,一个医生可能认为真正的自己其实是个画家 — 唯一的问题是他们从来没有写过小说或者画过画 — 但他们认为他们距离“真正的自己”只有一步之遥,一旦尝试了就会爆发天才。 所有这些关于成功学的个人经验和励志故事都不科学。假设一个成功人士做过一百件事,包括参加演讲比赛,衣着有个性,听英文歌曲,最喜欢的颜色是绿色等等,他会非常自得地把这一百件事都写进自传,没准还要加上女朋友的影响。然而其中真正起到决定性作用的可能只有四件事,问题是他和读者都不知道是哪四件。 科学家不信励志故事,他们只相信调查研究。在过去二三十年内,心理学家们系统地调研了各行各业内的从新手,一般专家到世界级大师们的训练方法,包括运动员,音乐家,国际象棋棋手,医生,数学家,有超强记忆力者等等,试图发现其中的共性。他们的研究甚至细致到精确记录一所音乐学院的所有学生每天干的每一件小事,用多少时间做每件事,父母和家庭环境,来比较到底是什么使得那些音乐天才脱颖而出。 现在这项工作已经成熟了。2006年,一本900多页的书,The Cambridge Handbook of Expertise and Expert Performance, 出版。这是“怎样炼成天才”研究的一本里程碑式的学术著作,此书直接引领了后来一系列畅销书的出现,包括格拉德威尔的《异类》,Geoff Colvin 的 Talent is...
许多刚开始使用Sublime的同学可能都抱怨过为什么没有语法错误提示功能。像WebStorm,输入的语法错误在程序被编译之前就被编辑器提示出来,这样会在一定程度上提高开发的效率。而Sublime似乎不会提示语法错误或是简单的拼写错误,比如误用了中文符号,对象的属性之间忘记用逗号隔开等等一些低级错误;我们必须每次编译后才知晓这些错误,这样会将我们的部分精力和时间浪费在一次次地修改这些低级错误上,从而无法专注于程序本身。 甚至有时候像`if(a=1)`这样的错误,编译也是完全通过的。我就不只一次碰到过这样的情况,编译完全通过,逻辑也对,就是结果不对。结果debug半天,发现是这样的错误,顿时有种精力都喂了狗的感觉。好在现在有解决办法了(其实早有了,我刚发现而已~~),我们也能像在WebStorm中一样,一边写程序,一边系统自动帮我们检测语法正确性,就像下面这样:  我误用了`=`,在文件保存时就会被提示,直接顺手改掉就行了,方便的不行。 这些都是[ESLint](http://eslint.org/)的功劳,它包含了一系列的[Rules](http://eslint.org/docs/rules/),通过配置这些Rules,你可以轻松地实时检测语法错误。在使用之前最好把[官方教程](http://eslint.org/docs/user-guide/configuring)学习一下。下面说说在Sublime中的配置方法: - Sublime集成[ESLint](http://eslint.org/)需要两个插件[SublimeLinter](https://github.com/SublimeLinter/SublimeLinter3)和[SublimeLinter-contrib-eslint](https://github.com/roadhump/SublimeLinter-eslint);直接在Package Controll中安装就好 - 安装ESLint:`npm i -g eslint` - 安装后修改SublimeLinter的配置文件,在Package Settings中打开其Setting-User,将下列代码复制进去: ``` json { "user": { "debug": false, "delay": 0.25, "error_color": "D02000", "gutter_theme": "Packages/SublimeLinter/gutter-themes/Default/Default.gutter-theme", "gutter_theme_excludes":...
很多场景下都需要拖曳或拖放元素的功能,例如拖曳一个登陆框或提示框等。今天温习了一下传统的拖曳方式,并学习了一下HTML5提供的原生拖放功能,总结了一下。 ### 传统拖放元素的方式 实现步骤如下: 1. 鼠标选中元素,触发`onmousedown`事件 2. 开始拖动,触发`onmousemove`事件,元素跟随鼠标移动 3. 释放鼠标,触发`onmouseup`事件 其实关键就是在移动过程中将鼠标的坐标不断赋值给被拖动的元素,从而达到拖曳元素的效果。 核心实现代码如下,进行了简单的封装,使用时调用drag函数并传入点击的元素和被拖曳的元素即可: ``` javascript var drag = (function() { var flag = false // 表示是否拖曳 /** * @param {[element]} bar:点击的元素,如登录框的头部...
翻译自 [Dynamic Components in Vue.js](https://coligo.io/dynamic-components-in-vuejs/) 这篇文章将会教你如何使用Vue中的[动态组件](http://cn.vuejs.org/guide/components.html#u52A8_u6001_u7EC4_u4EF6)。当创建小型的单页应用时,这些小型应用可能并不需要vue-router来控制路由,我们只想简单地切换不同的组件来达到不同的展示效果。  Vue中的动态组件要求你指定一个挂载点,在这个挂载点下你可以动态地切换组件。在这篇教程中,我们将通过几个例子来展示如何使用动态组件。我们会创建一个动态组件,学习使用keep-alive指令参数,最后我们还会在组件的切换之间添加一些过渡效果。下面开始吧: ## 创建动态组件 假设我们正在为一个Blog做个简单的导航栏,我们想添加两个页面: - 一个用于管理已经存在的博客文章 - 一个用于创建新的博客文章 稍后,我们会组件化这两个页面。现在,让我们从头一步步来吧,我们把这个简单的应用挂载到body下: ``` javascript new Vue({ el: 'body' }) ``` 添加导航栏,在头部引入[BootStrop 3.3.6](http://cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css): ``` html Manage Posts...