整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

XML 学习详解

XML 学习详解

习思路

1.什么是XML

Extendisble mark language 【可扩展的标记语言】

? 标记语言

HTML,XHTML,HTML5,XML

你们知不知道他们之间有什么关系吗?


? 可扩展

在HTML中 写一个表格我们使用

预定义标签,含义已经被定义好了。

标签可以自定义 ,

? 特点

XML 指可扩展标记语言,是独立于软件和硬件的信息传输工具。

XML 是一种标记语言,很类似 HTML。

XML 的设计宗旨是传输数据,而非显示数据

XML 标签没有被预定义。您需要自行定义标签。

XML 被设计为具有自我描述性。

XML 是 W3C 的推荐标准。


2.Xml的作用

总共分为两大部分:

? 数据储存

配置文件储存数据:

在一些软件:QQ,飞秋,都有配置文件的,固定参数数据储存,在一些C/S模式的软件中应用的非常多,在编程语言中,java ,net ,C#

临时表的数据储存:

在实际的项目中, 一些固定不变得数据和数据量比较少的数据我们会使用xml 来进行储存。例如:地理信息数据


? 数据交换

AJAX 角度

进行固定格式的数据交换

Webservice 网络服务

例如:查询天气,航班信息查询


二、XML结构

? 代码举例:

? 结构分析:

? 总结特点

1.必须要有根元素,有且只能有一个。

2.Xml的元素类型有三种:

元素节点

文本节点:

标签中含有文本内容

属性节点:

在节点中有属性存在,我们就说这个节点是一个属性节点


三、XML语法

1.语法总则

必须以XML声明开头

它必须拥有唯一的根元素

开始标签必须与结束标签相匹配

元素对大小写敏感

所有的元素都必须关闭

所有元素都必须正确嵌套

必须对特殊字符使用实体

2.文档声明

声明一个xml文件


<?xml version=”1.0” encoding=”utf-8” ?>
语法规则: 必须 <?xml ?>
说明 version : xml的版本,通用版本1.0
     Encoding: 字符编码格式

运行上述代码,结果如下:


注意:字符编码格式统一,xml 编码的声明,必须要和文件的格式保持一致




3.命名规则【标签元素】

为什么要有这个命名规则呢?

因为我们XML 它是一个可扩展的标记语言,标签自己定义

名称可以是字母、数字以及其他的字符

名称不能以数字或者标点符号开始

名称不能以字符“xml”(或者Xml、XML)开始

名称不能包含空格

可以使用任何名称,没有保留的字词

插脚一脚:


4.定义元素【标签】

? Xml三种节点

元素节点

文本节点

属性节点

? 元素的三种表现形式:

元素包含元素:

元素包含文本节点:

元素包含属性:

? 实例


5.定义属性

? 描述

属性他就是用来描述一些事物元素的【附加描述信息】

属性必须依附于元素来实现

? 作用

描述信息的定义

描述信息可以在属性和标签之间进行切换

? 注意使用事项

1.属性必须依附于元素来实现

2.必须定义在开始标签


6.实体引用【CDATA区】

对比人物大小如下图:

? 描述

在标签内部写字符串文本的时候,会有一些特殊的字符例如:< > 空格,等。我想需要在文本中展示出来,这个时候我们不能直接写在里面,要使用实体引用


? 实体引用

在HTML中的实体引用,

空格:



在XML中使用实体引用

如果特殊符号特别多,这个时候怎么办?

? 多个实体引用

语法:<![CDATA[data]]>

Data: 数据

使用CDATA 区 如下


7.注释

在HTML中使用注释


<!--  注释内容 -->


在XML中同样使用

注意:注释不能写在声明的开始

8.批处理指令【了解】

处理指令(PIs)允许文档包含用于应用程序的指令

处理指令很少被使用。主要用于链接 XML 文档到样式表【xml-stylesheet】

引入方法:

定义样式文件

Books.css

代码:

p{

color:red;

}

XML 实现


课堂练习:

编写xml文档,将如下所示user数据用XML的方式来保存

四、PHP解析XML

1.什么是XML的解析

其实就是将xml结构中储存的数据给提取出来, 这个提取的过程我们把他叫做解析,解析出来的内容就是,文本节点包含的内容还有属性

2.PHP解析XML方式

手册位置:

在PHP中解析XML文档,有十几种操作, 但是我们主要关注 DML操作和SimpleXML


