手动实现轮播图

使用纯HTMLCSSJavaScript实现轮播图功能。

position

使用position的绝对定位与相对定位实现轮播图,首先将图片全部拼接成为一行,使用overflow: hidden;将其他图片隐藏,将这一行图片加入定时任务不断进行左移,从而只显示中间的图片,对于边缘特殊处理,将第一张轮播图追加到一行图片之后,当切换到最后一张轮播图时,下一张即播放第一张图,当此图轮播完成后,将所有图片归位,提供两个DEMO,第一个是单纯的轮播不存在任何控制按钮,第二个则比较完善。

实例

<!-- 简单DEMO,未实现任何控制,单纯图片轮播
--><!DOCTYPE html>
<html>
<head><title>轮播图</title><meta charset="utf-8"><meta name="referrer" content="no-referrer">
</head>
<style type="text/css">body{margin: 0;padding: 0px;}#carousel{margin: auto; /* 居中 */width: 600px; /* 设置宽度 */position: relative; /* 相对定位 */overflow: hidden; /* 超出隐藏 */}#carousel img{width: 600px; /* 设定大小 按比例缩放 */}#carousel > ul {display: flex; /* 图片处理为一行 */position: absolute; /* 设置绝对定位,实现相对于#carousel的绝对定位 */}#carousel > ul,#carousel > ul > li{padding: 0;margin: 0;list-style:none; }
</style>
<body><!-- 轮播图容器 --><div id="carousel"><ul> <!-- 图片容器 --><li><img src="http://www.sdust.edu.cn/__local/9/7A/B1/F29B84DEF72DD329997E8172ABA_664BA3EF_32466.jpg"></li><li><img src="http://www.sdust.edu.cn/__local/B/F3/E4/693AB931C9FFB84646970D53BFE_C506394A_4282CA.jpg"></li><li><img src="http://www.sdust.edu.cn/__local/F/7A/AA/E1459849AA8AB0C89854A41BD41_BF3BD857_BC0D8.jpg"></li><li><img src="http://www.sdust.edu.cn/__local/1/95/CB/EDC1450B8FD1B8A25FAAC726AA4_A36D4253_16C91.jpg"></li></ul></div>
</body><script type="text/javascript">var imgArr = []; // 图片数组var curIndex = 0; // 当前显示图片var timer = null; // 定时器function slide(slideContainer){var width = imgArr[curIndex].width; // 获取图片宽度,也就是每次切换图片要滑动的距离var distanceMoved = 0; // 已经移动的距离var step = 10; //切换的步长var curConLeft = slideContainer.offsetLeft; // 获取ul的leftvar slideInterval = setInterval(function (){ // 此定时器是为了实现切换动画if(Math.abs(width - distanceMoved) > step){ // 边界判定,判断已移动距离以及应移动距离的差与步长关系curConLeft -= step; // 大于步长则不断移动slideContainer.style.left = `${curConLeft}px`; // 移动distanceMoved += step; // 已移动距离加步长}else{ clearInterval(slideInterval); // 若最后移动距离不足步长,则清除动画定时器slideContainer.style.left = `${curConLeft - width + distanceMoved }px`; // 直接完成此次动画distanceMoved = 0; // 重设移动距离为0if(++curIndex === imgArr.length){ // index加1,判断是否为最后一张来作边缘处理curIndex = 0; // 最后一张则重置indexslideContainer.style.left = 0;  // 重置ul}}}, 10);}(function start() {var config = {height: "300px", // 配置高度interval: 5000 // 配置轮播时间间隔}document.getElementById("carousel").style.height = config.height; // 将轮播容器高度设定document.querySelectorAll("#carousel img").forEach(v => imgArr.push(v)); // 获取所有图片组成数组var slideContainer = document.querySelector("#carousel > ul"); // 获取ul也就是一行图片的容器var li = document.createElement("li"); // 创建<li>var img = document.createElement("img"); // 创建新的<img>img.src = imgArr[0].src; // 设置图片srcli.appendChild(img); // 追加<img>到<li>slideContainer.appendChild(li); // 将第一张图片追加到轮播图的最后,作边缘处理timer = setInterval(() => {slide(slideContainer)},config.interval); // 设置定时器定时切换})();</script>
</html>
<!-- 加入控制按钮,上一张与下一张,直接切换按钮将第一张图片的边缘化进行处理对浏览器页面显隐与鼠标移入移出事件的支持
--><!DOCTYPE html>
<html>
<head><title>轮播图</title><meta charset="utf-8"><meta name="referrer" content="no-referrer">
</head>
<link rel="stylesheet" type="text/css" href="https://at.alicdn.com/t/font_1582902_u0zm91pv15i.css">
<style type="text/css">body{margin: 0;padding: 0px;}#carousel{margin: auto; /* 居中 */width: 600px; /* 设置宽度 */position: relative; /* 相对定位 */overflow: hidden; /* 超出隐藏 */}#carousel img{width: 600px; /* 设定大小 按比例缩放 */}#carousel > ul {display: flex; /* 图片处理为一行 */position: absolute; /* 设置绝对定位,实现相对于#carousel的绝对定位 */}#carousel > ul,#carousel > ul > li{padding: 0;margin: 0;list-style:none; }/* 控制按钮的样式 */#leftArrow,#rightArrow{position: absolute;left: 5px;top: 43%;width: 25px;height: 30px;background-color: #eee;display: flex;justify-content: center;align-items: center;opacity: 0.7;font-size: 20px;cursor: pointer;}#rightArrow{left: auto;right: 5px;}#sliderBtn{position: absolute;width: 100%;bottom: 0;display: flex;justify-content: flex-end;}.unitBtn{width: 10px;height: 10px;background-color: #eee;border-radius: 10px;margin: 10px;cursor: pointer;}.active{background-color: #4C98F7;}
</style>
<body><!-- 轮播图容器 --><div id="carousel"><ul> <!-- 图片容器 --><li><img src="http://www.sdust.edu.cn/__local/9/7A/B1/F29B84DEF72DD329997E8172ABA_664BA3EF_32466.jpg"></li><li><img src="http://www.sdust.edu.cn/__local/B/F3/E4/693AB931C9FFB84646970D53BFE_C506394A_4282CA.jpg"></li><li><img src="http://www.sdust.edu.cn/__local/F/7A/AA/E1459849AA8AB0C89854A41BD41_BF3BD857_BC0D8.jpg"></li><li><img src="http://www.sdust.edu.cn/__local/1/95/CB/EDC1450B8FD1B8A25FAAC726AA4_A36D4253_16C91.jpg"></li></ul><!-- 按钮组 --><div id="leftArrow" class="iconfont icon-arrow-lift"></div> <!-- 左箭头切换按钮 -->        <div id="rightArrow" class="iconfont icon-arrow-right"></div> <!-- 右箭头切换按钮 --> <div id="sliderBtn"></div> <!-- 切换按钮组 --></div>
</body><script type="text/javascript">var imgArr = []; // 图片数组var curIndex = 0; // 当前显示图片var timer = null; // 定时器var clickAllow = true; // 锁,是否允许用户点击var btnList = []; // 右下角切换按钮组function slide(slideContainer , targetIndex = curIndex + 1){var width = 0; // 计算切换图片要滑动的距离if(targetIndex > curIndex){for(let i=curIndex;i<targetIndex;++i) width+=imgArr[i].width; // 正向切换则计算本图片到后续图片宽度}else{if(targetIndex === -1) width = imgArr[imgArr.length-1].width; // 特殊处理第一张图片else for(let i=targetIndex;i<curIndex;++i) width+=imgArr[i].width; // 逆向切换处理宽度}clickAllow = false; // 不允许用户点击var step = width/60; // 动态设置步长step = targetIndex > curIndex ? step : -step; // 正向逆向切换 var curConLeft = slideContainer.offsetLeft; // 获取ul的leftvar distanceMoved = 0; // 已经移动的距离var slideInterval = setInterval(function (){ // 此定时器是为了实现切换动画if(Math.abs(width - distanceMoved) > Math.abs(step)){ // 边界判定,判断已移动距离以及应移动距离的差与步长关系curConLeft -= step; // 大于步长则不断移动slideContainer.style.left = `${curConLeft - step}px`; // 移动distanceMoved += Math.abs(step); // 已移动距离加步长}else{ clearInterval(slideInterval); // 若最后移动距离不足步长,则清除动画定时器var directMove = step > 0 ? (curConLeft - width + distanceMoved) : (curConLeft + width - distanceMoved); // 正向移动与逆向移动的计算方式不同slideContainer.style.left = `${directMove}px`; // 直接完成此次动画distanceMoved = 0; // 重设移动距离为0curIndex = targetIndex; // 设置当前indexif(curIndex === imgArr.length){ // index加1,判断是否为最后一张来作边缘处理curIndex = 0; // 最后一张则重置indexslideContainer.style.left = `-${imgArr[0].width}px`;  // 重置ul}else if (curIndex === -1) {curIndex = imgArr.length-1; // 第一张重置indexslideContainer.style.left = `-${slideContainer.offsetWidth - imgArr[imgArr.length-1].width - imgArr[0].width}px`;  // 重置ul}switchBtnActive(); // 右下角按钮的切换clickAllow = true; // 允许点击}}, 10);}function switchBtnActive(){ btnList.forEach((v) => {v.className = "unitBtn"; // 设置其他按钮为灰色})btnList[curIndex] .className = "unitBtn active"; // 设置当前按钮为蓝色}function createBtnGroup(carousel,slideContainer,config){document.getElementById("leftArrow").addEventListener('click',(e) => { clearInterval(timer); // 清除定时器,避免手动切换时干扰if(clickAllow) slide(slideContainer,curIndex-1); // 允许点击则切换上一张timer = setInterval(() => {slide(slideContainer)},config.interval); // 重设定时器}) document.getElementById("rightArrow").addEventListener('click',(e) => {clearInterval(timer); // 清除定时器,避免手动切换时干扰if(clickAllow) slide(slideContainer,curIndex+1); // 允许点击则切换下一张timer = setInterval(() => {slide(slideContainer)},config.interval); // 重设定时器}) var sliderBtn = document.getElementById("sliderBtn"); // 获取按钮容器的引用imgArr.forEach((v,i) => {let btn = document.createElement("div"); // 制作按钮btn.className = i === 0 ?  "unitBtn active" : "unitBtn"; // 初设蓝色与灰色按钮样式btn.addEventListener('click',(e) => {clearInterval(timer); // 清除定时器,避免手动切换时干扰if(clickAllow) slide(slideContainer,i); // // 允许点击则切换timer = setInterval(() => {slide(slideContainer)},config.interval); // 重设定时器}) btnList.push(btn); // 添加按钮到按钮组sliderBtn.appendChild(btn); // 追加按钮到按钮容器})}function edgeDispose(slideContainer){var li = document.createElement("li"); // 创建<li>var img = document.createElement("img"); // 创建新的<img>img.src = imgArr[0].src; // 设置图片srcli.appendChild(img); // 追加<img>到<li>slideContainer.appendChild(li); // 将第一张图片追加到轮播图的最后,作边缘处理var li2 = document.createElement("li"); // 创建<li>var img2 = document.createElement("img"); // 创建新的<img>img2.src = imgArr[imgArr.length-1].src; // 设置图片srcli2.appendChild(img2); // 追加<img>到<li>slideContainer.insertBefore(li2,slideContainer.firstChild); // 将最后一张图片追加到轮播图的最前,作边缘处理slideContainer.style.left = `-${imgArr[0].width}px`; // 重设ul位置}function eventDispose(carousel,slideContainer,config){document.addEventListener('visibilitychange',function(){ // 浏览器切换页面会导致动画出现问题,监听页面切换if(document.visibilityState=='hidden') clearInterval(timer); // 页面隐藏清除定时器else timer = setInterval(() => {slide(slideContainer)},config.interval); // 重设定时器});carousel.addEventListener('mouseover',function(){ // 鼠标移动到容器则不切换动画,停止计时器clearInterval(timer); // 页面隐藏清除定时器});carousel.addEventListener('mouseleave',function(){ // 鼠标移出容器则开始动画timer = setInterval(() => {slide(slideContainer)},config.interval); // 重设定时器});}(function start() {var config = {height: "300px", // 配置高度interval: 5000 // 配置轮播时间间隔}var carousel = document.getElementById("carousel"); //获取容器对象的引用carousel.style.height = config.height; // 将轮播容器高度设定document.querySelectorAll("#carousel img").forEach(v => imgArr.push(v)); // 获取所有图片组成数组var slideContainer = document.querySelector("#carousel > ul"); // 获取ul也就是一行图片的容器edgeDispose(slideContainer); // 对边缘处理eventDispose(carousel,slideContainer,config); // 对一些浏览器事件处理createBtnGroup(carousel,slideContainer,config); // 按钮组的处理timer = setInterval(() => {slide(slideContainer)},config.interval); // 设置定时器定时切换})();</script>
</html>

