标签归档:HTML

(使用 HTML、JavaScript、Flask 或 Nginx)为丢失的图片显示默认图片

当在 HTML 页面上显示图片时,如果图片不存在,我们通常需要显示一个默认图片。

假设我们的图片路径在 /imgs 下,默认图片为 /imgs/default.jpg,下面是一些常见的处理方法示例。

Solution 1: HTML / JavaScript

最简单的,你可以使用 <img> 元素的 onerror 属性来设置默认图片:

<img src="/imgs/cat.jpg" onerror="this.src='/imgs/default.jpg'">

类似的,你也可以使用 JavaScript(jQuery)监听 img 元素的 error 事件(当图片地址无效时浏览器会触发这个事件):

$('img').on("error", function() {
  $(this).attr('src', '/imgs/default.jpg');  // 替换为默认图片
});

Solution 2: Flask

除此之外,你也可以在服务器端处理,以 Flask 为例,你可以写一个自定义视图函数来加载图片:

import os
from flask import send_from_directory

# ...

@app.route('/img/<path:filename>')
def get_image(filename):
    img_path = os.path.join(images_path, filename)  # 获取图片路径

    if not os.path.exists(img_path):  # 判断图片文件是否存在
        return send_from_directory(os.path.join(images_path, '/imgs/default.jpg'))
    return send_from_directory(img_path)

在模板里,使用这个视图函数获取图片 URL:

<img src="{{ url_for('get_image', filename='imgs/' + image.filename) }}" >

Solution 3: Nginx

在生产环境下,出于性能的考虑,我们通常会使用 Web 服务器(比如 Nginx / Apache) 来服务(serve)静态文件。以 Nginx 为例,你可以使用 try_files 指令来设置默认图片:

location /imgs/ {
    try_files $uri /imgs/default.jpg;
}

附注:本文改写自我的SO 回答

页面右侧出现空白?试试这个CSS调试器!

很多新手在写CSS会遇到很多问题,比如发现页面右侧出现了很多空白。你在网上搜索了之后,发现使用这行代码可以解决:

body, html {
    overflow-x: hidden;
}

但是虽然滚动条被隐藏了,问题并没有解决,你还是不知道是哪个元素在作怪。而且,隐藏了x向的滚动条会导致很多副作用,比如缩小浏览器后无法滚动。

调试工具

最佳的解决方法是使用一个CSS调试工具来把出问题的元素揪出来。你可以访问这个页面,点击页面第二行的链接(Click me……),然后看看发生了什么……不用担心,刷新一下,页面就会恢复正常

如果你使用Chrome浏览器,那么可以试试这个GhostPage扩展。

使用方法

你可以拖拽这个链接到你浏览器的书签栏(或是使用上面提到的Chrome扩展),然后在任一个打开的页面,都可以通过点击这个书签来查看整个页面的元素结构。比如一开始我打开知乎的主页,是这样:

知乎主页

正常的页面

当我点了这个书签,页面就变成了这样:

使用了Ghost CSS后的页面

使用了Ghost CSS后的页面

很神奇吧?

其实原理很简单,只是在页面的CSS文件里加入了这几行代码:

* {
    background: #000 !important;
    color: #0f0 !important;
    outline: solid #f00 1px !important;
}

更改所有元素的背景,颜色和边框(你可以通过修改书签的链接内容来自定义颜色)。

在你的出现右侧空白问题的页面上,你会看到有一个元素一直顶到最右边的边界,修正这个元素就可以彻底的解决问题。这样,一旦页面出现了奇怪的问题时,你就可以通过点击这个书签来检查问题。把它放到你的日常开发工具箱里吧:)

方法来自:Debug Ghost CSS Elements Causing Unwanted Scrolling

impress.js——用HTML“写”幻灯片

一、我做的幻灯片

先看一下我用impress.js做的幻灯片吧!
加载可能会有些慢。如果打不开那就看一下作者的demo吧。
注:文字摇晃的特效使用的是CSSHake,视频用Chomp(ios)制作。

 

二、概述

impress.js是一个免费开源的JavaScript库,可以用来制作非常酷的幻灯片。如果你之前接触过Prezi,肯定还记得那让人赞叹的特效吧。而impress.js就是受Prezi启发做成的。