DOM: 是XML解析通用方法,不仅适用于PHP ,也使用其他语言【操作方法和函数是一样】


SimpleXML: 是PHP语言所特有的处理方法, 将一些复杂DOM操作,进行了方法的封装,可以简单实现XML的操作


3.创建一个XML文件

? 创建步骤

1.声明文档格式

2.定义元素

3.元素结构化

? 最终代码


<?xml version="1.0" encoding="utf-8" ?>
<words>
	<word>
		<name>no zuo no die</name>
		<fayin>no zuo no die</fayin>
		<fanyi>不作死就不会死</fanyi>
	</word>
	<word>
		<name>hello </name>
		<fayin>hello</fayin>
		<fanyi>你好</fanyi>
	</word>

</words>

想操作XML必须确保xml没有任何语法错误!

4.DOM操作方式【了解】

? 实现原理

整个转换操作是在计算机内存中实现的。

? 实现思路

1.读取文档

2.获取文档内容

3.将文档的内容展示出来

? 使用语法

操作类DOMDocument

$dom=new DOMDocument(version,encoding);

说明:version 我们定义XML 是的版本,

Encoding 定义时候的编码格式

实现代码:


//读取创建的单词的xml 文档
//实例化操作对象DOM
$dom=new DOMDocument('1.0', 'utf-8');
//加载words.xml 文


? 操作方法

语法:对象模型->load(url);

说明:url 可以是据对路径也可以是相对路径

作用:加载要操作的xml文件

对象加载文件之前和文件之后区别:

? 读取节点

语法:当前对象->getElementsByTagName(‘标签名’);

作用:选中指定所有的标签

获取了所有的节点:


//加载words.xml 文件
$dom->load('words.xml');
$names=$dom->getElementsByTagName('name');
var_dump($names->item(1));exit;


从节点中获取文本内容

语法:选中的节点-> Item(0);

作用:选中具体的操作节点


//加载words.xml 文件
$dom->load('words.xml');
$names=$dom->getElementsByTagName('name');
var_dump($names->item(1));exit;

? 读取节点属性

当前节点对象->getAttribute(‘属性名称’);

? 增加节点


? 删除节点


5.SimpleXML方式【重点】

? 实现原理

? 使用语法

使用函数

Simplexml_load_file(path);

说明:path 就是要加载的文件的路径【相对路径也可以是绝对路径】

作用:1.加载xml文件

2.实例化操作类【SimpleXmlElement】


Simplexml_load_string(str);

说明:str 就是一个xml格式的字符串

作用:将一个xml格式的字符串,转换成就可以操作的对象

File_get_contents(path);


读取节点


$dom=simplexml_load_file('words.xml');
//循环读取
foreach ($dom->word as $key=> $value) {
echo $value->name;
}
Simplexml_load_string()



读取节点属性

语法:当前节点对象->attributes()

作用:获取当前节点的属性的值

创建节点

语法:操作对象->addChild(节点名称,节点内容)

语法:操作对象-asXML(‘保存的文件以及路径’);


$str=file_get_contents('words.xml');
// var_dump($str);exit;
$dom=simplexml_load_string($str);
//增加word节点
$word=$dom->addChild('word');
//增加name
$word->addChild('name', 'xiaoming');
//fanyi
$word->addChild('fayin', '小明');
//翻译
$word->addChild('fanyi', '小明');
//将追加的内容写入文件即可
$dom->asXML('words.xml');


? 删除节点

在PHP数组中我想删除某个值,使用unset($arr[1])

也是使用unset() , 但是不是unset 数组,而是对象的属性名称

? 修改操作自己完成


6.DOM和SimpleXML对比

? 实现原理对比

DOM 他是将XML文档转换成可以操作的模型【在内存中存在】,这个时候在使用DOM封装的操作对象来对这个模型进行CURD操作。

SimpleXML 它是将XML文档直接转换成对象来直接进行CURD操作


? 代码对比

六、XPATH

1.什么是XPATH

XPath是一门在 XML 文档中查找信息的语言,XPath可用来在 XML 文档中对元素和属性进行遍历。

而且Xpath并不仅仅应用于XML数据查询,其在很多语言中(PHP、Java、.NET以及Javascript),都可以广泛使用。

参考文献: @link http://www.w3school.com.cn/xpath/xpath_syntax.asp

