admin 发布于 04月28, 2017

【译】何时需要文档兼容模式(IE)

原文:http://www.zcfy.cc/article/103

Windows Internet Explorer的每个主要版本都会增加新功能,目的是让浏览器更好用、更安全、更符合行业标准。随着功能的增多,很多旧网站面临无法正确显示的风险。本文介绍Windows Internet Explorer近期版本的变化情况,以便大家明白为什么需要文档兼容模式。

如果你想简单,给网页添加HTML5文档声明就行了,这样所有支持的IE都会以标准模式显示它。更多信息,请参考Defining document compatibility.aspx)。

为了把风险降到最小,Microsoft Internet Explorer 6允许开发者选择Internet Explorer解释及显示网页的方式。默认是老旧模式(Quirks mode),就是让用户好像在使用旧版本浏览器(如IE5.5)查看网页一样。还有标准模式(也叫严格模式),使用最新的行业标准显示网页。而为了利用这一点,网页需要包含相应的<!DOCTYPE>.aspx)指令。

如果网页不包含<!DOCTYPE>.aspx)指令,IE6会以老旧模式显示它。如果网页包含了有效的<!DOCTYPE>指令,但该浏览器不认识,IE6会以标准模式显示它。因为当时很少有网页包含<!DOCTYPE>指令,所以这种兼容性切换效果非常好。因为这样开发者就有时间从容地决定什么时候迁移到标准模式。

过了一段时间,很多网站都依赖标准模式了。这些网站还会使用Internet Explorer 6的特性和行为来识别Internet Explorer。比如,Internet Explorer 6不支持通用选择器.aspx),于是一些网站就利用这一点,专门为Internet Explorer提供特殊内容。

Windows Internet Explorer 7新增的功能旨在更加全面地支持行业标准,例如支持通用选择器.aspx)。由于<!DOCTYPE>.aspx)指令只支持两种情况(老旧模式和标准模式),IE7标准模式就取代了IE6标准模式。

结果,那些依赖IE6标准模式(比如不支持通用选择器)的网站,就无法再检测IE的这个新版本。换句话说,原来专门给IE准备的内容就发不到IE7了,结果就是这些网站不能按预期效果显示。由于IE7只支持两种兼容模式,网站所有人被迫升级自己的网站去支持IE7模式。

Windows Internet Explorer 8增加了一些从未来标准中特选的功能,虽然是标准功能但还没有尘埃落定。由于某些功能的行为与之前发布的标准不完全相同,因此有必要让开发者选择自己的网页想支持哪个标准。于是 IE8引入了一个新概念,叫“文档兼容性”(document compatibility),允许开发者指定网站想要支持的IE的一个或多个版本号。文档兼容性给IE8增加了新的模式,比如IE8标准模式。

Windows Internet Explorer 9加入了更多对未来标准的支持,包括HTML5、CSS3、Scalable Vector Graphics (SVG) 1.1 (Second Edition),等等。由于当时这些标准还在制定过程中,某些行为后来发生了变化,而IE9在这些标准发布时都支持了最新的行为。正如你所料,这些行为只有在IE9标准模式下才能使用。

Internet Explorer 10支持更多的标准.aspx),同时也升级了老旧模式,以便与HTML5规范中描述的变化对应。而这也意味着,此时的老旧模式也支持标准模式下的很多特性。更多信息,请参考Interoperable HTML5 Quirks mode in Internet Explorer 10

如果你的网站在IE中显示不正确,要么重写网页以支持最新Web标准(推荐),要么就强制让新版本IE像旧版本一样显示网页。后一种情况下,可以使用meta.aspx)元素,在页面头部区域增加X-UA-Compatible属性。更多信息,请参考Specifying legacy document modes.aspx)。

相关内容

英文原文:https://msdn.microsoft.com/en-us/library/jj676916(v=vs.85).aspx

阅读全文 »

admin 发布于 10月17, 2016

【译】CSS伪类与伪元素完全指南

原文:http://www.zcfy.cc/article/239

刚开始从事Web设计时,我犯了很多错误,也因此获得了进步。那时候没有Smashing MagazineCan I Use CodePen,也没有其他我们现在常见的工具。只要有人能告诉一个设计思路,特别是CSS前沿方向的,那就谢天谢地了。

今天我的经验已经很丰富了,所以想本着友好、随意、探讨的原则,跟大分享一下CSS中的伪类和伪元素。

如果你已经是有经验的Web设计者和开发者了,那么一定对本文要讨论的伪类和伪元素有所了解。不过,还是建议你先看看本文后面完整的列表,看有没有一两个你还不知道的?

在真正开始之前,因为我们想讲伪类和伪元素嘛,所以先问个基本的问题:你知道这里的“伪”是什么意思吗?不确定的话,可以参考Dictionary.com的定义

形容词

1. 不是真实的但有其外观;伪装的;假的或欺骗的;骗人的。

2. 差不多,很接近,或尽可能一样。

不用管W3C是怎么定义的,反正伪类就是某个元素的一种虚拟状态,或者说一种特有的性质,这种状态或性可以通过CSS捕捉到。常见的伪类有::link:visited:hover:active:first-child:nth-child。当然这只是一少部分,一会儿我们都会介绍。

伪类是一个冒号(:)后跟伪类的名字构成的,有时候名字后面还会有一个放在括号里的值。:nth-child是第几个?

好了,再说伪元素。伪元素是一种虚拟的元素,CSS把它当成普通HTML元素看待。之所以叫伪元素,就因为它们在文档树或DOM中并不实际存在。换句话说,我们不会在HTML中包含伪元素,只会通过CSS来创建伪元素。

以下是几个常见的伪元素::after:before:first-letter。伪元素会在本文后面介绍。

伪元素是一个冒号还是两个冒号?

简单回答:多数情况下,都行。

两个冒号(::)是CSS3为了区分::before::after这样的伪元素和:hover:active等伪类才引入的。除了IE8及以下版本,所有浏览器都支持两个冒号的伪元素表示法。

不过,有些伪元素只能使用两个冒号,像::backdrop

我个人使用一个冒号,为了跟以前的浏览器兼容。当然,不用两个冒号不行的时候,还是要用两个冒号。

这里没有对错,完全看你个人喜好。

不过,我在写这篇文章时查了一下,规范建议使用单冒号表示法,原因也是向后兼容:

请注意CSS3中表示伪元素使用双冒号,比如a::after { … },这是为了与伪类区分开。伪类应该是在CSS中经常出现的。不过,CSS3也允许单冒号的伪元素,目的是向后兼容。我们也建议暂时使用单冒号。

如果伪元素同时支持单、双冒号的形式,本文标题会给出两种形式。如果只支持双冒号,那就只有一种形式。

什么时候使用(不使用)生成的内容

通过CSS生成内容需要用到CSS属性content和伪元素:before:after