opacity

首先通过对图片绝对定位来使图片堆叠,通过使用opacity来控制图片的显示与隐藏,即不使用Js控制轮播图的切换动画,而使用CSS动画来完成,由于是堆叠完成的,使用z-index也是可行的方案。

实例

<!DOCTYPE html>
<html>
<head><title>轮播图</title><meta charset="utf-8"><meta name="referrer" content="no-referrer">
</head>
<link rel="stylesheet" type="text/css" href="https://at.alicdn.com/t/font_1582902_u0zm91pv15i.css">
<style type="text/css">body{margin: 0;padding: 0px;}#carousel{margin: auto; /* 居中 */width: 600px; /* 设置宽度 */position: relative; /* 相对定位 */overflow: hidden; /* 超出隐藏 */}#carousel img{position: absolute; /* 绝对定位 使图片堆叠 */width: 600px; /* 设定大小 按比例缩放 */transition: all .6s; /* 动画 */opacity: 0; /* 隐藏 */}.imgActive{opacity: 1 !important; /* 显示图片 最高优先级 */}/* 控制按钮的样式 */#leftArrow,#rightArrow{position: absolute;left: 5px;top: 43%;width: 25px;height: 30px;background-color: #eee;display: flex;justify-content: center;align-items: center;opacity: 0.7;font-size: 20px;cursor: pointer;z-index: 1000;}#rightArrow{left: auto;right: 5px;}#sliderBtn{position: absolute;width: 100%;bottom: 0;display: flex;justify-content: flex-end;z-index: 1000;}.unitBtn{width: 10px;height: 10px;background-color: #eee;border-radius: 10px;margin: 10px;cursor: pointer;}.btnActive{background-color: #4C98F7;}
</style>
<body><!-- 轮播图容器 --><div id="carousel"><img src="http://www.sdust.edu.cn/__local/9/7A/B1/F29B84DEF72DD329997E8172ABA_664BA3EF_32466.jpg"><img src="http://www.sdust.edu.cn/__local/B/F3/E4/693AB931C9FFB84646970D53BFE_C506394A_4282CA.jpg"><img src="http://www.sdust.edu.cn/__local/F/7A/AA/E1459849AA8AB0C89854A41BD41_BF3BD857_BC0D8.jpg"><img src="http://www.sdust.edu.cn/__local/1/95/CB/EDC1450B8FD1B8A25FAAC726AA4_A36D4253_16C91.jpg"><!-- 按钮组 --><div id="leftArrow" class="iconfont icon-arrow-lift"></div> <!-- 左箭头切换按钮 -->        <div id="rightArrow" class="iconfont icon-arrow-right"></div> <!-- 右箭头切换按钮 --> <div id="sliderBtn"></div> <!-- 切换按钮组 --></div>
</body><script type="text/javascript">var imgArr = []; // 图片数组var curIndex = 0; // 当前显示图片var timer = null; // 定时器var btnList = []; // 右下角切换按钮组function slide(targetIndex = curIndex + 1){curIndex = targetIndex % imgArr.length; // 获取当前indeximgArr.forEach((v) => v.className = "" ); // 设置其他图片隐藏imgArr[curIndex] .className = "imgActive"; // 设置当前index图片显示btnList.forEach(v => v.className = "unitBtn") // 设置其他按钮为灰色btnList[curIndex] .className = "unitBtn btnActive"; // 设置当前按钮为蓝色}function createBtnGroup(carousel,config){document.getElementById("leftArrow").addEventListener('click',(e) => { clearInterval(timer); // 清除定时器,避免手动切换时干扰slide(curIndex-1); // 允许点击则切换上一张timer = setInterval(() => {slide()},config.interval); // 重设定时器}) document.getElementById("rightArrow").addEventListener('click',(e) => {clearInterval(timer); // 清除定时器,避免手动切换时干扰slide(curIndex+1); // 允许点击则切换下一张timer = setInterval(() => {slide()},config.interval); // 重设定时器}) var sliderBtn = document.getElementById("sliderBtn"); // 获取按钮容器的引用imgArr.forEach((v,i) => {let btn = document.createElement("div"); // 制作按钮btn.className = i === 0 ?  "unitBtn btnActive" : "unitBtn"; // 初设蓝色与灰色按钮样式btn.addEventListener('click',(e) => {clearInterval(timer); // 清除定时器,避免手动切换时干扰slide(i); // // 允许点击则切换timer = setInterval(() => {slide()},config.interval); // 重设定时器}) btnList.push(btn); // 添加按钮到按钮组sliderBtn.appendChild(btn); // 追加按钮到按钮容器})}function eventDispose(carousel,config){document.addEventListener('visibilitychange',function(){ // 浏览器切换页面会导致动画出现问题,监听页面切换if(document.visibilityState=='hidden') clearInterval(timer); // 页面隐藏清除定时器else timer = setInterval(() => {slide()},config.interval); // 重设定时器});carousel.addEventListener('mouseover',function(){ // 鼠标移动到容器则不切换动画,停止计时器clearInterval(timer); // 页面隐藏清除定时器});carousel.addEventListener('mouseleave',function(){ // 鼠标移出容器则开始动画timer = setInterval(() => {slide()},config.interval); // 重设定时器});}(function start() {var config = {height: "300px", // 配置高度interval: 5000 // 配置轮播时间间隔}var carousel = document.getElementById("carousel"); //获取容器对象的引用carousel.style.height = config.height; // 将轮播容器高度设定document.querySelectorAll("#carousel img").forEach((v,i) => {imgArr.push(v); // 获取所有图片组成数组v.className = i === 0 ?  "imgActive" : "";}); eventDispose(carousel,config); // 对一些浏览器事件处理createBtnGroup(carousel,config); // 按钮组的处理timer = setInterval(() => {slide()},config.interval); // 设置定时器定时切换})();</script>
</html>