使用Xpath定义路径表达式 可以按需查找节点 并返回集合形式。

2.查找规则

? 【/】设置绝对路径

语法:操作对象->xpath(‘/节点名’);

作用:选取从根节点开始查找

? 【//】全局查找

语法规则:操作对象->xpath(‘/节点//节点名称’);

作用:查找节点, 不管节点在什么层次下都返回节点的内容

使用例子:


? 【..】选取父节点

语法:操作对象->xpath(‘/节点1/节点2/节点3/..’);

作用:


? 【[]】过滤节点

语法规则:操作对象-xpath(‘/节点[节点名称=节点里面的内容]’);

作用:根据节点内容来查找节点


? 【@】过滤属性

语法:操作对象-xpath(‘/节点[@属性=属性的值]’);

作用:

3.XPATH在线词典应用

1.完成需求

提供一个input 框 当用户输入要查找的单词的时候返回这个单词的所有翻译结果。

2.完成步骤

1.使用函数来加载单词xml文件

2.获取用户传递的参数

3.使用xpath进行数据的检索

4.将结果返回并且展示到页面中

因为检索出来的内容是多个,所以返回格式是:数组包含对象


要想trans 里面的内容向,word 一样可以使用【对象->word】这种形式来输出

可以将CDATA进行转码

3.完成代码

”XMLHttpRequest 的异步调用网上找的例子运行没问题,但稍微改了一点点就报错”InvalidStateError: XMLHttpRequest has an invalid context“。断断续续 搞了3天终于通了,可以接收二进制文件了。 “ 之后找到了下篇文章,发现我所使用的方法是下方中的老方法。准备再按下文所说新方法试试。

下文是2011写的了,想必所说内容到现在已是所有浏览器都支持的了吧。

以下转自: https://www.html5rocks.com/zh/tutorials/file/xhr2/。

XMLHttpRequest2 新技巧

HTML5 Rocks

目录

  • 简介
  • 抓取数据
  • 发送数据
  • 跨源资源共享 (CORS)
  • 实际示例:
  • 参考

By Eric Bidelman

已发布: 五月 27th, 2011 Comments: 0

简介

HTML5 世界中有这样一位无名英雄:XMLHttpRequest。严格地说,XHR2 并不属于 HTML5。不过,它是浏览器供应商对于核心平台不断做出的改进中的一部分。我之所以将 XHR2 加入我们新的百宝囊中,就是因为它在如今复杂的网络应用中扮演了不可或缺的角色。

结果呢,我们这位老朋友来了个大变身,很多人都不知道它的新功能了。2 级 XMLHttpRequest 引入了大量的新功能(例如跨源请求、上传进度事件以及对上传/下载二进制数据的支持等),一举封杀了我们网络应用中的疯狂黑客。这使得 AJAX 可以与很多尖端的 HTML5 API 结合使用,例如 File System API、Web Audio API 和 WebGL。

此教程重点介绍 XMLHttpRequest 中的新功能,尤其是可用于处理文件的功能。

抓取数据

以前通过 XHR 抓取二进制 blob 形式的文件是很痛苦的事情。从技术上来说,这甚至是不可能的实现。有一种广为流传的一种技巧,是将 MIME 类型替换为由用户定义的字符集,如下所示:

提取图片的旧方法:

var xhr=new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
// Hack to pass bytes through unprocessed.
xhr.overrideMimeType('text/plain; charset=x-user-defined');
xhr.onreadystatechange=function(e) {
 if (this.readyState==4 && this.status==200) {
 var binStr=this.responseText;
 for (var i=0, len=binStr.length; i < len; ++i) {
 var c=binStr.charCodeAt(i);
 //String.fromCharCode(c & 0xff);
 var byte=c & 0xff; // byte at offset i
 }
 }
};
xhr.send();

虽然这种方法可行,但是 responseText 中实际返回的并不是二进制 blob,而是代表图片文件的二进制字符串。我们要巧妙地让服务器在不作处理的情况下,将这些数据传递回去。虽然这个技巧有用,但是我不推荐大家走这种歪门邪道。只要是通过玩弄字符代码和字符串操控技巧,强行将数据转化成所需的格式,都会出现问题。

指定响应格式

在前一个示例中,我们通过替换服务器的 MIME 类型并将响应文本作为二进制字符串处理,下载了二进制“文件”形式的图片。现在,让我们利用 XMLHttpRequest 新增的 responseType 和 response 属性,告知浏览器我们希望返回什么格式的数据。

xhr.responseType

在发送请求前,根据您的数据需要,将 xhr.responseType 设置为“text”、“arraybuffer”、“blob”或“document”。请注意,设置(或忽略)xhr.responseType='' 会默认将响应设为“text”。

xhr.response

成功发送请求后,xhr 的响应属性会包含 DOMString、ArrayBuffer、Blob 或 Document 形式(具体取决于 responseTyp 的设置)的请求数据。

凭借这个优秀的新属性,我们可以修改上一个示例:以 ArrayBuffer 而非字符串的形式抓取图片。将缓冲区移交给 BlobBuilder API 可创建 Blob:

BlobBuilder=window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder;
var xhr=new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType='arraybuffer';
xhr.onload=function(e) {
 if (this.status==200) {
 var bb=new BlobBuilder();
 bb.append(this.response); // Note: not xhr.responseText
 var blob=bb.getBlob('image/png');
 ...
 }
};
xhr.send();

好多了!

ArrayBuffer 响应

ArrayBuffer 是二进制数据通用的固定长度容器。如果您需要原始数据的通用缓冲区,ArrayBuffer 就非常好用,但是它真正强大的功能是让您使用 JavaScript 类型数组创建底层数据的“视图”。实际上,可以通过单个 ArrayBuffer 来源创建多个视图。例如,您可以创建一个 8 位整数数组,与来自相同数据的现有 32 位整数数组共享同一个 ArrayBuffer。底层数据保持不变,我们只是创建其不同的表示方法。

例如,下面以 ArrayBuffer 的形式抓取我们相同的图片,但是现在,会通过该数据缓冲区创建无符号的 8 位整数数组。

var xhr=new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType='arraybuffer';
xhr.onload=function(e) {
 var uInt8Array=new Uint8Array(this.response); // this.response==uInt8Array.buffer
 // var byte3=uInt8Array[4]; // byte at offset 4
 ...
};
xhr.send();

Blob 响应

如果您要直接处理 Blob 且/或不需要操作任何文件的字节,可使用 xhr.responseType='blob':

window.URL=window.URL || window.webkitURL; // Take care of vendor prefixes.
var xhr=new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType='blob';
xhr.onload=function(e) {
 if (this.status==200) {
 var blob=this.response;
 var img=document.createElement('img');
 img.onload=function(e) {
 window.URL.revokeObjectURL(img.src); // Clean up after yourself.
 };
 img.src=window.URL.createObjectURL(blob);
 document.body.appendChild(img);
 ...
 }
};
xhr.send();

Blob 可用于很多场合,包括保存到 indexedDB、写入 HTML5 文件系统 或创建 Blob 网址(如本例中所示)。

发送数据

能够下载各种格式的数据固然是件好事,但是如果不能将这些丰富格式的数据送回本垒(服务器),那就毫无意义了。XMLHttpRequest 有时候会限制我们发送 DOMString 或 Document (XML) 数据。但是现在不会了。现已替换成经过修改的 send() 方法,可接受以下任何类型:DOMString、Document、FormData、Blob、File、ArrayBuffer。本部分的其余内容中的示例演示了如何使用各类型发送数据。

发送字符串数据:xhr.send(DOMString)

function sendText(txt) {
 var xhr=new XMLHttpRequest();
 xhr.open('POST', '/server', true);
 xhr.onload=function(e) {
 if (this.status==200) {
 console.log(this.responseText);
 }
 };
 xhr.send(txt);
}
sendText('test string');
function sendTextNew(txt) {
 var xhr=new XMLHttpRequest();
 xhr.open('POST', '/server', true);
 xhr.responseType='text';
 xhr.onload=function(e) {
 if (this.status==200) {
 console.log(this.response);
 }
 };
 xhr.send(txt);
}
sendText2('test string');

这没有新内容,只是正确的代码段略有不同。其中设置了 responseType='text' 作为对比。再次说明,省略此行会得到同样的结果。

提交表单:xhr.send(FormData)

很多人可能习惯于使用 jQuery 插件或其他库来处理 AJAX 表单提交。而我们可以改用 FormData,这是另一种针对 XHR2 设计的新数据类型。使用 FormData 能够很方便地实时以 JavaScript 创建 HTML <form>。然后可以使用 AJAX 提交该表单:

function sendForm() {
 var formData=new FormData();
 formData.append('username', 'johndoe');
 formData.append('id', 123456);
 var xhr=new XMLHttpRequest();
 xhr.open('POST', '/server', true);
 xhr.onload=function(e) { ... };
 xhr.send(formData);
}

实质上,我们只是动态创建了 <form>,并通过调用 append 方法为其附加了 <input> 值。

当然,您无需从一开始就创建 <form>。FormData 对象可通过页面上现有的 HTMLFormElement 进行初始化。例如:

<form id="myform" name="myform" action="/server">
 <input type="text" name="username" value="johndoe">
 <input type="number" name="id" value="123456">
 <input type="submit" onclick="return sendForm(this.form);">
</form>
function sendForm(form) {
 var formData=new FormData(form);
 formData.append('secret_token', '1234567890'); // Append extra data before send.
 var xhr=new XMLHttpRequest();
 xhr.open('POST', form.action, true);
 xhr.onload=function(e) { ... };
 xhr.send(formData);
 return false; // Prevent page from submitting.
}

HTML 表单可包含文件上传(例如 <input type="file">),而 FormData 也可以处理此操作。只需附加文件,浏览器就会在调用 send() 时构建 multipart/form-data 请求。

function uploadFiles(url, files) {
 var formData=new FormData();
 for (var i=0, file; file=files[i]; ++i) {
 formData.append(file.name, file);
 }
 var xhr=new XMLHttpRequest();
 xhr.open('POST', url, true);
 xhr.onload=function(e) { ... };
 xhr.send(formData); // multipart/form-data
}
document.querySelector('input[type="file"]').addEventListener('change', function(e) {
 uploadFiles('/server', this.files);
}, false);

上传文件或 blob:xhr.send(Blob)

我们也可以使用 XHR 发送 File 或 Blob。请注意,所有 File 都是 Blob,所以在此使用两者皆可。

该示例使用 BlobBuilder API 从头开始创建新的文本文件,并将该 Blob 上传到服务器。该代码还设置了一个处理程序,用于通知用户上传进度:

<progress min="0" max="100" value="0">0% complete</progress>
function upload(blobOrFile) {
 var xhr=new XMLHttpRequest();
 xhr.open('POST', '/server', true);
 xhr.onload=function(e) { ... };
 // Listen to the upload progress.
 var progressBar=document.querySelector('progress');
 xhr.upload.onprogress=function(e) {
 if (e.lengthComputable) {
 progressBar.value=(e.loaded / e.total) * 100;
 progressBar.textContent=progressBar.value; // Fallback for unsupported browsers.
 }
 };
 xhr.send(blobOrFile);
}
// Take care of vendor prefixes.
BlobBuilder=window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder;
var bb=new BlobBuilder();
bb.append('hello world');
upload(bb.getBlob('text/plain'));

上传字节:xhr.send(ArrayBuffer)

最后也是相当重要的一点就是,我们能以 XHR 的有效负载形式发送 ArrayBuffer。

function sendArrayBuffer() {
 var xhr=new XMLHttpRequest();
 xhr.open('POST', '/server', true);
 xhr.onload=function(e) { ... };
 var uInt8Array=new Uint8Array([1, 2, 3]);
 xhr.send(uInt8Array.buffer);
}

跨源资源共享 (CORS)

CORS 允许一个域上的网络应用向另一个域提交跨域 AJAX 请求。启用此功能非常简单,只需由服务器发送一个响应标头即可。

启用 CORS 请求

假设您的应用已经在 example.com 上了,而您想要从 www.example2.com 提取数据。一般情况下,如果您尝试进行这种类型的 AJAX 调用,请求将会失败,而浏览器将会出现“源不匹配”的错误。利用 CORS,www.example2.com 只需添加一个标头,就可以允许来自 example.com 的请求:

Access-Control-Allow-Origin: http://example.com

可将 Access-Control-Allow-Origin 添加到某网站下或整个域中的单个资源。要允许任何域向您提交请求,请设置如下:

Access-Control-Allow-Origin: *

其实,该网站 (html5rocks.com) 已在其所有网页上均启用了 CORS。启用开发人员工具后,您就会在我们的响应中看到 Access-Control-Allow-Origin 了:

html5rocks.com 上的 Access-Control-Allow-Origin 标头

启用跨源请求是非常简单的,因此如果您的数据是公开的,请务必启用 CORS!

提交跨域请求

如果服务器端已启用了 CORS,那么提交跨域请求就和普通的 XMLHttpRequest 请求没什么区别。例如,现在 example.com 可以向 www.example2.com 提交请求了:

var xhr=new XMLHttpRequest();
xhr.open('GET', 'http://www.example2.com/hello.json');
xhr.onload=function(e) {
 var data=JSON.parse(this.response);
 ...
}
xhr.send();

实际示例:

下载文件并保存到 HTML5 文件系统

假设您有一个图片库,想要提取一些图片,然后使用 HTML5 文件系统本地保存这些图片。一种方法是以 ArrayBuffer 形式请求图片,通过数据构建 Blob,并使用 FileWriter 写入 blob:

window.requestFileSystem=window.requestFileSystem || window.webkitRequestFileSystem;
function onError(e) {
 console.log('Error', e);
}
var xhr=new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType='arraybuffer';
xhr.onload=function(e) {
 window.requestFileSystem(TEMPORARY, 1024 * 1024, function(fs) {
 fs.root.getFile('image.png', {create: true}, function(fileEntry) {
 fileEntry.createWriter(function(writer) {
 writer.onwrite=function(e) { ... };
 writer.onerror=function(e) { ... };
 var bb=new BlobBuilder();
 bb.append(xhr.response);
 writer.write(bb.getBlob('image/png'));
 }, onError);
 }, onError);
 }, onError);
};
xhr.send();

请注意:要使用此代码,请参阅“探索 FileSystem API”教程中的浏览器支持和存储限制。

分割文件并上传各个部分

使用 File API,我们可以将操作简化为上传大文件。我们采用的技术是:将要上传的文件分割成多个部分,为每个部分生成一个 XHR,然后在服务器上将各部分组合成文件。这类似于 Gmail 快速上传大附件的方法。使用这种技术还可以规避 Google 应用引擎对 http 请求的 32 MB 限制。

window.BlobBuilder=window.MozBlobBuilder || window.WebKitBlobBuilder ||
 window.BlobBuilder;
function upload(blobOrFile) {
 var xhr=new XMLHttpRequest();
 xhr.open('POST', '/server', true);
 xhr.onload=function(e) { ... };
 xhr.send(blobOrFile);
}
document.querySelector('input[type="file"]').addEventListener('change', function(e) {
 var blob=this.files[0];
 const BYTES_PER_CHUNK=1024 * 1024; // 1MB chunk sizes.
 const SIZE=blob.size;
 var start=0;
 var end=BYTES_PER_CHUNK;
 while(start < SIZE) {
 // Note: blob.slice has changed semantics and been prefixed. See http://goo.gl/U9mE5.
 if ('mozSlice' in blob) {
 var chunk=blob.mozSlice(start, end);
 } else {
 var chunk=blob.webkitSlice(start, end);
 }
 upload(chunk);
 start=end;
 end=start + BYTES_PER_CHUNK;
 }
}, false);
})();