其中的“内容”(content)可是纯文本,也可以是一个容器,通过CSS操作来显示某种图形或者装饰性元素。本文只介绍第一种内容,即文本。

重要的内容可不要使用生成的内容,原因如下:

  • 屏幕阅读器读不到它
  • 无法选中
  • 如果为了装饰而在生成内容中使用了多余的内容,那么支持CSS生成内容的屏幕阅读器会大声地把它读出来,导致用户体验更差

CSS生成的内容只适用于装饰性、不重要的内容,但也要确保屏幕阅读器能够适当处理它,让使用这些辅助技术的用户不至于分心。这里适用“渐进增强”原则。

Smashing Magazine上,Gabriele Romanato为此写过一篇非常棒的文章

实验性伪类和伪元素

实验性的伪类和伪元素,指的是那些不稳定或没最终定案的伪类和伪元素。它们的语法和行为还可能有变。

不过,加上厂商前缀就可以使用这些实验性的伪类和伪元素。可以参考Can I Use,以及一些自动加前缀的工具,比如-prefix-freeAutoprefixer就是必备的。

本文会在实验性的伪类和伪元素的名字旁边加上“experimental”标签。

全部伪类和伪元素(按字母顺序)

  • :active
  • ::after/:after
  • ::backdrop (experimental)
  • ::before/:before
  • :checked
  • :default
  • :dir (experimental)
  • :disabled
  • :empty
  • :enabled
  • :first-child
  • ::first-letter/:first-letter
  • ::first-line/:first-line
  • :first-of-type
  • :focus
  • :fullscreen (experimental)
  • :hover
  • :in-range
  • :indeterminate
  • :invalid
  • :lang
  • :last-child
  • :last-of-type
  • :link
  • :not
  • :nth-child
  • :nth-last-child
  • :nth-last-of-type
  • :nth-of-type
  • :only-child
  • :only-of-type
  • :optional
  • :out-of-range
  • ::placeholder (experimental)
  • :read-only
  • :read-write
  • :required
  • :root
  • ::selection
  • :scope (experimental)
  • :target
  • :valid
  • :visited
  • Bonus content: A Sass mixin for links

好啦,诸位,好戏开场了!

伪类

首先,我们讨论伪类,从状态伪类开始。

状态伪类

状态伪类通常出现在用户执行某个操作的情况下。在CSS里,“操作”也可以是“无操作”,比如尚未点过的链接。

下面就有请它们一个一个地上场。

:link伪类表示链接的正常状态,选择那些尚未被点过的链接。建议在其他链接相关的伪类之前声明:link,它们的顺序为::link:visited:hover:active

a:link {
    color: orange;
}

当然,这个伪类也可以省略:

a {
    color: orange;
}

:VISITED

:visited伪类选择点过的链接,应该声明在第二位(在:link之后)。

a:visited {
    color: blue;
}

:HOVER

:hover伪类在用户指针悬停时生效。而且它不只可以用于链接。

它应该在第三位(在:visited之后)。

a:hover {
    color: orange;
}

看示例:http://codepen.io/ricardozea/pen/vGEzJK

:ACTIVE

:active伪类选择被鼠标指针或触摸操作“激活的” 元素,也可以通过键盘来激活,就像:focus伪类一样。

:focus类似,但区别在于:active只发生在鼠标被按下到被释放的这段时间里。

它应该在第四位(在hover后面)。

a:active {
    color: rebeccapurple;
}

:FOCUS

:focus用于选择已经通过指针设备、触摸或键盘获得焦点的元素,在表单里使用得非常多。

a:focus {
    color: green;
}

或者:

input:focus {
    background: #eee;
}

扩展内容:Sass中针对链接的混入

如果你用过CSS预处理器,那应该对这一部分感兴趣。

(如果你不熟悉CSS预处理器,没问题,跳过这一节,直接看下一节吧。)

为了简化CSS编码工作,这里介绍一下创建一组基本的链接样式的Sass混入(mixin)。

这里的混入没有默认参数,因此我们必须以一种友好的方式,声明链接的全部4种状态。

:focus:active伪类的声明通常在一块,当然也可以给它们分开。

注意这个混入不仅仅适用于链接,而是适用于任何 HTML元素。

这就是我们定义的混入:

@mixin links ($link, $visited, $hover, $active) {
    & {
        color: $link;
        &:visited {
            color: $visited;
        }
        &:hover {
            color: $hover;
        }
        &:active, &:focus {
            color: $active;
        }
    }
}

使用方法:

a {
    @include links(orange, blue, yellow, teal);
}

编译结果:

a {
  color: orange;
}
a:visited {
  color: blue;
}
a:hover {
  color: yellow;
}
a:active, a:focus {
  color: teal;
}

看示例:http://codepen.io/ricardozea/pen/wMyZQe

结构化伪类

结构化伪类选择通过其他选择符无法选择的文档树或DOM中的其他信息。

:FIRST-CHILD

:first-child伪类选择父元素的第一个子元素。

在下面的例子中,只有第一个li元素的文本是橙色的。

HTML:

<ul>
    <li>This text will be orange.</li>
    <li>Lorem ipsum dolor sit amet.</li>
    <li>Lorem ipsum dolor sit amet.</li>
</ul>

CSS:

li:first-child {
    color: orange;
}

:FIRST-OF-TYPE

:first-of-type伪类选择父元素容器内任意类型子元素的第一个元素。

在下面的例子中,第一个li元素和第一个span元素的文本才是橙色的。

HTML:

<ul>
    <li>This text will be orange.</li>
    <li>Lorem ipsum dolor sit amet. <span>This text will be orange.</span></li>
    <li>Lorem ipsum dolor sit amet.</li>
</ul>

CSS:

ul :first-of-type {
    color: orange;
}

:LAST-CHILD

:last-child伪类选择父元素的最后一个子元素。

在下面的例子中,只有最后一个li元素的文本是橙色的。

HTML:

<ul>
    <li>Lorem ipsum dolor sit amet.</li>
    <li>Lorem ipsum dolor sit amet.</li>
    <li>This text will be orange.</li>
</ul>

CSS:

li:last-child {
    color: orange;
}

:LAST-OF-TYPE

:last-of-type伪类选择父元素容器内任意类型子元素的最后一个元素。

在下面的例子中,最后一个li元素和最后一个span元素的文本才是橙色的。

HTML:

<ul>
    <li>Lorem ipsum dolor sit amet. <span>Lorem ipsum dolor sit amet.</span> <span>This text will be orange.</span></li>
    <li>Lorem ipsum dolor sit amet.</li>
    <li>This text will be orange.</li>
</ul>

CSS:

ul :last-of-type {
    color: orange;
}

:NOT

:not伪类也叫取反伪类,它通过括号接受一个参数,一个“选择符”。实际上,这个参数也可以是另一个伪类。

这个伪类可以连缀使用,但不能包含别的:not选择符。

