学习与分享,当然还有生活~

从快排递归说起

快排最简洁的是递归写法,可是当我问自己你真的想明白到底发生了什么吗?如果你有些不能肯定,那么我们一起来看看到底发生了什么。 其实快排的原理用语言描述起来挺容易的,简单说就是在数组中找一个值作为对比值(常常找中间那个元素),然后把数组中小于此值的值放入一个数组,把大于此值得放入另一个数组。然后针对这两个数组重复递归上面的过程,把所有的值连接起来就是最后的结果了。 让我们来写写代码: var qsort = function(arr) { if(arr.length <= 1) { return arr; } var pivot = arr.splice(Math.floor(arr.length/2), 1)[0], left = [], right =[]; for(var i=0; i<arr.length; i++) { if(arr[i] < pivot)

mobile

移动端适配页面快速搭建

遥想去年入前端坑的时候,就很快遇到了移动端页面的开发,天(er)真(bi)的我立马上去量设计稿,然后撸起袖子就是干!可是打开调试一看乱套了,先不说布局上的问题,就是大小看起来也不太对啊,太大了!然后就去问老司机,他说尺寸你要除以2才行,我心里挺郁闷的,为啥啊。。当时羡慕紧,就先这么搞,然后加上百分比布局,完成了第一次的开发任务。。。 但是!这只是叫完成,我非常不喜欢心里有梗的感觉,我觉得这事儿没这么简单,而且随着后期开发的进行,有一天设计mm给我说你这个线好粗啊,能不能再细点儿,我心中一万个不(cao)情(ni)愿(ma)飞过,我这已经是1px了啊。。。 还有最关键的我发现用百分比布局有个极大的缺陷,就是当你感知设计的设计意图的时候,(我们的设计师同学们的设计意图有多重要,我觉得好的设计师一定是设计意图非常犀利的),有些设计元素并不是单纯的左对齐,右对齐,或者和某个元素有某种视觉上的联系。也就是说,这个时候百分比布局就要头疼了,这个元素到底是百分之多少呢,用尺子量一下,可以啊,可是你把设备屏幕放大或者缩小看看,哭还是不哭?。。。。 是的,

React

React起手-组合vs继承

当然,React也是提倡组合优于继承的,这里对一些新手来说,往往他们喜欢用继承,我们来看一下如果用组合来更好的来解决问题吧~ 这里的这个例子所实现的功能,当时用vue1实现的时候特别困难,如今vue2应该也支持了相应的功能,不过当我看到入门文章的这里的时候,我感觉这是React很强大的地方,简单来说就是,可以进行依赖注入,注入什么呢?当然什么都可以,这就给UI组件强大的灵活能力,即父组件只用实现那些不变的部分,那些变化的部分我只需要抽取出来行程单独的子组件,这样父组件在不知道他内部某些部分是什么样子的时候就可以进行抽象。 还是先看例子来理解一下: function FancyBorder(props) { return ( <div className={'FancyBorder FancyBorder-' + props.color}> {props.children} </div> ); } function WelcomeDialog() { return ( <FancyBorder color="blue"> <h1 className="

React

React起手-提炼状态

官方文档叫Lifting State up,不知道我翻译的是否妥当,哈哈哈。 组件之间的数据有些肯定是共享的,也就是说这个共享数据不管在什么地方被改变了,所有组件都要及时的反应到自身上,官方推荐提炼共有状态到他们最近的祖先上。举个例子来理解这个东东,例如有个温度计,当温度到100以上时候水开,反之不开。 function BoilingVerdict(props) { if (props.celsius >= 100) { return <p>The water would boil.</p>; } return <p>The water would not boil.</p>; } 然后我们添加一个计算器来输入温度 class Calculator extends React.Component

React

React起手-表单

对于表单的处理,react的处理和原生很相像,所以没有什么多说的,就是看例子吧~ 以下就是input, textarea, select的用法,其实都一样,把state的值挂载到相应位置的value上,并且监听相应的事件即可,注意事件的写法onChange驼峰哦。回调函数的第一个参数是event哦,原生event对象可以做一些例如消除默认行为和停止冒泡的事情。这些被控制的组件叫做controlled components。 然后你会发现这也太麻烦啦,每一个表单控件我都得写一个handler区处理它,这样的话不仅麻烦而且和原生代码以及非react得库难以整合,所以有uncontrolled components, 来改善这一情况,会另起文章来记录~ class NameForm extends React.Component { constructor(props) { super(props); this.state = {value: ''}; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { this.

React

React起手-列表渲染

列表渲染也很简单,利用map方法返回一个新的渲染列表即可,例如: const numbers = [1, 2, 3, 4, 5]; const listItems = numbers.map((number) => <li>{number}</li> ); ReactDOM.render( <ul>{listItems}</ul>, document.getElementById('root') ); 基础列表组件的构造中,有一个重要的属性值key需要你进行指定,这个很重要,和帮助框架进行性能优化有关,具体深入原因后续会继续了解,先来看例子: function NumberList(props) { const numbers = props.numbers; const listItems

React

React起手-事件处理

React的事件处理和DOM的事件处理是很相似的,只是有一些语法上的区别: React的事件名是驼峰的,不是小写的 在JSX语法中,你传递一个fucntion作为时间处理器,而不是一个string 举个例子: <button onClick={activateLasers}> Activate Lasers </button> 而且如果你想拿到事件对象event,这个对象是React按照w3c标准完成的,所以不用担心浏览器的兼容性,可以像如下这样: function ActionLink() { function handleClick(e) { e.preventDefault(); console.log('The link was clicked.'); } return ( <a href="#" onClick={handleClick}> Click me </a>

React

React起手-条件渲染

可以根据state的值进行组件的条件渲染。例如: function Greeting(props) { const isLoggedIn = props.isLoggedIn; if (isLoggedIn) { return <UserGreeting />; } return <GuestGreeting />; } ReactDOM.render( // Try changing to isLoggedIn={true}: <Greeting isLoggedIn={false} />, document.getElementById('root') ); 你还可以用变量去存储组件,以便进行条件筛选,使得渲染函数的返回值更加清爽,例如: class LoginControl extends React.Component { constructor(props) { super(props); this.handleLoginClick = this.

js

小心事件多次绑定

今天同事让我看一个问题,就是jquery中的on事件的回调函数中引用了外部的一个变量a,但是经过一些操作之后在触发事件回调时候a的变量的值总和预期的不一致,好久没写jquery看了半天也没看出来哪里有问题,后来发现原来绑定的这个on语句在操作的时候会不断被执行,意味着添加了好多次的回调函数,而回调触发的时候就会触发n多次。这就意味着如果每次添加on的时候引用的变量a是不同的话,回调函数多次执行时引用的a的值也就是不同的(这次闭包添了乱orz。。)。 所以呢?结论就是绑定事件时最好进行单次绑定,重复绑定时要小心了,看看业务逻辑是否真的需要这么干,当然上面的解决办法也很简单,先解绑元素之前的事件再添加现有的事件即可。 $().off('change').on('change', function(){});

从exports和module.exports说起

虽然暂时工作上没有用到commonJS的模块化写法,但是还是经常看到这种写法的源码或者文章,有时候看到exports和module.exports就有点儿傻傻分不清楚了。。。我想初学者可能会和我一样的疑问吧,结果一查还真是一大把。。看了几篇文章,其中stackoverflow上有个哥们写的很好,故记录在此。 其实记住和理解这张图就很容易区分了: 这个图展示了两者的关系,为了方便理解,我觉得可以这么来解释,当一个js文件需要模块化的时候,node环境中会给文件注入exports和module.exports这两个变量,并且刚开始的时候这两个变量是指向同一个空对象的,随后你拿着这两个变量做了一系列操作后,注意这是关键:只有module.exports会被返回以便后续其他模块require引用使用。 所以到这里只是解释了运行的关系,那为啥弄两个呢?对啊为啥啊?只要module.exports不就行了,你赋值给它返回也是它多好多正常,非要弄个exports干啥幺蛾子。。。。哈哈,我理解的是,没错,你总是用module.exports是可以的而且不会出错,但是每次都这么写: module.exports.a = 1; module.exports.b = function() {}; module.exports.c = 'ccc'; 觉得累么??那这样写好了: exports.a

js

从css3和canvas的旋转说起

之前遇到的一个老问题啦,突然发现又傻傻分不清楚啦。。。来总结一下吧,哈哈。先来说一下,为什么要把这两者放在一起说,先上需求:如何把反着的一张图片弄正,并输出出来呢?也就是我们的目标如图: 这个需求来源于,手机照相机照出的图片其实存起来的时候对于程序显示来说不都是正的,我们自己在手机上浏览看起来是正的是因为手机的程序帮我们搞定啦,可是当我们拿到手机原始图片的时候想展示的时候发现,矣?怎么有的反着的,其实照相机照相的时候会留下照片的方向信息,根据这些方向信息我们就可以把照片调正过来,然后再存到服务器或者展示出来,关于照片里的方向信息大家可以去参考EXIF.js这个库,我总结的信息如下:(EXIF信息有1 8 3 6) 1: 正向 8: 需要逆时针旋转90 3: 需要旋转180度 6: 需要顺时针旋转90 好了,有了这些信息我们来看看怎么去做呢? 比如有张图是需要旋转90度才能扶正的,那写css3的rotate的不就行了么?是啊,我最初也是这种感觉,可是这样有诸多限制,比如,如果你想把图片存在服务端,下次别人用的时候图片就是正的了,就不用再做特殊处理了啊,那得图像处理下,前端怎么弄呢?canvas应该可以吧!本以为可以像css3那样两行搞定: transform:

H5页面 - 小米 Max 微信群聊
h5

H5页面 - 小米 Max 微信群聊

开始 上半年小米Max发布的时候,做了一个在朋友圈传播的模仿微信的群聊界面H5页面:一群公司的大咖在群里聊小米Max,用户可以向大咖们提问,以此了解产品。 页面的主体是群聊对话,同时在对话中包含了很多交互:图片、视频、动画、翻译等。如果用户是用微信打开的链接,还会获取用户名和头像,作为页面里的“我”来聊天,效果有点逼真~ 页面里有“彩蛋”,还能求红包喔~ 不啰嗦,先看页面效果。页面地址(手机浏览效果更好)。微信里访问这个链接 原页面对话和交互都很多,我择出了主要逻辑和交互放在codepen上,供有兴趣的同学参考~ 同时简单分析了自己的想法和思路,也算是一个总结~ Codepen 链接 整体布局 整体布局还是很简单的:一个可以滚动的div,承载所有对话;一个固定在底部的“输入框”,包含所有选项。 人物 & 对话数据 群聊里的所有人物都保存在 js 对象 _members 里,包含人物的 id、

jQuery无new化探索

最近尝试着写dom库,发现了一个问题,就是jquery不用new就可以得到相应的对象实例,好奇之下发现网上已经有很多的分析和解释啦,但是看起来还是那么绕绕绕~~ 没关系,来慢慢理解看看呗。先看最关键的几个源代码 jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context ); } jQuery.fn = jQuery.prototype = { jquery: version, constructor: jQuery, ... } init = jQuery.fn.init = function( selector, context, root ){} init.prototype = jQuery.fn; window.jQuery = window.$ = jQuery; 具体实现就不贴了,很复杂怕怕。。。就单说无new化,其实就是$()就是调用了jQuery这个构造函数,而这个函数里面是返回的一个new的init构造方法,所以实际上$

从 __proto__ prototype 说起

先来做个复习,ES5中有有几种数据类型呢? 5种基本数据类型 Undefined Null Boolean Number String 1种复杂数据类型 Object 除了基本数据类型,万物皆对象,记住这个很重要,这体现了js设计的哲学思想,和现实生活事物存在的关系一模一样。 接触js也一年有余了,刚开始看各种概念感觉在记忆,先能上手干活的感觉也让自己先用了js起来,回头来看很多概念你不真正用的有些感悟可能真的很迷糊,就像今天突然问自己__proto__ 是干嘛的,和它长得很像的prototype又是干嘛的,为啥不都用一个,看起来读起来都那么像。。。。ok,我尽量把自己所思所想记录下来,能表达的清晰,哈哈其实我理解能力有限哈哈哈。 不让自己思维绕弯子,当我们想完全弄清楚一件事情的时候,那么最好搞清楚我们最关心的两个问题:它是什么,有什么用,那么先直接给几个定论(如果有误区请各位大神指正): 是什么 __proto__ 每个对象都拥有的属性 prototype 每个方法都拥有的属性 有什么用 让js拥有了原型链来达到共享数据和方法的目的 好了,先来说是什么,那么让我们想想几个关键字:每个对象,每个方法,那么记得开始很重要的一件事儿么,就是js中万物皆对象,

页面切换滑动过场

今天看一篇文章页面切换的文章,作者做了很多页面切换的效果,链接如下here, 作者给了我一种页面切换的思路,记录如下,其实之前总觉得所有页面应该看成一个整体来看,可是这样反而限制了一些效果的实现,而作者的基本思路是每个页面都有独立的动画,只是每两个相邻页面的各自动画要相互配合,配合是指的动画时间契合和动画形式契合,所以我就简单学习作者的代码,练习了一个demo,以加强这种思路~ <!DOCTYPE html> <html> <head> <script src="http://code.jquery.com/jquery-1.8.3.min.js"></script> <meta charset="utf-8"> <title&

Select2通过ajax初始化筛选项踩坑之殇

今天出现了一个bug,让我深深地再一次鄙视了自己的智商。。。话不多说,记录下自己的二逼,上代码: Vue.directive('select2', { twoWay: true, params: ['options'], bind: function() { var self = this; $(this.el).select2(this.params.options).on('change', function() { self.set($(this).val()); //为了清空可能的输入文字 $(this).siblings('.select2').find('.select2-search__field').val(''); }); }, update: function(value) { $(this.el).val(value).trigger('change')

&& || 赋值时傻傻分不清楚吗?

先上一个问题: a = b || c; 请问a的值会等于b还是等于c呢? 相信你心里已经分情况讨论了, 那再来一个问题: a = b && c; 再请问a的值会等于b还是等于c呢? 相信你心里已经又开始分情况讨论了, 矣等等。。。我好想傻傻分不清了哈哈哈 那到底这两种操作符是怎样解析的呢? 我们来做个试验: var a = true || 'c'; // true a = false || 'c'; // 'c' // a = true && 'c' // 'c' a = false && 'c' // false 矣,有没有发现正好相反,平时我用 || 比较多,今天突然看到有人用 &&,一下子有些蒙圈哈哈哈,就拿来研究了一把,是不是觉得不好记忆,然后有啥卵用?

一次性获取浏览器前缀

当你想用js去操作一些新特性的时候有没有对写前缀有种想死的赶脚。。。故去寻找了一番得到vendorprefix的方法,以减少重复劳动。 var prefix = (function () { var styles = window.getComputedStyle(document.documentElement, ''), pre = (Array.prototype.slice .call(styles) .join('') .match(/-(moz|webkit|ms)-/) || (styles.OLink === '' && ['', 'o']) )[1], dom = ('WebKit|Moz|MS|O').match(new RegExp('(' + pre + ')', 'i'))[1]

你的webpack/browserify watch 远程同步文件失效了吗?

最近在项目上捯饬js模块化的东西,选来选去还是选择了gulp+webpack这种方式,因为我已经用gulp做了一些css的相关工作,gulp用起来更像是在编程,感觉自己的掌控力会更大,所以并没有一下子都投入到现在相当火的webpack中去(webpack更像是基于配置的东西,初看起来各种概念、配置和插件让人眼花缭乱,如果要实现些特殊需求可能需要对其有更深的理解,所以在功力不够的时候,在目前的阶段上我选在了以上方案)。 这里不谈方案的具体内容,谈一下让我极其郁闷的遇到的一个问题,就是不管我用browerify的watchify还是webpack自带的增量watch功能,当文件变化的时候竟然不更新!!!!! 我解决问题的思路如下: 首先我尝试检查配置,确定输入和出入都没有任何异常,和官网文档对比也没有不同之处,然后我就特别纳闷是什么原因。。。 突然想到会不会是因为我的文件更改是在本机上,然后利用sftp同步到远程虚拟机上的时候出了问题(工程化环境我上维护在了远程虚拟机上),所以我就直接上虚拟上修改文件试了一下,bingo。。watch成功了。。。 然后我想一定是和底层文件传输和watch的监听方式有关,奈何自己对底层。。(知识的多样性是多么重要啊),然后就google之。。。都很少有内容提到这些,还好在对比了几篇文章后,找到了解决方案就是:给webpack加上如下配置(很意外,browerify的watchify也有类似的poll配置,但是应该是有bug,并不起作用。。这也让我放弃了它。。。如果有人知道为什么可以给我留言,谢谢啦) watchOptions: { poll: true } 问题虽然解决了,但是我心里还是疑问的啊,为啥啊为啥啊,本地监听就可以,

js

js加载与执行你分得清楚吗?

今天在和端上app通过异步回调进行js通信时遇到了些执行顺序的问题,然后就发现矣~js的加载和执行到底是怎样的呢?还真不一定能理得很清楚,然后我想哎~~基础真重要啊,不要把自己老是埋在需求里,要慢慢量变到质变吧! 引用一篇博文里的讲述很清楚 js的运行一定要知道的两大特性: 载入后马上执行 执行时会阻塞页面后续的内容(包括页面渲染,其他资源的下载) 所以,如果有多个js文件被引用,那么这些js被串行的载入,并依次执行。因为javascript可能会来操作HTML文档的DOM树,所以,浏览器一般都不会像并行下载css文件并行下载js文件,因为这是js文件的特殊性造成的。所以,如果你的javascript想操作后面的DOM元素,基本上来说,浏览器都会报错说对象找不到。因为Javascript执行时,后面的HTML被阻塞住了,DOM树时还没有后面的DOM结点。所以程序也就报错了。 传统方式 所以,当你写在代码中写下如下的代码: <script type="text/javascript" src="http://coolshell.cn/asyncjs/alert.js">

js

读js红宝书之:栈+队列

js中可以以数组来模拟栈和队里的行为哦,哎~数据结构这东西还是得会用到实际场景中,和算法神马最配哦。。。可是,无奈我还是没什么天赋。。废话不多说,说多了都是泪。。。 1.栈 push()方法:后进 接受任意参数,逐个添加到数组末尾,并返回修改后的数组长度。 pop()方法:先出 从数组末尾移除最后一项,减少length,并返回移除的项。 var colors = ['red', 'blue']; colors.push('brown'); //此时 length为3 var item = colors.pop(); //item 为 brown, length为2 2.队列 push()方法:先进 shift()方法:先出 移除数组中的第一项,并返回该项,减少length

js

读js红包书之:检测数组

一共介绍了三种判断方法: 1.instanceof 判断法 if(value instanceof Array) 缺点:instanceof是根据构造函数来判断的,而且value必须是和Array在同一个全局作用域中,如果一个页面包含多个frame有多个全局作用域的时候就会出现问题。 2.isArray 判断法 if(Array.isArray(value)) 缺点:ES5的方法,旧浏览器不支持 3.toString 判断法 function isArray() { return Object.prototype.toString.call(value) == "[object Array]"; } //类似的还可以检测 function isFunction() { return Object.prototype.toString.call(value) == "[object Function]"

模拟ios滚动选择弹框

突然发现用别人的插件挺好的,就琢磨着我是不是应该也写一个试试(就是就是发现自己啥都不会哈哈哈),然后大概有了思路就开始动手,写了好久感觉越写越乱了。。。现阶段这版只是能用。。写的过程中也发现了和思考了不少东西,对于怎么组织好代码更优雅还是有不少困惑,不过呢慢慢来吧,多练习多思考才是王道,其他各种浮躁的情绪只能帮倒忙。。。简单介绍一下其功能,具体代码有兴趣的可以去这里看看点击这里 还有todo就是增加多列并动态加载数据的功能 安装 引入iscroll-probe.js 引入xScrollSelect.js 引入xScrollSelect.css 使用示例 var xs = new xScrollSelect({ spaceNum: 2, //预留的格子数, 即选择空白区域所占的格子数, 默认为2 itemWidth: 40, //每个格子的宽度单位px,默认为40 showCover: true, //是否展示背景遮罩, probeType: 2, //iscroll配置参数,表示scroll监听中切换active的class的检查灵敏度,取值1,2,3越高越灵敏,默认为2 //需要展示的数据, name是展示名称,其他数据可以放入每个{},回调时会把选中的数据原样返回