用于在服务器上重组文件的代码并未在此显示。

赶快试试吧

VG 动画有很多种实现方法,也有很大SVG动画库,现在我们就来介绍 svg动画实现方法都有哪些?

一、SVG 的 animation

SVG animation 有五大元素,他们控制着各种不同类型的动画,分别为:

  • set
  • animate
  • animateColor
  • animateTransform
  • animateMotion

1.1、set

set 为动画元素设置延迟,此元素是SVG中最简单的动画元素,但是他并没有动画效果。

使用语法:

<set attributeName="" attributeType="" to="" begin="" />
  • attributeName :是要改变的元素属性名称。
  • attributeType :是表明attributeName属性值的列表,支持三个固定参数 CSS/XML/auto,如x,y以及transform属于XML,opacity属于CSS。auto是浏览器自动判别的意思,也是默认值,如果你不知道该选哪个就填auto,浏览器自己判别。
  • to :动画结束的属性值。
  • begin :动画延迟时间。

eg:绘制一个半径为200的圆,4秒之后,半径变为50。

<svg width="320" height="320">
 <circle cx="0" cy="0" r="200" style="stroke: none; fill: #0000ff;">
  <set attributeName="r" attributeType="XML" to="50" begin="4s" />
 </circle>
</svg>

1.2、animate