在下面的例子中,:not伪类选择与参数不匹配的元素。

HTML:

<ul>
    <li class="first-item">Lorem ipsum dolor sit amet.</li>
    <li>Lorem ipsum dolor sit amet.</li>
    <li>Lorem ipsum dolor sit amet.</li>
    <li>Lorem ipsum dolor sit amet.</li>
</ul>

CSS:

应用下面的CSS,除了类为.first-itemli之外的li元素的文本都是橙色的:

li:not(.first-item) {
    color: orange;
}

下面看一看“连缀”两个:not伪类。应用下面的CSS规则,除了类为.first-itemli和最后一个li,其他li都会有黄色背景和黑色文本:

li:not(.first-item):not(:last-of-type) {
    background: yellow;
    color: black;
}

看示例:http://codepen.io/ricardozea/pen/dGmqbg

:NTH-CHILD

:nth-child伪类根据元素在标记中的次序选择相应的元素。

这个伪类在CSS中是用途最广、支持也最广的。

所有:nth伪类都接受一个参数,这个参数是一个公式。公式可以是一个整数,或者关键字oddeven,或者形如an+b的结构。

对于an+b:

  • a是一个数值(整数)
  • n就是n
  • +是运算符,可以是加号+或减号-
  • b也是一个整数,但只有使用了运算符的时候才会用到

以希腊字母的英文列表为例,以下是HTML标记结构:

<ol>
    <li>Alpha</li>
    <li>Beta</li>
    <li>Gamma</li>
    <li>Delta</li>
    <li>Epsilon</li>
    <li>Zeta</li>
    <li>Eta</li>
    <li>Theta</li>
    <li>Iota</li>
    <li>Kappa</li>
</ol>

CSS:

选择第2个子元素,结果Beta会变成橙色:

ol :nth-child(2) {
    color: orange;
}

从第2个子元素起,隔一个选一个,结果Beta、Delta、Zeta、Theta和Kappa会变成橙色:

ol :nth-child(2n) {
    color: orange;
}

选择所有偶数个子元素:

ol :nth-child(even) {
    color: orange;
}

从第6个子元素起,隔一个选一个,结果Zeta、Theta和Kappa会变成橙色:

ol :nth-child(2n+6) {
    color: orange;
}

看示例:http://codepen.io/ricardozea/pen/adYaER

:NTH-LAST-CHILD

除了是从后往前选择元素,:nth-last-child:nth-child完全一样。

CSS:

选择倒数第2个子元素,只有Iota是橙色:

ol :nth-last-child(2) {
    color: orange;
}

从倒数第2个子元素开始,隔一个选一个,结果Iota、Eta、Epsilon、Gamma和Alpha会变成橙色:

ol :nth-last-child(2n) {
    color: orange;
}

从后往前,选择所有偶数个子元素:

ol :nth-last-child(even) {
    color: orange;
}

从倒数第6个元素开始,隔一个选一个,因此Epsilon、Gamma和Alpha会变成橙色:

ol :nth-last-child(2n+6) {
    color: orange;
}

:NTH-OF-TYPE

:nth-of-type伪类与:nth-child类似,主要区别是它更具体了,只针对特定类型的元素。

在下面的例子中,所有容器内的第2个p元素将为橙色。

HTML:

<article>
    <h1>Heading Goes Here</h1>
    <p>Lorem ipsum dolor sit amet.</p>
    <a href=""><img src="images/rwd.png" alt="Mastering RWD"></a>
    <p>This text will be orange.</p>
</article>

CSS:

p:nth-of-type(2) {
    color: orange;
}

:NTH-LAST-OF-TYPE

:nth-last-of-type伪类是从后往前数,其余跟:nth-of-type一样。

对于下面的例子,因为是从末尾开始,所以第1个段落会变成橙色。

HTML:

<article>
    <h1>Heading Goes Here</h1>
    <p>Lorem ipsum dolor sit amet.</p>
    <a href=""><img src="images/rwd.png" alt="Mastering RWD"></a>
    <p>This text will be orange.</p>
</article>

CSS:

p:nth-last-of-type(2) {
    color: orange;
}

相关资源

建议大家在使用:nth伪类前,一定要参考下面这两篇不错的文章:

:ONLY-CHILD

:only-child选择父元素中唯一的子元素。

在下面的例子中,第一个ul只有一个子元素,因此该子元素将变成橙色。第二个ul有多个子元素,因此其子元素不会受:only-child伪类影响。

HTML:

<ul>
    <li>This text will be orange.</li>
</ul>

<ul>
    <li>Lorem ipsum dolor sit amet.</li>
    <li>Lorem ipsum dolor sit amet.</li>
</ul>

CSS:

ul :only-child {
    color: orange;
}

:ONLY-OF-TYPE

:only-of-type伪类选择同级中类型唯一的元素,与:only-child类似,但针对特定类型的元素,让选择符有了更强的意义。

在下面的例子中,第一个ul只有一个li元素,因此其文本将为橙色。

HTML:

<ul>
    <li>This text will be orange.</li>
</ul>

<ul>
    <li>Lorem ipsum dolor sit amet.</li>
    <li>Lorem ipsum dolor sit amet.</li>
</ul>

CSS:

li:only-of-type {
    color: orange;
}

:TARGET

:target伪类通过元素的ID及URL中的锚名称选择元素。

在下面的例子中,当浏览器中的URL以#target结尾时,ID为target的文章将被选中。

URL:

http://awesomebook.com/#target

HTML:

<article id="target">
    <h1><code>:target</code> pseudo-class</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit!</p>
</article>

CSS:

:target {
    background: yellow;
}

提示: background:background-color:的简写形式,用于指定颜色时效果一样。

验证伪类

表单验证一直是Web设计与开始中最不好搞的。有了验证伪类,可以让用户填写表单的过程更平顺。

有一点要注意,虽然本节介绍的伪类都用于表单元素,但其中有的伪类也可以用于其他HTML元素。

下面就来看看这些伪类吧!

:CHECKED

:checked伪类选择被勾选或选中的单选按钮、多选按钮及列表选项。

在下面的例子中,复选框被勾选后,标签会突出显示,增加了用户体验。

看示例:http://codepen.io/ricardozea/pen/wMYExY

:DEFAULT

:default伪类从表单中一组类似元素里选择默认的元素(即“提交”按钮。——译者注)。

如果要选择表单中没有类的默认按钮,可以使用:default

注意,在表单中使用Reset或Clear按钮会招致严重的可用性问题,所以除非绝对必要再用。参考下面两篇文章:

看示例:http://codepen.io/ricardozea/pen/WrzJKO

:DISABLED

:disabled伪类选择禁用状态的表单元素。处于禁用状态的元素,不能被选中、勾选,不能获得焦点。

在下面的例子中,name输入框处于禁用状态,因此会半透明。

HTML:

<input type="text" id="name" disabled>