CSS

CSS实现轮播图,完全使用CSS3动画完成轮播,主要使用animation属性与@keyframes规则,使用left控制距离,也可以使用opacity,为每个图片设置动画属性即可。

实例

<!DOCTYPE html>
<html>
<head><title>轮播图</title><meta charset="utf-8"><meta name="referrer" content="no-referrer">
</head>
<link rel="stylesheet" type="text/css" href="https://at.alicdn.com/t/font_1582902_u0zm91pv15i.css">
<style type="text/css">body{margin: 0;padding: 0px;}#carousel{margin: auto; /* 居中 */width: 600px; /* 设置宽度 */position: relative; /* 相对定位 */overflow: hidden; /* 超出隐藏 */height: 300px;}#carousel img{width: 600px; /* 设定大小 按比例缩放 */}#carousel > ul {display: flex; /* 图片处理为一行 */position: absolute; /* 设置绝对定位,实现相对于#carousel的绝对定位 */}#carousel > ul,#carousel > ul > li{padding: 0;margin: 0;list-style:none; }#carousel > ul{animation: switch 10s ease 1s infinite alternate; /* 设定动画播放 */}#carousel > ul:hover{animation-play-state: paused; /* 暂停动画 */}@keyframes switch{ /* 制定动画规则 */0%,13%{left: 0;}27%,41%{left: -600px;}55%,69%{left: -1200px;}83%,100% {left: -1800px;}}
</style>
<body><!-- 轮播图容器 --><div id="carousel"><ul> <!-- 图片容器 --><li><img src="http://www.sdust.edu.cn/__local/9/7A/B1/F29B84DEF72DD329997E8172ABA_664BA3EF_32466.jpg"></li><li><img src="http://www.sdust.edu.cn/__local/B/F3/E4/693AB931C9FFB84646970D53BFE_C506394A_4282CA.jpg"></li><li><img src="http://www.sdust.edu.cn/__local/F/7A/AA/E1459849AA8AB0C89854A41BD41_BF3BD857_BC0D8.jpg"></li><li><img src="http://www.sdust.edu.cn/__local/1/95/CB/EDC1450B8FD1B8A25FAAC726AA4_A36D4253_16C91.jpg"></li></ul></div>
</body>
</html>