是基础的动画元素,实现单属性的过渡效果。

使用语法:

<animate 
 attributeName="r" 
 from="200" to="50" 
 begin="4s" dur="2s" 
 repeatCount="2"
></animate>
  • from :过渡效果的属性开始值。
  • to:过渡效果的属性结束值。
  • begin:动画开始时间。
  • dur:动画过渡时间,控制动画速度。
  • repeatCount:动画重复次数。

eg:绘制一个半径为200的圆,4秒之后半径在2秒内从200逐渐变为50。

<circle cx="0" cy="0" r="200" style="stroke: none; fill: #0000ff;">
 <animate attributeName="r" from="200" to="50" 
  begin="4s" dur="2s" repeatCount="2"></animate>
</circle>

1.3、animateColor

控制颜色动画,animate也可以实现这个效果,所以该属性目前已被废弃。

1.4、animateTransform

实现transform变换动画效果,与css3的transform变换类似。实现平移、旋转、缩放等效果。

使用语法:

<animateTransform attributeName="transform"  type="scale" 
 from="1.5" to="0" 
 begin="2s"  dur="3s" 
 repeatCount="indefinite"></animateTransform>
  • repeatCount:重复次数,设置为 indefinite 表示无限循环,一直执行。
  • type:添加 transform 变换类型。
  • eg:绘制一个半径为200的圆,4秒之后开始缩放,在2秒内从1.5缩小到0倍。
