Zhang Xiao

Zhang Xiao

45 posts published

📍 beijing
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:

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是展示名称,其他数据可以放入每个{},回调时会把选中的数据原样返回

jQuery

jQuery 插件开发基础篇

在前端框架漫天飞舞的时代,作为一个刚入前端坑不久的小白来说真的无所适从啊。。当然自己也在项目里尝试使用了MVVM类的框架,因为感觉数据驱动可以让我少些很多DOM操作的代码,效率提高很大(其实就是我DOM操作用的不熟哈哈哈)。。。嗯嗯偏题了,关于我眼中的前端,会在另一篇好好总结下,这篇主要来学习一下jQuery插件。 很多人都会说用原生js牛逼,用jQuery的多low,然而我并不同意,我觉得应该是js基础很重要,jQuery也是应该好好学习的,并不是一定要用自己造的轮子,jQuery是好好的轮子放在那里让我们学习和使用,不仅提高我们效率也让我们从中学习到很多处理问题的思路和想法,何乐而不为?还有最近很多jQuery要死,MVVM永生的论调我也是不同意的,在原生js没有提供很好的DOM操作标准之前,jQuery还是将长期存在的,MVVM减少了我们的DOM操作并不代表我们不需要DOM操作(MVVM主要减少的是数据类的DOM操作,其他表现类的操作还是它不擅长的,所以两者结合起来有何不可,虽然有人说不伦不类,但是新事物不一定非要替代旧事物,而应该是各取所长嘛。。个人之见咯)好啦。。又扯淡多了。。切入正题。 为什么突然想到研读一下这个问题呢,因为我还真没写过插件。。可能写过也不算不上哈哈哈。。确定目标后然后我就开始百度谷歌的一通乱搞,发现每个人都有每个人的写法和理由,一时间脑子里乱乱的,哎~突然想到与其太混乱还不如去官网看看官方推荐的写法应该是靠谱的哈哈,写法先了解一种嘛,体会个中思想才是重要的。 jQuery Object Method $("a"

js

js 数组用 for in 循环

今天写数组循环的时候隐约觉得不管object还是array都用forin循环不就得了,写的还少。。哈哈,不过好像在哪里看过不要这样做,查了下资料,综合一下原因,不要使用forin循环数组哦。 数组是跳跃型的 var a = []; a[5] = 5; for (var i = 0; i < a.length; i++) { //会按预想从零循环到5 } var a = []; a[5] = 5; for (var x in a) { //只会循环index5。。。。。 } 数组被添加了其他属性 Array.prototype.foo = 1; var a = [1, 2, 3, 4, 5]; for (var x in

css

图片不失真自适应水平垂直居中

想到了一个问题 今天在浏览网页的时候看到一种布局突然就想它是怎么实现的呢,看来下发现不是css实现的,是用js实现的觉得如果没有js帮忙呢,就尝试用css看看能不能实现,发现自己基础真的要好好补下了。。哈哈,anyway,需求如下: 图片在屏幕上方块中水平垂直居中 图片宽度和高度都是不确定的 图片宽度和高度自适应其容器,宽度和高度随着容器变化而变化,这时需保证宽高比不变即图片不被拉长或压缩;还需保证宽度和高度都不能超过原始值的大小,这样图片不会失真 尝试实现一下 常见的未知高度的垂直居中的方法选一种就好了。而不失真自适应的原理就是利用我不太常用的max-width: 100%; max-height=100%; 来保证第三条的实现。如果图片的实际宽或高超过了其容器,因为有上面max的限制,浏览器就会按照其容器的宽或高来限制其超出容器。因为图片高度和宽度都没有设为固定值,则他们的比例一直保持着。如果图片的实际宽或高没有超过其容器,则按原始大小呈现,即便容器再变大图片也不会受影响,自然不会变大失真了。有点儿绕。。。表达能力真作急。。。 代码如下: <div class="block"> <div class="pic-wrapper"> <