常见的幻灯片工具有微软的PowerPoint【1】,苹果的Keyword等。不常见的有Prezi等。除此之外,还有一些通过HTML,CSS,JavaScript等前端语言制作的工具,主要有impress.jsreveal.js(这个有时间探索一下),deck.jshtml5slides。其中impress.js最让人印象深刻(impress!),使用它可以你可以制作出许多特效:三维空间的无限延伸,3D效果,任意角度的旋转,任意大小的缩放,把一页幻灯片放在三维空间的任一位置。算了,语言是苍白的,看看作者的demo吧。

虽然效果很好,但impress.js也有一些缺点:比如编辑方式太繁琐(其实是需要学的东西很多……),尤其是想要获得一些特殊效果时。总的来说,impress.js比较适合以演讲内容为主的展示(参考高桥流简报法),单页只放一个名词或句子,或是一张图片,这样会带来比较出众的效果。可以用它来做一个词云图,前提是演讲水平够好。

先泼一盆冷水,工具是为内容服务的,如果你没有什么好的内容——要么是有质量,要么有意思,那么幻灯片做的再炫也没什么用。当然,如果你只求酷炫,那当我没说。

 

三、前提要求

需要一些HTML和CSS的基础知识(会JavaScript更好),没有的话花几个小时到w3school中文)或MDN上了解一下。

按照作者在代码注释里说的,你不光得有HTML和CSS的基础知识,还得有设计的眼光。因为impress.js没有默认的风格或样式,一切都得你自己来。而且作者不希望所有的impress.js展示都像demo一样,所以,明白了方法就自己从头做起,你会体会到很大的乐趣的!

英文好的还是去看源代码吧。作者的注释很详细,也很有趣。

 

四、文件的使用

新手可能会对文件有些疑问,所以在这里说明一下。不需要可直接跳至下一节。

下载

你可以到项目的Github页面下载文件,或者直接点击这儿下载。解压后会得到一个文件夹,双击打开根目录下的index.html就可以看到作者的demo了。

 

主要文件组成

impress:

  • js
    • impress.js(JavaScript文件,提供特效支持)
  • css
    • impress_demo.css(CSS文件,提供样式支持)
  • index.html(HTML文件,幻灯片的入口,也是你写入幻灯片的地方)

 

如何“制作”幻灯片

你要做的就是创建一个HTML文件(使用文本编辑器比如Notepad++),demo对应的HTML文件就是根目录下的index.html。然后把CSS文件和JS文件引入你的HTML文件里(见“初始化”),接着把你的幻灯片按照一定的属性设置写进HTML文件里(见“创建幻灯片”)。最后用浏览器把这个HTML文件打开就可以了。

 

五、初始化