<svg width="320" height="320">
 <circle cx="0" cy="0" r="200" style="stroke: none; fill: #0000ff;">
  <animateTransform attributeName="transform" begin="4s"  
   dur="2s" type="scale" from="1.5" to="0" 
   repeatCount="indefinite"></animateTransform>
 </circle>
</svg>

1.5、animateMotion

可以定义动画路径,让SVG各个图形,沿着指定路径运动。

使用语法:

<animateMotion 
 path="M 0 0 L 320 320" 
begin="4s" dur="2s"></animateMotion>
  • path:定义路径,使用语法与《HTML5(八)——SVG 之 path 详解》path的d属性一致。
  • begin:延迟时间。
  • dur:动画执行时间。

eg:绘制一个半径为10的圆,延迟4秒从左上角运动的右下角。

<svg width="320" height="320">
 <circle cx="0" cy="0" r="10" style="stroke: none; fill: #0000ff;">
  <animateMotion 
   path="M 0 0 L 320 320" 
   begin="4s" dur="2s"
   ></animateMotion>
 </circle>
</svg>

实际制作动画的时候,动画太单一不酷,需要同时改变多个属性时,上边的四种元素可以互相组合,同类型的动画也能组合。以上这些元素虽然能够实现动画,但是无法动态地添加事件,所以接下来我们就看看 js 如何制作动画。

