按月归档:2015年十二月月

CSS滑动下划线

搜集翻译了一些下划线的动态效果,感觉可能什么时候会用,这里贴一下~请使用现代浏览器查看效果。

主要就是使用了CSS的:after伪类,再加上一些transition动画效果,设置设置宽度高度,左右距离好像就完事儿了……

下划线从上到下出现

鼠标放上去,你会发现下划线“生长”出来了,不过页面所有的内容也往下走了3像素,这样视觉效果不是很好,你可以将它设置一下绝对定位(就好像下面的那个例子)或者用一个固定高度的容器包裹一下它。

下划线从下到上出现

这个就是使用绝对定位的效果。

下划线从左到右出现

下划线从右到左出现

下划线两边伸展

下划线滑进滑出

下划线反向滑进滑出

博客搬了个房间……

博客没有搬家,只是搬了房间。

前两天主机商联系我,说我的空间占用了大量的服务器资源,需要给我搬个服务器观察观察(羁押候审?),我正觉得空间慢了不少,忙不迭地答应了。

话说我一直安安静静的码一些文字,怎么会做出破坏环境的事情呢?前段时间为了加快访问速度,减轻服务器压力,还安装了缓存插件的说。

不管怎么说,搬就搬咯,然后还换了IP,使用了什么智能解析DNS,花了两天,不知道哪里有问题,还是时不时打不开,不得已我把IP写到Hosts里去了……换IP会不会降权重哇,虽然我也不在意这个事情,(-__-)b

现在访问好像快了一些,新服务器人居环境不错。如果有朋友出现时不时打不开页面的情况,请千万留言告知,我好去找主机商理论。万一连留言都留不了,那么请邮件eyehere艾特sian.com吧。万一页面一直打不开都看不到这篇文字,那……

好像本地的电信DNS还是没有更新,一直打不开,咋整哪~~~

ReactJS小记(2)

上一次我们简单的新建了一个组件,不过这个组件实在太简单了,根本无法把Components的优点表达出来,更主要的是,这个组件完全是静态的,这么一来,我们不如直接写HTML好了呀。

Props属性

props用于定义在新建组件时的属性,在组件的代码中,我们可以使用this.props来获取,光这么说太过抽象,我们来关门放代码……

运行它,我们可以看到原来的world被新建组件时传入的xishui所代替(居然想代替世界好大的胆子:-)。

组件的嵌套

在React中,一旦你创建了一个组件,你就可以把它当作一个标准的html标签用了,什么意思呢?我们上面的组件是用标准的<div>创建的,而事实上,我们完全可以使用另外的组件来创建一个新的组件!

好复杂好复杂,我们创建了四个组件呢,其中CommentBox用到了CommentList和CommentForm,而CommentList又用到了Comment,这样嵌套的使用组件也是完全么有问题的!事实上你也应该学会这么使用。

  • CommentBox – 最高级的组件,展示了整个留言App的界面
  • CommentList – 留言列表组件,调用Comment组件
  • CommentForm – 留言框组件,用于接收用户输入
  • Comment – 留言组件,用于展示一条留言
20151216151714

执行效果的话,就是这个样子

顺便看看Comment中,我们还用到了一个this.props.children,这是一个特别的属性,代表了书写组件标签内部的所有内容。

事件和状态

我们知道了Components初始化的时候传入的参数可以使用this.props来获得,但是这好像并没有多少改善吧……因为传入的数据不是一成不变的啊,Web页面或者说Web的UI就是要发生改变才有趣嘛。

再给大家介绍一位小兄弟this.state,事实上他可能比this.props更为重要,因为State是保持组件现有数据的一个属性,当你使用setState方法设置state属性的时候,React就会触发刷新UI的动作。如果你想在组件初始化的时候设置一下state,记得使用getInitialState。我们还是用一个例子来说明一下这个东西。

CommentBox又变复杂了一点,我们还增加了一个自定义的方法,用来增加count的值,而为了调用这个方法,使用了很常规的按钮,注意这里的onClick大小写要正确,包括<br />也要正确闭合,因为JSX是一种XML,无法适应html宽松的写法,我们要严格一些才行。

上面的效果就是,点一下按钮,comments的数量就会+1,当然改的只是那个数字,留言本身的条数还没有变化。

其实有件事情一开始出现了,我一直忍住没说……所有涉及到Components的属性或者方法的地方,我们都用了{}来包裹,这也是React的规定,如果不这么写,编译器很难判断这个到底是个表达式还是一个字符串。

有了getInitialState,有没有getInitialProps呢?否则如果新建Components的时候没有传入值想用默认的怎么办?你说的没错,React有这么一个东西,不过名字叫getDefaultProps,其实也很好理解,属性是默认的,状态是初始化后才有的。