头部(head

先把文件下载下来,然后创建一个HTML文件,把下面的head放上去:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />    
    <meta name="viewport" content="width=1024" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <title>impress.js</title>
    <link href="css/impress-demo.css" rel="stylesheet" />
    <link rel="apple-touch-icon" href="apple-touch-icon.png" />
</head>

头部信息经过删改。

 

错误反馈

接下来是一个错误反馈的class,当浏览器不支持时会显示,可以改写错误信息的内容。也可以不加。

<body class="impress-not-supported">
<div class="fallback-message">
    <p>Your browser <b>doesn't support the features required</b> by impress.js, so you are presented with a simplified version of this presentation.</p>
    <p>For the best experience please use the latest <b>Chrome</b>, <b>Safari</b> or<b>Firefox</b> browser.</p>
</div>

 

编辑幻灯片区域

创建一个id为impress的div,待会所有的演示文稿都要放在这个div里:

<div id="impress">
</div>

 

操作提示

下面这两段分别用于在电脑和移动设备上提示用户怎么控制幻灯片:

<div class="hint">
    <p>Use a spacebar or arrow keys to navigate</p>
</div>
<script>
    if ("ontouchstart" in document.documentElement) {
        document.querySelector(".hint").innerHTML = "<p>Tap on the left or right to navigate</p>";
}
</script>

 

调用JS文件声明

这两行放在文件的最后。声明对impress.js的引用,并且初始化impress.js。

<script src="js/impress.js"></script>
<script>impress().init();</script>

别忘了关闭上面的几个标签:

</body>
</html>

点击这儿看完整的模板文件。

 

六、创建幻灯片

impress.js创建了一个三维空间,所有的幻灯片都有各自的位置坐标(x,y,z)。整个空间的中心是原点(0,0,0)。其他的幻灯片或文字都是相对于这个原点来设置位置的。(中心不一定是第一张幻灯片)

像之前提到的,所有的幻灯片都要放在一个id=impress的div里。而且所有幻灯片都使用一个div。设置幻灯片的各个参数如下:

id(可选)——可以用来表示幻灯片的顺序,格式是id=“step-N”,(比如id=”step-2″,序号为2)。如果不指定id的话,幻灯片按照代码从上往下的顺序出现
class(必须)——通常有两个值,“step”表示一个步骤,元素透明显示,“step slide”有幻灯片白色方框。

其他的调整选项都以data开头。

位置属性

data-x——表示x轴坐标
data-y——表示y轴坐标
data-z——表示z轴坐标

坐标的设置,如图所示。需要注意的是Y轴向上是负值。简单的理解就是:往右(x),往下(y),往上(z)是正值;相应为负值。

坐标

坐标方向

常用效果

data-rotate——表示旋转,分别有data-rotate-x,data-rotate-y和data-rotate-z(同data-rotate),值表示旋转的度数。正值表示按照相应的轴顺时针旋转,负值则是逆时针。
data-scale——表示幻灯片的大小,如data-scale=”4″表示比其他幻灯片大四倍

 

不常用属性

data-transition-duration——幻灯片切换的时间,默认为1000,单位为ms(1000ms=1s)

data-perspective——表示视角,设为0则取消3D效果。默认为1000。更改前最好知道你在干什么,详情见:https://developer.mozilla.org/en/CSS/perspective

 

示例

第一个div创建了一个有白色底框的幻灯片,位置在第四象限,沿x轴顺时针旋转90度。文本是100px大小的“Hello, world!”。

    <div class="step slide" style="font-size:100px" data-x="0" data-y="0">
        <q>Hello, World!</q>
    </div>

 

第二个div创建了一个透明的幻灯片,位置在第一张幻灯片的右上方,绕z轴旋转90度。

    <div class="step" data-x="2000" data-y="-2000" data-rotate-z="90">
        <q>Hello, You!</q>
    </div>

第三个div创建了一个透明的幻灯片,位置在第二张下方。

    <div class="step" data-x="2000" data-y="-2000" data-z="-5000" >
        <q>Hello, Boy!</q>
    </div>

第四个div创建了一个透明的幻灯片,位置在第三张绕y轴旋转90度的地方,2倍大小。

    <div class="step" data-x="-2000" data-y="-2000" data-z="-5000" data-rotate-x="180" data-scale="2">
        <q>Hello, Girl!</q>
    </div>

点击这里查看这四张幻灯片的效果。

 

全景图

最后一个div是一个全景图:

    <div id="overview" class="step" data-x="3000" data-y="1500" data-scale="10">
    </div>

以上这些属性可根据需要调节,只有xy坐标是必须的

 

七、插入媒体问题

使视频和音乐在进入幻灯片时自动播放

html5可以使用<video>和 <audio>标签插入音视频,控制方式有三种:

controls

显示视频控制条

loop

自动播放,循环播放

autoplay

 自动播放

代码如下:

<video width="320" height="460" autoplay>
    <source src="video/test.webm" type=video/webm>
</video>

音频的代码类似,只要去掉宽高设置,更改文件的type就可以了。

在impress.js中,把视频标签放入DOM限制了媒体的autoplay。这时我们可以在impress.js中插入这段代码:

var videoStep = document.getElementById("video-step");
var video = document.getElementById("video");
videoStep.addEventListener("impress:stepenter", function(){
    video.play();
}, false);
videoStep.addEventListener("impress:stepleave", function(){
    video.pause();
}, false);

代码解释:

1~2行:设置了两个变量,分别代表幻灯片和视频文件,后面分别填上相应的id。
3~5行:监听当前幻灯片上的事件,如果进入幻灯片就执行相应的函数(即播放视频文件)
6~8行:同3~5行,这次是设置离开幻灯片时执行的函数(即暂停视频文件)。

然后把有视频的那张幻灯片的id设为video-step,视频的id设为video。

<div id="video-step" class="step" data-x="-50000" data-y="2000" data-z="-60000" data-scale="6">
    <video id="video" width="420" height="340" autoplay>
        <source src="video/IMG_1254.webm" type="video/webm">
    </video>
</div>

这样视频就可以在进入到那张幻灯片时开始播放,进入下一张幻灯片时就自动暂停了。

 

一张幻灯片里放入多个视频或音频

以放两个视频为例:

第一步:
在上面那段JS代码里定义两个视频文件的变量(比如video1,video2):

var video1 = document.getElementById("video-1");
var video2 = document.getElementById("video-2");

第二步:
进入幻灯片时执行的函数变更为:

videoStep.addEventListener("impress:stepenter", function(){
    video1.play();
    video2.play();
}, false);

离开幻灯片时执行的函数相应修改;

第三步:
HTML文件设置相应的id。

 

在不同幻灯片里分别放入视频

以在三个幻灯片中放置视频为例:

  1. 在impress.js重复插入三个上面那段代码;
  2. 改掉变量名称(videoStep和video);
  3. 相应地更改其他位置的变量名;
  4. 修改相应的id名称(video-step和video);
  5. html文件设置相应的id。

插入音频的方法,以此类推。

 

背景音乐

上面的方法只适合在某一页幻灯片上放置媒体,而如果想要全程播放背景音乐的话,就可以把audio标签放在整个编辑幻灯片(id为“impress”)的div之外。同时,你还可以在任一页控制背景音乐的暂停与播放。方法相同,也是插入上面那段JS代码,更改相应的变量和id,然后设置相应的操作,具体见上面那段代码的解释。

 

编辑JavaScript

我还没开始学JavaScript,能给的建议就这几点:

  1. 保持相同的缩进;
  2. 语句后加上分号;
  3. 变量名不能重复;
  4. 另外,HTML里的ID也不能重复

 

八、头脑风暴

把impress.js和其他的前端工具搭配使用,你会获得更加有趣的效果,比如reveal.js的作者推荐的许多有趣的前端项目。再比如CSShake(可以让文字或图片实现各种摇晃效果),参考我之前写过的介绍示例页面。或者是做出一个词云图来,都是很好的创意。当然,你得会演讲。

impress+word cloud

impress+word cloud

像demo里说的,唯一的限制就是你的想象力,快去探索吧!

 

九、Last but not least

把作者的最后一大段注释翻译过来吧:

“现在,完成你第一个impress.js幻灯片的所有知识,你差不多都有了。但是在你开始之前……
啊,你已经从Github复制了代码?
你已经打开编辑器粘贴了上去?
快停下!
幻灯片不是这样做的。这些只是代码。实现这些创意之前你得在心里完成它们。

如果你想做出好的幻灯片,就拿出铅笔和纸。关掉电脑。打个草稿,写写画画,通过头脑风暴把你的创意在纸上展现出来。试着把你想展示的东西做出个思维导图。这会让你离待会你要用impress.js实现的排版越来越近。只有当你把你的展示在纸上做好了,再回到代码前。太早写代码没什么用,因为那样你只会把你的时间浪费在和没用的点坐标搏斗上。

如果你觉得我疯了,那么请你把你的手放在一本叫做《展示的哲学》(”Presentation Zen”)的书上。这本书完全是关于如何创建让人赞叹和着迷的幻灯片的。

好好想想,如果你没有什么有趣的东西要表达,impress.js可能帮不了你什么。”

 

十、附录

作者的Twitter:@bartaz
项目Github地址【https://github.com/impress/impress.js

 

注释

1】因为大部分人都会用“PPT”代称幻灯片,可是“PPT”本身指的是用微软的演示文稿工具PowerPoint做出来的幻灯片(其生成的文件格式默认为ppt),而英文里这个在做展示/报告(Presentation/Slide Show)时用的东西一般称作Slide,翻译过来是幻灯片或是演示文稿。本文统一称为幻灯片。