二、JavaScript 控制

上篇文章我们介绍js可以操作path,同样也可以操作SVG的内置形状元素,还可以给任意元素添加事件。

给SVG元素添加事件方法与普通元素一样,可以只用on+事件名 或者addEventListener添加。

eg:使用SVG绘制地一条线,点击线条地时候改变 x1 ,实现旋转效果。

<svg width="800" height="800" id="svg">
    <line id="line" x1="100" y1="100" 
    x2="400" y2="300" 
    stroke="black" stroke-width="5"></line>  
  </svg>
<script>
 window.onload=function(){
  var line=document.getElementById("line")
  line.onclick=function(){
   let start=parseInt(line.getAttribute("x1")),
       end=400,dis=start-end
   requestAnimationFrame(next)
   let count=0;
   function next(){
    count++
    let a=count/200,cur=Math.abs(start+ dis*a)
    line.setAttribute('x1',cur)
    if(count<200)requestAnimationFrame(next)
   }
  }
 }
</script>

js制作的SVG动画,主要利用 requestAnimationFrame 来实现一帧一帧的改变。

我们上述制作的 SVG 图形、动画等,运行在低版本IE中,发现SVG只有IE9以上才支持,低版本的并不能支持,为了兼容低版本浏览器,可以使用 VML ,VML需要添加额外东西,每个元素需要添加 v:元素,样式中还需要添加 behavier ,经常用于绘制地图。由于使用太麻烦,所以我们借助 Raphael.js 库。

三、Rapha?l.js (拉斐尔)