除了HTML中的一些事件,React还专门为Components加了几个事件,事实上这也是组件生命周期上几个事件,罗列如下:

  • componentWillMount – 在第一次挂载的时候执行。
  • componentDidMount – 在第一次挂载完成后执行,这是一个用来加载远程数据的好地方。
  • shouldComponentUpdate – 每次重新渲染前执行,可以返回一个false值来阻止UI更新。
  • componentWillUnmount – 在挂载取消前执行。

我们再来为我们的程序引入更多的活力,那个CommentForm不是还空空如也么,就在这里开刀:

不得不说,与Angular的双向绑定相比,这个写法还是有点麻烦的……我们为文本框绑定了change事件,每次都捕获用户的输入,然后设置回去;我们同时捕获了表单的提交事件,阻止浏览器的默认提交动作,然后将用户输入的东西打了出来。

再来看看最常用的循环表示一个列表是怎么做的,CommentList里的数据还都是写死的,用一个变量来表示吧:

React中对于数据的循环并没有引入一些自定义的方法,而是纯粹是用了JS原生方法,当然如果你对map不熟悉,使用for循环也是可以的(这样的话{}里可以调用一个函数,这个函数的返回值就是拼接的结果)。

有一个注意点是Comment属性里我们加了一个key,这是React推荐的做法,当提供一组循环的组件时,最好为每一个子组件带上唯一的key值,如果你不这么做,React会给出一个警告。我们这里简单的使用了index来作为key,其实不是一个好方法,最好每个comments里每一个元素都有自己的标识(就好像数据表里的主键),不过这里为了简单,我们暂时这么写。

好了,我们都知道下面要做什么了,这么几个组件得有机的结合起来才行——当我们在CommentForm中输入一点什么的时候,我们希望把输入的东西加到CommentList中去。这里牵涉到组件之间的相互关联,我们看看React是怎么解决这个事情的。注意上方的CommentList将数据直接自己保管了,为了通讯上的方便,我们应该把数据交给最高层的CommentBox来管理;而不同层级间方法的调用,我们其实可以使用props值之间传入方法。为了方便对比纠错,把babel代码全部粘上:

最终效果如下图:

react-comment-box1

好了,现在我们已经学习了React的一些基本概念了,包括JSX,组件,以及一些常见的API。我们最后做了一个本地的Web App(数据都是存放在js变量里的),如果您有一些ajax的基础,可以很容易的把它改写成与服务器同步的应用。

下一次我们来说说React的一些更深层次的东西,大概会是Flux或者React编程思想吧(笑)。

在行内css中书写伪选择器:hover

我们知道直接写style可以把css属性直接作用到一个元素上,但是如果这个元素有:hover怎么办呢?还是只能写style吗?查看CSS的标准,你会发现这么一段描述:

Setting properties on a source anchor for each of its dynamic states, using pseudo-classes:
<a href=”http://www.w3.org/”
style=”{color: #900}
:link {background: #ff0}
:visited {background: #fff}
:hover {outline: thin red solid}
:active {background: #00f}”>…</a>

上面这个标准给了我们一个新天地,原来用大括号把自己的css括起来,后面就能自由发挥啦……

是不是很高兴?高兴的太早啦~~你去试试,没有一个浏览器支持这个写法(了),即便是紧跟潮流的Chrome也不例外。

为什么?不是浏览器不思进取,而是这个标准太老了……抱歉我也被忽悠了,原来这是2002年的标准,(-__-)b

所以,如今,你想在inline css中输入pseudo-selector是不行的,这种伪选择器如今只存在与CSS的上下文里面,如果我一定在元素的属性里完成这个事情该怎么办?你懂的,使用js吧……

好没营养的一篇文章……

ReactJS小记(1)

坑永远不嫌多的,记得之前说过要更新EmberJS教程的,但是最近感觉React如日中天,就连Angular也难掩其光辉,React Native出来后更是如此,虽说是两个东西,但是两者还是有很多共通之处的,React Native入手之前,学习学习ReactJS总是没错的,所以……来挖这个坑吧!

话说Twitter贡献了个Bootstrap,Facebook贡献个ReactJS(当然我知道他们贡献的远远不止这些),两个“不存在”的网站,都干的不错嘛~

React的教程不少,甚至有官方文档的中文翻译了,不过现在React已经更新到0.14.3了(2015/12/15),翻译的教程依然停留在0.13。而0.14后,react有了比较大的变化,可能让下载了新的库却又面对着旧的文档的同学有些不知所措。虽然老的写法可能还是有效的,但是官方已经不推荐那么写了,而且0.15后可能会剔除兼容的写法,所以还是跟随官方来吧。

本系列教程以最新的0.14.3为模板书写,面向初学者,其实就是个入门,精通什么的……大家看看就好了。

在这个下载页面,可以下载最新的Starter Kit,可以理解成基本的必须文件,用这个就不用各个地方去下库了,即时解压就能用。

要去用什么JS编辑器,html的基础什么的我就不说了啊,稍微介绍一下React。

React是什么?

React是Facebook开发的一个UI库,用于制作“可重用、高交互性、带状态”的UI组件。Facebook在2013年就开源了这个东西,它的很多网站也使用这个来书写,现在的话使用React开发的网站越来越多了,Instagram.com(好吧也被墙了)就是一个完全使用React编写的站点。

React高效而灵活,它有一个特点是可以在服务端执行渲染然后传给客户端,当时一定是个很惊艳的想法,不过得益于Node.js的流行,现在很多js库都这么弄了,所以听起来也不是那么有亮点了。

React最厉害的概念其实是虚拟DOM( Virtual DOM) ,这个确实颇为新颖,直到现在这么做的UI框架也没几个,它维护了一棵表示所有节点状态的树,当数据发生变化时,React查看到底是哪些节点发生了变化,然后在页面上绘制出来。

虚拟DOM是个怎么回事?

内部一棵UI树,然后再画出来,听起来好像有点多此一举,但是实际上,在Web的世界,JavaScript很快而DOM很慢,重绘界面是很花时间的,React有一个不错的Diff算法,可以很高效的找到哪些节点发生了变化,然后只需要在界面上局部地更新那几个节点,这样其实也算一种用空间换时间的做法。事实证明,这个方法还真挺好用的……

而且不知道是不是无心插柳,虚拟DOM很好的解决了不同终端的显示问题,只要最后改一下显示的方法就行了,而内部的UI组件甚至逻辑都可以完全是一致的,React的服务器渲染也因为这个思想得到了实现,而React Native也就乐呵呵的出来吸粉了:)

开始吧

上面那个Starter Kit下载下来了吧,解压它,里面有个examples文件夹,你可以打开几个项目看看……

看完了?是不是有几个还没啥反应,那是需要后台服务器支持的,咱先不管~

上面是个最简单的React框子,仅仅是引入了react和react-dom两个库。

顺便说一下,以前react-dom是和react一起的(0.14以前),但是Facebook意识到,dom这个东西毕竟只是Web上的概念,其他的界面比如手机UI上就是没有的,所以就把React-DOM独立出来了,我们Web开发肯定要带上它,而App开发就不需要了。

React所有的组件需要挂载到一个实际的节点上,我们这里用了一个叫mount-point的div,过会儿魔法也就在这里施展。

再顺便说一下……js放在body的最后是一种最佳实践,应该大家都知道了吧?

我们来写一点react的代码

OK,执行页面,你可以看到Hello, world!了!

如果你写过一些JS代码,或者使用过一些JS的库,但又是React的初学者,相信你有海量的槽想吐,其中最有可能的一句应该就是“我去这也太麻烦了吧?!”

没错,如果使用jQuery,$("#mount-point").html("<h1>Hello, world!</h1>")就完事了,这个相比实在是太繁琐了。但如果您因此给React判了死刑,那可真是放弃了一片星辰大海啊。我们现在先来把这个例子稍微简化一丁点~

引入一个新的JS,你可以直接下下来或者使用cdn上的,http://cdn.bootcss.com/babel-core/5.8.34/browser.min.js。browser.js是什么呢?它自我介绍说是用来识别次世代javascript写法的工具,听起来好像牛气冲天哇,可别说,还真是这么一回事,我们把react代码这么改写一下。

心急的朋友立刻跳出来了,“你这个写法根本就不对,语法错误!”,不要这么急嘛,你先试试?

如果你试了还是报错,那么请检查,有没有正确引入browser.js,然后最重要的,看看script的type有没有设置正确,应该是text/babel。什么是babel,这个暂时不重要,就知道这是一种JS的模板好了,我们要知道的是,这种像极了XML的JavaScript的写法,它叫JSX。JSX可是非常重要的东西,也是React引入的。以前的版本,可能是引入JSXTransformer.js,并且script标记为text/jsx,不过既然官方已经摒弃了这种用法,我们也只能随大流了,而且实际上,官方提供一个babel-cli的编译器,可以把我们的babel脚本编译成合法的javascript脚本,这个暂时先不说,以后有机会再讲,我们现在只要使用这种browser.js的方法就好了。

Components组件

当我们使用了ReactDOM的render方法的时候,第一个参数就是一个组件,第二个参数则是挂载的节点。组件可以是html标签,也就是我们上面使用的React.createElement和JSX,除此之外还有一种更为强大的React.createClass,它可以用来创建自定义组件,举个例子:

这个组件只是一个简单的div,我们创建了一个Component之后,就可以使用JSX宛若原生的HTML标签那样使用它了,为了以示区别,我们一般把自己定义的组件用大写字母开头,而原生的像div之类的,都是小写字母。

也许你会问div的class为什么写成了className,那id也要写成idName吗?事实上因为class和for是JS的关键词,所以仅有这两个属性发生了一点变化,分别是className和htmlFor,其他的还是熟悉的味道~

不过Components远没有这么简单,我们下次来说说创建组件时的一些高级点用法。