CSS:

:disabled {
    opacity: .5;
}

提示: 标记中是非要使用disabled="disabled",只写一个disabled属性就行了。在XHTML中,disabled="disabled"这种写法才是必须的。

看示例:http://codepen.io/ricardozea/pen/NxOLZm

:EMPTY

:empty伪类选择其中不包含任何内容的空元素。只要包含一个字母、其他HTML元素,甚至一个空格,都不算空。

关于空或非空,以下是定义:


  • 元素中没有内容或字符。元素中包含HTML注释不算有内容。
  • 非空
    出现在元素中的字符。空格也算。

在下面的例子中,

  • 第一个元素中包含文本,因此背景不会变成橙色
  • 第二个元素包含一个空格,空格也是内容,因此也不会有橙色背景
  • 第三个元素中什么也没有(空的),因此背景为橙色
  • 最后一个元素中只有一个HTML注释(也是空的),因此也有橙色背景。

HTML:

<div>This box is orange</div>
<div> </div>
<div></div>
<div><!-- This comment is not considered content --></div>

CSS:

div {
  background: orange;
  height: 30px;
  width: 200px;
}

div:empty {
  background: yellow;
}

看示例:http://codepen.io/ricardozea/pen/rxqqaM

:ENABLED

:enabled伪类选择启用的元素。所有表单元素默认都是启用的,除非在标记中添加了disabled属性。

通过:enabled:disabled可以提供视觉上的反馈,改善用户体验。

在下面的例子中,禁用后又被启用的name输入框的不透明度将变为1,同时会有一个1像素的边框:

:enabled {
    opacity: 1;
    border: 1px solid green;
}

提示: 标记中是非要使用enabled="enabled",只写一个enabled属性就行了。在XHTML中,enabled="enabled"这种写法才是必须的。

看示例:http://codepen.io/ricardozea/pen/zqYQxq

:IN-RANGE

:in-range伪类选择有范围且值在指定范围内的元素。

在下面的例子中,输入元素支持输入5~10。输入值在这个范围内,会触发绿色边框。

HTML:

<input type="number" min="5" max="10">

CSS:

input[type=number] {
    border: 5px solid orange;
}

input[type=number]:in-range {
    border: 5px solid green;
}

看示例:http://codepen.io/ricardozea/pen/XXOKwq

:OUT-OF-RANGE

:out-of-range伪类选择有范围且值超出指定范围的元素。

在下面的例子中,输入元素支持输入1~12。输入值超出这个范围内,会触发橙色边框。

HTML:

<input id="months" name="months" type="number" min="1" max="12">`

CSS:

input[type=number]:out-of-range {
    border: 1px solid orange;
}

看示例:http://codepen.io/ricardozea/pen/XXOKwq

:INDETERMINATE

:indeterminate伪类选择单选按钮或复选框在页面加载时没有被勾选的。

比如,页面加载后,一组单选按钮中没有默认或预先勾选的,或者一个复选框已经通过JavaScript设置为indeterminate状态。

HTML:

<ul>
    <li>
        <input type="radio" name="list" id="option1">
        <label for="option1">Option 1</label>
    </li>
    <li>
        <input type="radio" name="list" id="option2">
        <label for="option2">Option 2</label>
    </li>
    <li>
        <input type="radio" name="list" id="option3">
        <label for="option3">Option 3</label>
    </li>
</ul>

CSS:

:indeterminate + label {
    background: orange;
}

看示例:http://codepen.io/ricardozea/pen/adXpQK

:VALID

:valid伪类选择输入格式符合要求的表单元素。

在下面的例子中,email输入框中的电子邮箱格式是正确的,因此这个输入框会被认为有效,将出现1像素的绿色边框:

input[type=email]:valid {
    border: 1px solid green;
}

看示例:http://codepen.io/ricardozea/pen/bEzqVg

:INVALID

:invalid伪类选择输入格式不符合要求的表单元素。

在下面的例子中,email输入框中的电子邮箱格式不正确,因此这个输入框会被认为无效,将出现橙色边框:

input[type=email]:invalid {
    background: orange;
}

看示例:http://codepen.io/ricardozea/pen/bEzqVg

:OPTIONAL

:optional伪类选择表单中非必填的输入字段。换句话说,只要输入字段中没有required属性,就会被:optional伪类选中。

在下面的例子中,这个数值字段是可以选填的,因此其中的文本将为灰色。

HTML:

<input type="number">

CSS:

:optional {
    color: gray;
}

:READ-ONLY

:read-only伪类选择用户不能编辑的元素,与:disabled伪类相似,标记中使用的属性决定了使用哪个伪类。

不能编辑的元素可以用来显示预先填好、不允许修改,但又需要连同表单一起提交的信息。

在下面的例子中,文本框有一个readonly属性,因此会被:read-only伪类选中,文本将为灰色。

HTML:

<input type="text" value="I am read only" readonly>

CSS:

input:read-only {
    color: gray;
}

看示例:http://codepen.io/ricardozea/pen/Nxopbj

:READ-WRITE

:read-write伪类选择用户可以编辑的元素,适用于有contenteditable属性的HTML元素。

有时候,可以与:focus伪类一块使用以增强用户体验。

在下面的例子中,点击div元素就可以编辑其中的内容,为此可以应用特殊的样式,让用户知道自己可以编辑其中的内容。

HTML:

<div class="editable" contenteditable>
    <h1>Click on this text to edit it</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit!</p>
</div>

CSS:

:read-write:focus {
    padding: 5px;
    border: 1px dotted black;
}

看示例:http://codepen.io/ricardozea/pen/LGqWxK

:REQUIRED

:required伪类选择有required属性的表单元素。

除了通过标签中的星号(*)提示必填,也可以通过这个伪类为输入字段应用样式。这样就万无一失了。

在下面的例子中,输入框有required属性,通过这个伪类为它应用特殊样式,可以提醒用户它是必填项。

HTML:

<input type="email" required>

CSS:

:required {
    color: black;
    font-weight: bold;
}

看示例:http://codepen.io/ricardozea/pen/KVJWmZ

:SCOPE (EXPERIMENTAL)

:scope伪类适用于style标签中有scoped属性的情形。

如果页面中某一部分的style标签里没有scoped属性,那么:scope伪类会一直向上查找,直到html元素,即当前样式表的默认作用范围。

在下面的例子中,第二个section中有一个scoped样式表,因此这个section中的文本会变成斜体。

HTML and CSS:

<article>
    <section>
        <h1>Lorem ipsum dolor sit amet</h1>
        <p>Lorem ipsum dolor sit amet.</p>
    </section>
    <section>
        **<style scoped>
                        :scope {
                            font-style: italic;
                        }
                  </style>**
        <h1>This text will be italicized</h1>
        <p>This text will be italicized.</p>
    </section>
</article>

看示例:http://codepen.io/ricardozea/pen/ZQobzz

语言伪类

语言伪类与页面中包含的文本相关,与图片、视频等媒体无关。

:DIR (EXPERIMENTAL)

:dir伪类选择文档中指定了语言方向的元素。换句话说,为了使用:dir伪类,需要在标记中为相关元素指定dir属性。

语言方向目前有两种:ltr(从左到右)和rtl(从右往左)。

写这篇文章时,支持:dir伪类的只有Firefox(-moz-dir()),下面的例子同时使用带前缀和不带前缀的:dir选择符。

注意: 要用带前缀和不带前缀的选择符分别创建规则,两种选择符共享一条规则是不行的。

在下面的例子中,段落中的文字是阿拉伯文(是从右往左书写的),因此其颜色是橙色。

HTML:

<article dir="rtl">
    <p>التدليك واحد من أقدم العلوم الصحية التي عرفها الانسان والذي يتم استخدامه لأغراض الشفاء منذ ولاده الطفل.</p>
</article>

CSS:

/* 带前缀 */
article :-moz-dir(rtl) {
    color: orange;
}

/* 不带前缀 */
article :dir(rtl) {
    color: orange;
}

下面段落中的文字是英文(从左到右),颜色为蓝色。

HTML:

<article dir="ltr">
    <p>If you already know some HTML and CSS and understand the principles of responsive web design, then this book is for you.</p>
</article>

CSS:

/* 带前缀 */
article :-moz-dir(ltr) {
    color: blue;
}

/* 不带前缀 */
article :dir(ltr) {
    color: blue;
}

看示例:http://codepen.io/ricardozea/pen/adrxJy

:LANG

:lang伪类选择的元素通过lang=""属性、相应的meta元素以及HTTP首部的协议信息来确定。

lang=""属性常用于html标签,其实也可以用于其他标签。

插一句,这里通常的做法是使用CSS的quotes 属性来标记特定的语言。不过,多数浏览器(包括IE9及更高版本)会在CSS中没有声明的情况下自动添加适当的引用标记。

不过,自动添加的引用标记也可能不合适。因为浏览器自动添加的与CSS添加的还不太一样。

比如浏览器为德语(de)添加的引用标记如下:

„Lorem ipsum dolor sit amet.“

但通过CSS为德语添加的引用标签则通常如下:

»Lorem ipsum dolor sit amet.«

这两种都对。因此,使用浏览器自动添加的引用标记,还是自己通过CSS的:lang伪类及quotes属性添加,都看你的需要。

下面看看怎么通过CSS来添加引用标记。

HTML:

<article lang="en">
    <q>Lorem ipsum dolor sit amet.</q>
</article>
<article lang="fr">
    <q>Lorem ipsum dolor sit amet.</q>
</article>
<article lang="de">
    <q>Lorem ipsum dolor sit amet.</q>
</article>

CSS:

:lang(en) q { quotes: "“" "”"; }
:lang(fr) q { quotes: "«" "»"; }
:lang(de) q { quotes: "»" "«"; }

看示例:http://codepen.io/ricardozea/pen/gPJyvJ

其他伪类

下面再看看拥有其他功能的伪类。

:ROOT

:root伪类选择文档中最高层次的父元素。

在HTML中,:root伪类选择的就是html元素。但在SVG或XML等标记语言中,它可能选择不同的元素。

以下规则为HTML文档中最高层次的父元素html添加背景颜色:

:root {
    background: orange;
}

注意: 使用html也可以设置相同的样式,但:root是一个类,拥有比元素选择符(即html)更高的特指度。

:FULLSCREEN (EXPERIMENTAL)

:fullscreen伪类选择在全屏模式下显示的元素。

不过,这不适用于用户按F11进入的全屏模式,只适用于通过JavaScript Fullscreen API切换进入的全屏模式,通常由父容器中的图片、视频或游戏来调用。

怎么知道已经进入全屏模式呢?一般浏览器会在窗口顶部提示你,并告诉你按Escape键可以退出全屏模式。

使用:fullscreen伪类前必须知道,浏览器应用样式的方式差别很大。而且,不仅要在CSS中使用前缀,JavaScript中也一样。推荐使用Hernan Rajchert的screenfull.js,它帮我们填了不少浏览器的“坑”。

本文不会讨论全屏API,只给出一个在WebKit和Blink浏览器中可用的例子。

HTML:

<h1 id="element">This heading will have a solid background color in full-screen mode.</h1>
<button onclick="var el = document.getElementById("element"); el.webkitRequestFullscreen();">Trigger full screen!</button>

CSS:

h1:fullscreen {
    background: orange;
}

看示例:http://codepen.io/ricardozea/pen/ZQNZqy

伪元素

如前所述,伪元素类似一种虚拟元素,可以将其视为普通的HTML元素。但伪元素并不存在于文档树或DOM中,因此不能在HTML中输入,只能通过CSS创建。

同样,双冒号(::)与单冒号(:)也只是CSS3与CSS2.1的不同。

::BEFORE/:BEFORE

:before伪元素与:after类似,都可以为其他HTML元素添加内容(文本或图形)。同样,这里的内容并不实际存在于DOM中,但可以像存在一样操作它们。需要在CSS中声明content属性。

记住,通过这个伪元素生成的内容不能通过其他选择符选中。

HTML:

<h1>Ricardo</h1>

CSS:

h1:before {
    content: "Hello "; /* 注意Hello后面有一个空格 */
}

结果网页中会变成这样:

Hello Ricardo!

注意: 看到“Hello ”后面的空格了吗?没错,空格也算数。

::AFTER/:AFTER

:after伪元素也用于为其他HTML元素添加内容(文本或图形)。这里的内容并不实际存在于DOM中,但可以像存在一样操作它们。为了使用这个伪元素,必须在CSS中声明content属性。

同样,通过这个伪元素添加的任何内容都无法通过其他选择符选中。

HTML:

<h1>Ricardo</h1>

CSS:

h1:after {
    content: ", Web Designer!";
}

结果如下:

Ricardo, Web Designer!

::BACKDROP (EXPERIMENTAL)

::backdrop伪元素是在全屏元素后面生成的一个盒子,与:fullscreen伪类连用,修改全屏后元素的背景颜色。

注意: ::backdrop伪元素必须用双冒号。

还看前面:fullscreen伪类的例子。

HTML:

<h1 id="element">This heading will have a solid background color in full-screen mode.</h1>
<button onclick="var el = document.getElementById("element"); el.webkitRequestFullscreen();">Trigger full screen!</button>

CSS:

h1:fullscreen::backdrop {
    background: orange;
}

看示例:http://codepen.io/ricardozea/pen/bEPEPE

::FIRST-LETTER/:FIRST-LETTER

:first-letter伪元素选择一行文本第一个字符。

如果相应行前面包含图片、视频或表格元素,那么不会影响选择第一个字符。

这个伪元素非常适合对段落进行排版,有了它就不必用图片或其他技巧了。

提示: 这个伪元素也可以选中:before伪元素生成的第一个字符。

CSS:

h1:first-letter  {
    font-size: 5em;
}

::FIRST-LINE/:FIRST-LINE

:first-line选择元素的第一行,只适用于块级元素,行内元素不适用。

即使一段文本有多行,也会选中第一行。

CSS:

p:first-line {
    background: orange;
}

::SELECTION

::selection选择文档中被高亮选中的部分。

注意,基于Gecko的浏览器要求使用前面:::-moz-selection

注意: 在一条规则中同时使用带前缀和不还前缀的::selection是不行的,要分别写。

CSS:

::-moz-selection {
    color: orange;
    background: #333;
}

::selection  {
    color: orange;
    background: #333;
}

::PLACEHOLDER (EXPERIMENTAL)

::placeholder伪元素选择表单元素中通过placeholder属性设置的占位文本。

也可以写成::input-placeholder

注意: 这个伪元素不是标准的,因此将来有可能会变化。

在某些浏览器(IE10及Firefox 18之前)中,::placeholder伪元素的实现类似一个伪类。其他浏览器都将其视为伪元素。因此,除非要兼容IE10或旧版本的Firefox浏览器,因此应该这样写:

HTML:

<input type="email" placeholder="name@domain.com">

CSS:

input::-moz-placeholder {
    color:#666;
}

input::-webkit-input-placeholder {
    color:#666;
}

/* IE 10 only */
input:-ms-input-placeholder {
    color:#666;
}

/* Firefox 18 and below */
input:-moz-input-placeholder {
    color:#666;
}

小结

CSS伪类和伪元素相当有用,对不?这些伪类和伪元素提供了丰富的选择便利。

不要光看,自己动手试一试吧。广受支持的伪类和伪元素是很靠谱的。

希望大家看了这篇长文能有所收获。别忘了收藏它!

英文原文:https://www.smashingmagazine.com/2016/05/an-ultimate-guide-to-css-pseudo-classes-and-pseudo-elements/#?

阅读全文 »

admin 发布于 08月18, 2016

【译】JavaScript中该如何安排后台任务

原文:http://www.zcfy.cc/article/258

关于JavaScript,大家要牢记一点:它阻塞

想象一下,浏览器里有一个进程小精灵,负责处理一切。渲染HTML、响应菜单命令、绘制屏幕、处理鼠标点击、运行JavaScript函数……。跟我们人一样,这个小精灵每次只能做一件事。如果一次交给它很多任务,那么就会有一个待办事项列表,小精灵按顺序一项一项去处理。

小精灵在碰到script标签或者要运行JavaScript函数时,会停下其他任务。下载代码(必要时)然后立即运行,之后才会触发其他事件 ,以及渲染页面。这是必要的,因为脚本几乎什么都可能做:加载更多代码、删除DOM元素、重定向URL,等等。就算有两个甚至更多小精灵,那其他小精灵也需要在首次处理代码时停下来。这就是阻塞。这也是为什么运行时间过长的脚本会导致浏览器无响应的原因。

我们通常想让JavaScript尽快运行,因为代码要初始化部件和事件处理程序。可是,有些没那么重要的后台任务并不会直接影响用户体验,比如:

  • 记录分析数据
  • 向社交网络改送数据(或发送57个“分享”按钮)
  • 预先取得内容
  • 预先处理或预先渲染HTML

这些任务并不要求立即完成,而为了保证页面持续响应,不应该在用户滚动页面或浏览内容期间执行这些任务。

为此可以使用Web Workers,在另一个线程里并发地运行代码。这个技术非常适合预先取得和处理数据,但无权直接访问或修改DOM。你可保证自己的脚本不那么干,但却无法保证Google Analytics等第三方脚本不那么干。

还有一个选择是setTimeout,比如setTimeout(doSomething, 1);。浏览器会在立即执行的任务完成后紧接着执行doSomething()函数。实际上是把它放在了待办事项的最后一项。问题在于无论有没有处理需求,这个函数都会被调用。

requestIdleCallback

requestIdleCallback是新API,用于在浏览器空闲的时候安排一些没那么重要的后台任务。这个API会让人联想到requestAnimationFrame,后者会在下一次绘制前调用函数更新动画。具体内容可以参考这篇文章:Simple Animations Using requestAnimationFrame

可以这样检测浏览器是否支持requestIdleCallback

if ("requestIdleCallback" in window) {
  // 支持requestIdleCallback
  requestIdleCallback(backgroundTask);
}
else {
  // 不支持,换一种方式
  setTimeout(backgroundTask1, 1);
  setTimeout(backgroundTask2, 1);
  setTimeout(backgroundTask3, 1);
}

还可以通过一个选项对象参数,指定暂停时间(以毫秒计),比如:

requestIdleCallback(backgroundTask, { timeout: 3000; });

这样可以保证你的函数在三秒钟内执行,无论浏览器是否空闲。

requestIdleCallback只会调用一次你的函数,并传入一个包含以下属性的期限(deadline)对象:

  • didTimeout — 如果可选的暂停时间已到则为true
  • timeRemaining() — 函数,返回留给任务执行的毫秒数

timeRemaining()会给你的任务分配不超过50ms的执行时间。它不会让任务停止超过这个时间限制,不过你可以再次调用requestIdleCallback以安排进一步的处理。

下面看一个例子,按顺序执行几个任务。任务以函数引用形式保存在一个数组中:

// 要运行的函数数组
var task = [
  background1,
  background2,
  background3
];

if ("requestIdleCallback" in window) {
  // 支持requestIdleCallback
  requestIdleCallback(backgroundTask);
}
else {
  // 不支持,待会一次性运行所有任务
  while (task.length) {
    setTimeout(task.shift(), 1);
  }
}

// requestIdleCallback回调函数
function backgroundTask(deadline) {

  // 有可能的话运行下一个任务
  while (deadline.timeRemaining() > 0 && task.length > 0) {
    task.shift()();
  }

  // 还有未执行的任务,再次申请处理
  if (task.length > 0) {
    requestIdleCallback(backgroundTask);
  }
}

有没有什么不应该通过requestIdleCallback做的

正如Paul Lewis在他关于这个主题的博客文章所说的,requestIdleCallback应该执行小任务,不适合执行时间不确定的任务(像操作DOM,最好还是用requestAnimationFrame回调来做)。在resolve(或reject)Promise的时候也要注意,因为空闲回调完成后会立即调用Promise的回调,而不管剩下的时间还够不够执行该回调。

requestIdleCallback的浏览器支持情况

requestIdleCallback是一个实验性的API,规范仍在制定中,今后很可能有改动。Chrome 47支持它,Opera应该也会跟进。Microsoft和Mozilla都在关注它,前景不错。Apple照例没有表态。如果你现在就想试一试,最好用Chrome Canary

Paul Lewis写了一个简单的requestIdleCallback“垫片脚本”,实现了上述API的行为,但它不是一个可以模拟浏览器空闲检测行为的“腻子脚本”。他使用的是类似前面例子中的setTimeout。不过,如果你不想依赖对象检测也不想写分支代码,用这个脚本还是不错的。

虽然今天的浏览器对requestIdleCallback的支持有限,但这个API的确非常有助于提升网页性能。你对此有什么想法吗?欢迎留言。

英文原文:http://www.sitepoint.com/how-to-schedule-background-tasks-in-javascript/

阅读全文 »

admin 发布于 06月13, 2016

【译】不用jQuery实现简单的JavaScript幻灯片

原文:http://www.zcfy.cc/article/411

“我就想不用jQuery实现简单的JavaScript幻灯片”

这里所说的幻灯片,或者叫图片传送带、图片滑块、旋转图等等,是JavaScript学习者必修课之一。

本教程内容如下:

  • 不用jQuery等外部库实现简单的幻灯片
  • 理解UX和无障碍问题,包括是否该用幻灯片
  • 给幻灯片添加控件

不依赖库实现幻灯片的主要好处是页面速度会变快,因为代码少了。而且,随便用到哪里都不用担心加载外部文件的问题。

读者最好懂JavaScript,包括函数、事件、样式过渡。另外推荐大家看看我的这个尽可能只用JavaScript做一些实用的东西都要学什么的路线图

做个简单的幻灯片

HTML代码

HTML需要有个容器,容器里是幻灯片:

<ul id="slides">
    <li class="slide showing">Slide 1</li>
    <li class="slide">Slide 2</li>
    <li class="slide">Slide 3</li>
    <li class="slide">Slide 4</li>
    <li class="slide">Slide 5</li>
</ul>

CSS

CSS要做下面几件事:

  • 确定幻灯片的容器
  • 在容器里将幻灯片堆叠起来
  • 确定幻灯片长啥样以及何时显示或隐藏
  • 实现淡入淡出效果

看CSS前,请注意不要使用与你的网页可能冲突的类或ID。本文使用了简短的名字。

CSS在这儿:

/*
基本样式:
支撑幻灯片
*/

#slides {
    position: relative;
    height: 300px;
    padding: 0px;
    margin: 0px;
    list-style-type: none;
}

.slide {
    position: absolute;
    left: 0px;
    top: 0px;
    width: 100%;
    height: 100%;
    opacity: 0;
    z-index: 1;

    -webkit-transition: opacity 1s;
    -moz-transition: opacity 1s;
    -o-transition: opacity 1s;
    transition: opacity 1s;
}

.showing {
    opacity: 1;
    z-index: 2;
}

再添加一些装饰性的幻灯片样式,以下是示例:

/*
非基本样式:
想要什么样,你自己定
*/

.slide {
    font-size: 40px;
    padding: 40px;
    box-sizing: border-box;
    background: #333;
    color: #fff;
}

.slide:nth-of-type(1) {
    background: red;
}
.slide:nth-of-type(2) {
    background: orange;
}
.slide:nth-of-type(3) {
    background: green;
}
.slide:nth-of-type(4) {
    background: blue;
}
.slide:nth-of-type(5) {
    background: purple;
}

JavaScript

JavaScript做一件事:隐藏当前幻灯片,显示下一张。为此,只需改变相关幻灯片的类名。

JavaScript代码:

var slides = document.querySelectorAll("#slides .slide");
var currentSlide = 0;
var slideInterval = setInterval(nextSlide,2000);

function nextSlide() {
    slides[currentSlide].className = "slide";
    currentSlide = (currentSlide+1)%slides.length;
    slides[currentSlide].className = "slide showing";
}

下面分析一下。

  1. 先用querySelectorAll 拿到容器中的幻灯片
  2. 然后声明一个变量保存当前幻灯片
  3. 最后通过定时器每2秒(2000毫秒)切换一次幻灯片

重点看看nextSlide函数。

  • 首先,把当前幻灯片的类置为不可见(去掉showing),CSS过渡会自动实现淡出。
  • 然后给当前幻灯片加1,这里使用%运算实现到最后一张后自动归零,即回到第一张;%运算符执行两个数相除,然后取得余数。 这个运算特别适合计算时间、日历等需要循环归零的情景。我们这个例子有5张幻灯片,那么依次执行取余运算的过程就是:1%5=1, 2%5=2, 3%5=3, 4%5=4, and 5%5=0。
  • 得到当前幻灯片编号之后,再给它的类加上showing。同样,CSS不透明度的渐变会自动出现。

祝贺你,一个简单的幻灯片诞生了。

注意兼容性

CSS过渡在IE9及以下版本是不能用的,在这些浏览器里,幻灯片会简单地切换到下一张。

这个简单的幻灯片是什么效果呢,看这里:Basic JavaScript Slideshow without jQuery

用户体验与无障碍

使用幻灯片之前,先要好好想想为什么在网页里用它。如果不小心的话,幻灯片很可能给你的网页带来用户体验和无障碍方面的问题。

幻灯片可能隐藏重要内容

如果是非常重要的内容,不应该放在幻灯片里。不能指望所有人都能使用合适的浏览器,这还不算无障碍问题。

根据 美国圣母大学的一项研究,只有1.07%的人会点击幻灯片中最突出的一张图,3%甚至更少的人会点击第一张之后的其他幻灯片。这说明通过幻灯片传达重要内容有多危险。

用户可能分不清你的网站是干什么的

如果幻灯片做得非常大,那么这真是个问题。如果你都不知道向用户展示什么,还怎么指望用户做出你期望的决定? (原推文)

网站应该明确告诉用户自己需要他们干什么,如果幻灯片妨碍了你达成这个目标,那该好好反思一下。

转换率优化公司WiderFunnel曾对幻灯片的有效性做过测试,并得出如下结论:

我们多次测试了轮播图,发现通过它展示主页内容效果很差;

有空的话,真的建议读一读他们这篇文章

移动用户可能不会高兴

幻灯片会导致加载时间过长,造成界面卡顿。

什么情况下可以使用幻灯片

既然幻灯片有这么多问题,那么什么情况下可以用它呢?下面是我的一些建议。

给人一个大体的印象

如果你不在乎用户是否会注意到某张幻灯片,只是想传达一种大概的印象,可以用。这种情况下,只要用户看到一张幻灯片,目的就达到了。

幻灯片外的主要内容很容易找到

比如,可能你想通过幻灯片展示某个景点、博物馆、会议或某系列产品的图片,但网站的其他地方也准备了相应图库或产品图片的完整展示区。这时候用幻灯片还是不错的。

在渐进增强的情况下

这种情况更普遍,前提是不要因为这个非网站主要功能的装饰带来太多问题。只要它只是装饰不是障碍就好。

无障碍指南

如果幻灯片的内容比较重要,应该做无障碍处理。当然,应该首先考虑到底该不该用幻灯片。

如果你(或你的客户)坚持要用,这是一篇关于幻灯片无障碍化的文章

根据这篇文章

幻灯片要做到无障碍,必须有五个条件:

  1. 允许用户停止全部切换

  2. 为键盘、鼠标和触摸设备提供无障碍访问机制

  3. 为幻灯片提供有效、可理念的焦点顺序指示

  4. 有效的代码和样式

  5. 为幻灯片提供有意义的替换

此外,这篇文章有一位评论者给出了是否决定使用幻灯片的有用资源

为了让幻灯片无障碍,下面我们就来添加一些控件。

为幻灯片添加控件

我们要添加“暂停/播放”、“下一张”和“上一张”按钮。

暂停/播放

首先为按钮添加HTML:

<button class="controls" id="pause">Pause</button>

接下来写JavaScript:

var playing = true;
var pauseButton = document.getElementById("pause");

function pauseSlideshow() {
    pauseButton.innerHTML = "Play";
    playing = false;
    clearInterval(slideInterval);
}

function playSlideshow() {
    pauseButton.innerHTML = "Pause";
    playing = true;
    slideInterval = setInterval(nextSlide,2000);
}

pauseButton.onclick = function() {
    if(playing) {
    pauseSlideshow();
  } else {
    playSlideshow();
  }
};

以上脚本都做什么了?

  • playing变量保存着幻灯片是否在播放的状态
  • 接着把暂停按钮也保存到一个变量中
  • pauseSlideshow函数负责暂停幻灯片,并把“暂停”改成“播放”
  • playSlideshow相反
  • 最后,为暂停/播放按钮添加一个单击处理程序,用于切换暂停和播放

加了这个按钮后的效果怎么样?看这里:JavaScript Slideshow With Pause Button

下一张和上一张

还是先添加HTML:

<button class="controls" id="previous">Previous</button>
<button class="controls" id="next">Next</button>

JavaScript,把

function nextSlide() {
    slides[currentSlide].className = "slide";
    currentSlide = (currentSlide+1)%slides.length;
    slides[currentSlide].className = "slide showing";
}

改成:

function nextSlide() {
    goToSlide(currentSlide+1);
}

function previousSlide() {
    goToSlide(currentSlide-1);
}

function goToSlide(n) {
    slides[currentSlide].className = "slide";
    currentSlide = (n+slides.length)%slides.length;
    slides[currentSlide].className = "slide showing";
}

为灵活起见,增加了goToSlide函数。同时,currentSlide变量的计算也做了一点改动,目的是防止出现负值。如果你想测试,可以给slides.length一个值,看看随着n变化currentSlide会怎么样。

下面添加JavaScript,让这个按钮在被点击时干它该干的事:

var next = document.getElementById("next");
var previous = document.getElementById("previous");

next.onclick = function() {
    pauseSlideshow();
    nextSlide();
};
previous.onclick = function() {
    pauseSlideshow();
    previousSlide();
};

控制添加好了。效果如何呢?看这里:JavaScript Slideshow With Controls

为用户提供了“下一张”和“上一张”按钮,用户就不会被自动播放“欺负”了。

因为这些控件就是HTML按钮,所以可以通过键盘来操控。

至于它们的样式和位置,随便你,只要明显,能用就行。

如果你还想加上用键盘上的左、右键控制,那么要保证用户在其他地方使用这两个键的时候关闭此处的控件。

防止没有JavaScript

偶尔会碰到JavaScript加载失败、被关闭,甚至设备不支持的情况。理想的情况当然是让用户仍然可以正常使用。如何做后备取决于你的目的。可以只展示第一张图片,也可以用一个列表展示所有图片。

如果幻灯片的主要目的只是给人一个大概的印象,那么显示保持网页布局不变比展示所有图片更重要。

如果确实需要展示所有图片,那你就把它们都罗列出来呗。

这两种情况,下面都会介绍。

无JavaScript时隐藏控件

默认使用CSS隐藏控制:

.controls {
    display: none;
}

然后使用JavaScript显示控制。这样,用户会在有JavaScript的时候看到控件。

var controls = document.querySelectorAll(".controls");
for(var i=0; i<controls.length; i++){
    controls[i].style.display = "inline-block";
}

以上代码循环所有控制,把它们都显示出来。

无JavaScript时列出所有图片

首先把.slide类的CSS由position: absolute;改为position: static;。这样,默认就是列出所有幻灯片。

然后添加JavaScript循环每一张幻灯片并将它们的定位改为绝对,像下面这样(一定要把这些代码放在slides变量后面):

for(var i=0; i<slides.length; i++) {
    slides[i].style.position = "absolute";
}

这样,幻灯片在JavaScript可用时就不会列出来了。

小结一下

我们讲了怎么做一个简单的幻灯片,如果处理用户体验和无障碍问题,以及如何添加控件。

本文最重要的,是想让大家思考:到底什么时候该用幻灯片,如果你想在网页中放个什么东西,请先想一想会对用户造成什么影响,以及它对你实现目标有没有帮助。如果答案明确,再去做或不做。

你想到什么了?关于幻灯片你有没有自己的经验或教训?或者有好玩的故事?欢迎留言。

英文原文:https://www.sitepoint.com/make-a-simple-javascript-slideshow-without-jquery/

阅读全文 »

admin 发布于 06月02, 2016

【译】Web会不会重生

原文:http://www.zcfy.cc/article/244

2015年7月,受Mat MarquisTXJS 2015上发言的启发,我建议网页的平均大小应该等于经典DOC游戏Doom安装的图片大小。

大约7个月平均下来,网页大小与Doom安装的图片大小相同。我们做到了,越来越大。 pic.twitter.com/xtSAtZjPGl

— ronan cremin (@xbs) July 30, 2015

我们做到了,虽然比预期晚了一点。这是我们当前的情况:

web page size revisited revised

阅读全文 »

admin 发布于 05月24, 2016

如何在众成翻译获得打赏

众成翻译(http://www.zcfy.cc)是360最大前端团队奇舞团推出的一个在线翻译平台,今年5月10号刚刚发布了1.0版。众成翻译的目标是做国内最好的技术翻译和内容产出社区,同时力争做最懂译者的翻译平台。本周一(5月23日),众成翻译上线译文打赏功能,本文将为大家详细介绍如何在众成翻译平台让自己的译文获得读者的打赏。

概述

要获得打赏,关键是在自己译文下方显示一个(或两个)收款二维码,这样读者才能把银子给你。比如这样:

alt

因此,要获得打赏,最重要的是学会生成自己的收款二维码。众成翻译目前支持上传两个二维码,默认为微信和支付宝的。下面就来看一看怎么在这两个手机应用中生成你自己的收款二维码。

阅读全文 »