Raphael.js是通过SVG/VML+js实现跨浏览器的矢量图形,在IE浏览器中使用VML,非IE浏览器使用SVG,类似于jquery,本质还是一个javascript库,使用简单,容易上手。

使用之前需要先引入Raphael.js库文件。cdn的地址为:https://cdn.bootcdn.net/ajax/libs/raphael/2.3.0/raphael.js

3.1、创建画布

Rapheal有两种创建画布的方式:

第一种:浏览器窗口上创建画布

创建语法:

var paper=Raphael(x,y,width,height)

x,y是画布左上角的坐标,此时画布的位置是绝对定位,有可能会与其他html元素重叠。width、height是画布的宽高。

第二种:在一个元素中创建画布

创建语法:

var paper=Raphael(element, width, height);

element是元素节点本身或ID width、height是画布的宽度和高度。

3.2、绘制图形

画布创建好之后,该对象自带SVG内置图形有矩形、圆形、椭圆形。他们的方法分别为:

paper.circle(cx, cy, r); // (cx , cy)圆心坐标 r 半径
paper.rect(x, y, width, height, r); // (x,y)左上角坐标 width宽度 height高度 r圆角半径(可选)
paper. ellipse(cx, cy, rx, ry); // (cx , cy)圆心坐标 rx水平半径 ry垂直半径

eg:在div中绘制一个圆形,一个椭圆、一个矩形。

<div id="box"></div>
<script>
 var paper=Raphael("box",300,300)
 paper.circle(150,150,150)
 paper.rect(0,0,300,300)
 paper.ellipse(150,150,100,150)
</script>

运行结果如下:

除了简单图形之外,还可以绘制复杂图形,如三角形、心型,这时就使用path方法。

使用语法:paper.path(pathString)

pathString是由一个或多个命令组成,每个命令以字母开始,多个参数是由逗号分隔。

eg:绘制一个三角形。

let sj=paper.path("M 0,0 L100,100 L100,0 'Z'")

还可以绘制文字,如果需要换行,使用 \n 。

文字语法:paper.text(x,y,text)

(x,y)是文字坐标,text是要绘制的文字。

3.3、设置属性

图形绘制之后,我们通常会添加stroke、fill、stroke-width等让图形更美观,Raphael使用attr给图形设置属性。

使用语法:circle.attr({"属性名","属性值","属性名","属性值",...})

如果只有属性名没有属性值,则是获取属性,如果有属性值,则是设置属性。

注意:如果只设置一个属性时,可以省略‘{}’。如:rect.attr('fill','pink')

eg:给上边的矩形添加边框和背景色。

<div id="box"></div>
<script>
 var paper=Raphael("box",300,300)
 let rect=paper.rect(100,100,150,200)
 rect.attr({'fill':'red','stroke':'blue','stroke-width':'10'})
</script>

3.4、添加事件

RaphaelJS一般具有以下事件:
click、dblclick、drag、hide、hover、mousedown、mouseout、mouseup、mouseover等以及对应的解除事件,只要在前面加上“un”就可以了(unclick、undblclick)。

使用语法:

obj.click(function(){
 //需要操作的内容
})

3.5、添加动画

animate为指定图形添加动画并执行。

使用语法:

obj.animate({
 "属性名1":属性值1,
 "属性名2":属性值2,
  ...
},time,type)

属性名和属性值就根据你想要的动画类型加就ok。

time:动画所需时间。

type:指动画缓动类型。常用值有:

  • linear - 线性渐变
  • ease-in | easeIn | < - 由慢到快
  • ease-out | easeOut | > - 由快到慢
  • ease-in-out | easeInOut | <> - 由慢到快再到慢
  • back-in | backIn - 开始时回弹
  • back-out | backOut - 结束时回弹
  • elastic - 橡皮筋
  • bounce - 弹跳

eg:点击矩形,矩形缓缓变大。

<div id="box"></div>
<script>
 var paper=Raphael("box",800,500)
 let rect=paper.rect(100,100,150,100)
 rect.attr({'fill':'red','stroke':'blue','stroke-width':'10'})
 rect.attr('fill','pink')
 rect.click(function(){
  rect.animate({
   "width":300,
   "height":300
  },1000,"bounce")
 })
</script>

复制上边的代码,分别在各个浏览器和低版本IE浏览器运行,发现都可以正常运行。SVG的动画库挺多了,我们介绍了拉斐尔,有兴趣的小伙伴可以自行找找其他库。