每日一题

https://github.com/WindrunnerMax/EveryDay

三种方式实现轮播图功能相关推荐

  1. 用三种方式实现轮播图

    轮播图的实现原理 顾名思义,轮播图就是实现图片的轮换播放效果.先显示一张图片,一定的时间,让这张图片消失,下一张图片显示.让它们实现跟淘宝首页一样的广告轮播效果. 首先是前端html代码 <!D ...

  2. 24小时轮播怎么实现的_四种方式实现轮播图

    不论是app,还是网站,基本上都会出现轮播图,今天和大家分享几种不同工具实现轮播图的几种方式. 轮播图的基本样式和功能就不需要解释了,相信能根据题目选择看文章的话都知道啥是轮播图,如果哪位读者老爷真的 ...

  3. html按钮轮播图,四种方式实现轮播图

    不论是app,还是网站,基本上都会出现轮播图,今天和大家分享几种不同工具实现轮播图的几种方式. 轮播图的基本样式和功能就不需要解释了,相信能根据题目选择看文章的话都知道啥是轮播图,如果哪位读者老爷真的 ...

  4. 三种方法实现轮播图配置,史上最简方法~

    源代码: <div class="conscroll"><div class="caroubtn" @click="toleft&q ...

  5. 项目轮播图功能实现和导航栏的实现

    项目轮播图功能实现和导航栏的实现 轮播图功能 安装依赖模块 上传文件相关配置 注册home子应用 创建轮播图的model模型 创建Banner的序列化器 创建Banner的视图类 配置Banner的路 ...

  6. 两种方法实现轮播图效果

    实现轮播图 学习前端差不多两三个月,在这里记录分享一下.因本人菜鸟一枚,希望大佬们多多指点,勿喷. 通过计算每一张图片高度实现滑动轮播图 HTML代码: <div class="fat ...

  7. html 轮播怎么用jq设置,jQuery轮播图功能实现方法

    本文实例为大家分享了jQuery轮播图功能的实现代码,供大家参考,具体内容如下 jQuery轮播(无animation) html布局 5 1 2 3 4 5 1 < > CSS /* 轮 ...

  8. html幻灯片图片轮播w3,支持30+种类型幻灯片|轮播图|旋转木马的强大jQuery插件

    jssor slider是一款功能非常强大的可制作超过30种不同类型的幻灯片|轮播图|旋转木马的jQuery插件.jssor具有高性能,轻量级,跨浏览器等特点,它可以支持IE6+的浏览器,并且可以支持 ...

  9. 一种无限循环轮播图的实现原理

    本文来自 http://www.jianshu.com/p/ef03ec7f23b2 轮播实现步骤 接下来,笔者将从各方面逐一分析 层级结构 最底层是一个UIView,上面有一个UIScrollVie ...

最新文章

  1. 中国科大潘建伟团队量子网络研究获重要进展
  2. 二、Netty服务端/客户端启动整体流程
  3. python三角形判断白盒测试的代码_进化的测试 软件测试,自动化测试,白盒测试,Python...
  4. 前端学习(3332):ant design介绍button
  5. SAP License:SAP中的凭证查询、科目余额表及分类账详解
  6. layui中接收modelView中返回的对象并赋值给容器
  7. keras+tensorflow —— 可视化及tensorboard
  8. Java神鬼莫测之Mybatis--增删改查CRUD以及批量操作(二)
  9. 2018年华为网络技术大赛总结
  10. 电脑自带的Windows照片查看器不见了,可以试试这种方法。
  11. 《深入理解计算机系统》Lab2-Bomblab
  12. redis.conf配置详细解析
  13. 如何使用AutoCAD软件截图?
  14. 并发编程面试宝典(内含69道常问面试题及答案解析)
  15. JS验证电话和传真号码格式
  16. java JSON格式字符串数组 转 数组
  17. perl-dbd-mysql qt_perl 安装DBI和DBD
  18. QQ概念版体验[多图]
  19. 拖动滑块验证——原生JS
  20. 飞鸽传书2008默认分类

热门文章

  1. (转)The Standard C Library 经典的基础(上)
  2. 什么是 gRPC ?
  3. JS module的导出和导入 1
  4. EasyExcel简单使用
  5. 多路开关模式的switch语句
  6. 【转】ASIHTTPRequest开源类库进行http请求
  7. R实例:根据经纬度坐标批量返回行政区域信息
  8. scikit-learn学习之神经网络算法
  9. 技术人生:给自己安慰的10句温馨话
  10. [SOA征文]谈谈资源端的SOA化