支持触屏的jQuery轮播图插件
移动轮播图我看到两类,
一款是无线天猫的m.tmall.com和携程,实现了无缝轮播。
一款是蘑菇街的,没有实现无缝轮播。
我自己重写一个,类似天猫。
1.页面代码
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="UTF-8">
<head>
<meta charset="UTF-8">
<title>基于jQuery的移动轮播图(支持触屏)</title>
<meta name="viewport" content="maximum-scale=1,initial-scale=1,user-scalable=0"> <style type="text/css"> img
{
border:0;
*display:inline;
}
li
{
border:0;
list-style-type :none;
}
ul
{
list-style:none;
margin:0;
padding:0;
}
body{
overflow-x:hidden;
margin:0 auto;
padding:0;
width: 100%;
height: 100%;
}
.WSCSlideWrapper{
width:100%;
position: relative;
margin:0 auto;
//cursor:move;
}
#WSCSlideWrapperTwo{
width:50%;
position: relative;
margin:10px auto;
//cursor:move;
} </style>
<script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/jquery-1.8.2.min.js"></script> <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/touchslide-1.1.js"></script>
</head>
<body> <div class="WSCSlideWrapper" id="WSCSlideWrapper" > <div> <a href="http://www.baidu.com"><img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/1.jpg" /></a>
<a href="http://m.tmall.com"><img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/2.jpg" /></a>
<a href="http://huaban.com"><img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/3.jpg" /></a>
</div> </div> <div class="WSCSlideWrapper" id="WSCSlideWrapperTwo" >
<div>
<a><img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/1 (1).jpg" /></a>
<a><img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/1 (2).jpg" /></a>
<a><img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/1 (3).jpg" /></a>
<a><img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/1 (4).jpg" /></a>
</div> </div>
<script type="text/javascript"> $(document).ready(function(){ $('.WSCSlideWrapper').height($('.WSCSlideWrapper').width()*0.3);
$('#WSCSlideWrapperTwo').height($('#WSCSlideWrapperTwo').width()*1.5);
$('.WSCSlideWrapper').touchslide({timecontrol:3000,animatetime:300,direction:'left',navshow:true,canvassuport:true});
}); </script>
</body>
</html>
2.js插件代码
/*
* touchslide 1.1
* Copyright (c) 2014 BowenLuo http://www.luobo.com/
* Date: 2014-06-08
* Example:$('.WSCSlideWrapper').touchslide({timecontrol:3000,animatetime:300,direction:'left',navshow:true,canvassuport:true});
* Update:增加对IE9+等非Safari内核浏览器的鼠标拖动图片功能
*/
(function($){
$.fn.touchslide = function(options){
var defaults = {
timecontrol:3000,//图片停留时间
animatetime:300, //图片滑动所需时间
direction:'left', //轮播方向
navshow:true,//是否显示图片导航栏
canvassuport:true//图片导航栏是否开启cavas绘制圆
}
var options = $.extend(defaults, options);
var timecontrol = options.timecontrol||3000;
var animatetime = options.animatetime||300;
var direction = options.direction||'left';
var navshow = options.navshow;
this.each(function(){
var slideWrapper=$(this);
var slideImgWrapper = slideWrapper.children('div:first');
var slideAs = slideImgWrapper.children('a');
var slideImgs = slideAs.children('img');
var imgcount = slideImgs.length;
var imgcountrealy = slideImgs.length;
var navimgs;
var circlewrapper;
var circles;
var canvassuport = true;
var circler = 0;
if(imgcount>1){
$((slideImgWrapper.html().split("/a>")[0]+"/a>"+slideImgWrapper.html().split("/a>")[1]+"/a>")).insertAfter(slideAs.last());
if(navshow){
$("<div class='navimgs'></div>").insertAfter(slideImgWrapper);
navimgs = slideWrapper.children('div:last');
navimgs.append("<div class='circlewrapper'></div>");
circlewrapper = navimgs.children('div:first');
for(var i=0;i<imgcountrealy;i++){
circlewrapper.append("<canvas class='circle' width='15' height='15'></canvas>");
}
circles = circlewrapper.children('canvas');
var myCanvas = circles[1];
if (!myCanvas.getContext)
{
canvassuport =false;
}else
{
canvassuport =options.canvassuport;
}
}
}
slideAs = slideImgWrapper.children('a');
slideImgs = slideAs.children('img');
imgcount = slideImgs.length;
var slideWrapperWidth = slideWrapper.width();
var slideWrapperHeight = slideWrapper.height();
slideWrapper.css({"overflow":"hidden","width":slideWrapperWidth,"height":slideWrapperHeight});
slideImgWrapper.css({'position':"absolute","z-index":"1","overflow":"hidden","width":slideWrapperWidth*imgcount,"height":slideWrapperHeight});
slideAs.css({'position':"relative","overflow":"hidden","float":"left","width":slideWrapperWidth,"height":slideWrapperHeight});
slideImgs.css({'position':"relative","z-index":"1","width":slideWrapperWidth,"height":slideWrapperHeight});
if(typeof(navimgs)!=='undefined'){
if(navshow){
navimgs.css({"position":"absolute","z-index":"3","overflow":"hidden","display":"block","width":slideWrapperWidth,"height":slideWrapperWidth*0.05,"bottom":"0"});
if(slideWrapperWidth*0.05>15){
navimgs.height(24);
}
circlewrapper.css({"position":"relative","overflow":"hidden","width":(slideWrapperWidth*0.05*imgcountrealy),"height":slideWrapperWidth*0.04,"margin":"auto"});
circles.css({'position':"relative","float":"left","max-width":15,"max-height":15,"margin-left":slideWrapperWidth*0.01});
if(slideWrapperWidth*0.03>15){
circler=15;
}else{
circler = slideWrapperWidth*0.03;
}
circles.attr("width",circler);
circles.attr("height",circler);
canvacircle(0);
for(var i=0;i<circles.length;i++){
navclick(i);
}
}else{
navimgs.css({"display":"none"});
}
}
if(imgcount<4){
return;
}
slideImgWrapper.css({'left':-slideWrapperWidth});
var st;
var sts;
sts = setTimeout(function(){
timedCount();
},timecontrol); slideWrapper.hover(function(){
stopAll();
},
function(){
sts = setTimeout(function(){
timedCount();
},timecontrol);
});
mouseDrag(slideWrapper);
touchDrag(slideWrapper); function timedCount()
{
if(direction=='left'){
turnleft();
}if(direction=='right'){
turnright();
}
clearTimeout(st);
st=setTimeout(function(){
timedCount();
},timecontrol);
} function stopCount()
{
if (st !=""){
clearTimeout(st);
}
} function stopAll()
{
stopCount();
clearTimeout(sts);
slideImgWrapper.stop(true);
} function navclick(navnum){
circlewrapper.children('canvas:eq('+navnum+')').click(function(e){
scideimgskip(navnum+1);
})
} function scideimgskip(imgnum){
stopAll();
turnleftwidth = imgnum*slideWrapperWidth;
slideImgWrapper.stop(true).animate({left:-turnleftwidth},animatetime,function(){
var imgnum = turnleftwidth/slideWrapperWidth-1;
if(imgnum==0){
imgnum=imgcountrealy;
}
if((imgnum-imgcountrealy)==0){
imgnum=0;
}
canvacircle(imgnum);
});
} function canvacircle(canvanum){
circles.attr("width",circler);
circles.attr("height",circler);
for(var i=0;i<circles.length;i++){
if(canvassuport){
var navCanvas=circles[i];
var cxt=navCanvas.getContext("2d");
if(i==canvanum){
cxt.fillStyle="#0182D7";
}else{
cxt.fillStyle="#ddd";
}
cxt.arc(circler*0.5,circler*0.5,circler*0.5,0,Math.PI*2,true);
cxt.closePath();
cxt.fill();
}else{
circles.css("background","#ddd");
circlewrapper.children('canvas:eq('+canvanum+')').css("background","#0182D7");
} }
} var turnleftwidth = slideWrapperWidth;
function turnleft(){
turnleftwidth = turnleftwidth+slideWrapperWidth;
if(turnleftwidth>(imgcount-2)*slideWrapperWidth){
slideImgWrapper.css({'left':0});
turnleftwidth = slideWrapperWidth;
}
slideImgWrapper.stop(true).animate({left:-turnleftwidth},animatetime,function(){
var imgnum = turnleftwidth/slideWrapperWidth-1;
if(imgnum==0){
imgnum=imgcountrealy;
}
if((imgnum-imgcountrealy)==0){
imgnum=0;
}
canvacircle(imgnum);
});
}
function turnright(){
turnleftwidth = turnleftwidth-slideWrapperWidth;
if(turnleftwidth==0){
slideImgWrapper.css({'left':-slideWrapperWidth*(imgcount-1)});
turnleftwidth = slideWrapperWidth*(imgcount-2);
}
slideImgWrapper.stop(true).animate({left:-turnleftwidth},animatetime,function(){
var imgnum = turnleftwidth/slideWrapperWidth-1;
if(imgnum==0){
imgnum=imgcountrealy;
}
if((imgnum-imgcountrealy)==0){
imgnum=0;
}
canvacircle(imgnum);
});
} var distanceX=0; function toLeft(){
if(turnleftwidth>(imgcount-3)*slideWrapperWidth){
slideImgWrapper.css({"left":distanceX});
turnleftwidth = 0;
}
turnleft();
sts = setTimeout(function(){
timedCount();
},timecontrol);
} function toRight(){
if(turnleftwidth==slideWrapperWidth){
slideImgWrapper.css({'left':-slideWrapperWidth*(imgcount-1)+distanceX});
turnleftwidth = slideWrapperWidth*(imgcount-1);
}
turnright();
sts = setTimeout(function(){
timedCount();
},timecontrol);
} function mouseDrag($element) {
var eventEle = $element;
var stx = etx = curX = 0;
var MAction = false;
var ahrefs = [];
for(var i=0;i<slideAs.length;i++){
if(typeof(slideImgWrapper.children('a:eq('+i+')').attr('href'))!=='undefined'){
ahrefs.push(slideImgWrapper.children('a:eq('+i+')').attr('href'));
}
}
eventEle.mouseover(function(){
for(var i=0;i<slideAs.length;i++){
if(typeof(slideImgWrapper.children('a:eq('+i+')').attr('href'))!=='undefined'){
slideImgWrapper.children('a:eq('+i+')').attr('href',ahrefs[i]);
}
}
});
eventEle.mousemove(function(event){
if(MAction){
var changeX = event.pageX-stx;
slideImgWrapper.css({"left":-turnleftwidth+changeX});
distanceX = changeX;
}
event.preventDefault();
}).mousedown(function(event){
stopAll();
MAction = true;
stx = event.pageX;
event.preventDefault();
});
eventEle.mouseup(function(event){
etx = event.pageX;
curX = etx-stx;
MAction = false;
if(curX>5){
slideAs.attr("href","javascript:void(0)");
toRight();
}
if(curX<-5){
slideAs.attr("href","javascript:void(0)");
toLeft();
}
event.preventDefault();
});
} function touchDrag($element) {
var gundongX = 0;
var gundongY = 0;
var moveEle = $element;
var stx = sty = etx = ety = curX = curY = 0; var ImgWidth_arr = [];
for (var i = 0; i < imgcount; i++) {
ImgWidth_arr.push(i * slideWrapperWidth);
} moveEle.on("touchstart", function(event) { //touchstart
stopAll();
var event = event.originalEvent;
gundongX = 0;
gundongY = 0;
// 元素当前位置
etx = parseInt(getT3d(moveEle, "x"));
ety = parseInt(getT3d(moveEle, "y"));
// 手指位置
stx = event.touches[0].pageX;
sty = event.touches[0].pageY;
});
moveEle.on("touchmove", function(event) {
var event = event.originalEvent;
// 防止拖动页面
event.preventDefault(); // 手指位置 减去 元素当前位置 就是 要移动的距离
gundongX = event.touches[0].pageX - stx;
gundongY = event.touches[0].pageY - sty; // 目标位置 就是 要移动的距离 加上 元素当前位置
curX = gundongX + etx;
curY = gundongY + ety;
slideImgWrapper.css({"left":-turnleftwidth+curX});
distanceX = curX;
});
moveEle.on("touchend", function(event) {
//alert(gundongX);
if(Math.abs(gundongX)>5){
event.preventDefault(); // 手指接触屏幕的位置
var oriX = etx;
var oriY = ety;
// 手指离开屏幕的位置
etx = curX;
ety = curY;
var slidePosition = 0;
for (var i = 0; i < imgcount - 1; i++) {
if (Math.abs(etx) > ImgWidth_arr[i]) { if (oriX > etx) {
// 左滑
toLeft();
} else {
// 右滑
toRight();
}
}
}
} }); function getT3d(elem, ename) {
var elem = elem[0];
var str1 = elem.style.webkitTransform;
if (str1 == "") return "0";
str1 = str1.replace("translate3d(", "");
str1 = str1.replace(")", "");
var carr = str1.split(","); if (ename == "x") return carr[0];
else if (ename == "y") return carr[1];
else if (ename == "z") return carr[2];
else return "";
}
}
});
};
})(jQuery);
3.整体思路
a.创建显示窗口,显示容器大小位置自定义;
b.创立图片容器,通过改变图片容器的位置来改变显示窗口中展示的图片。
难点在于如何改变图片容器位置来显示需要的图片和无缝轮播。可以想象一下以前的胶带式电影,如果放映速度慢下来就跟图片轮播类似了。所以可以把图片容器看成胶带,图片就是其中的一帧图像,显示窗口就是电影屏幕。
如果以一个显示窗口的宽为一个单位,我们把图片水平排放在图片容器中,每张图片恰好占用一个显示窗口的宽高,有多少张图片,图片容器的宽就为多少个单位宽。然后使图片向左移动一个单位的距离,就可以展示下一张图片了。为了使图片展示效果更美观,我用了jquery的动画效果animate()来改变图片容器的位置。如果设定间隔多少时间图片容器左移一个单位,达到最后一张图片时,图片容器恢复到原始位置,进行下一轮移动。这样,就可以实现图片的水平轮播了。至于无缝轮播,我采取的做法是把前两张图片复制一份,放到所有图片的最后面。首次显示第二张图片,当移动到倒数第二张图片时,在下一次移动时先改变容器的left,让第一张图片被显示出来,因为这个动作很快,看起来好像并没有进行任何操作(达到欺骗眼球的效果,呵呵),然后使用animate显示第二张图片,在视觉上实现无缝轮播。从第二张图片右移时也与此类似。这样做的主要目的是为了确保左右都有能被展示的图片,确保不会显示空白,以实现无缝切换。这里,会用到的主要知识点有:
(1).setTimeout和clearTimeout:
用于延迟执行、循环执行和终止循环。setTimeout延迟执行确定图片的显示时间,循环执行为了自动展示下一张图片。当需要停止轮播的时候就可以用clearTimeout来终止循环了。关于setTimeout和clearTimeout的具体用法,可以参照代码,这里就不再赘述了。
(2).jquery选择器:
无需多说,所有jquery动作的基础。
(3).jquery操作css:
为了保证使用的简单性,只需确定显示容器的样式(需确保overflow:hidden;插件中已设置),其子元素包括图片容器(这里只支持div标签slideWrapper.children('div:eq(0)'))和图片及其链接的样式都在插件中确定,包括:保证图片水平排列,大小恰好为显示窗口的大小;确定图片容器的大小恰好容下所有图片。
(4).jquery添加元素insertAfter:
复制前两张图片到所有图片的最后面$((slideImgWrapper.html().split("/div>")[0]+"/div>"+slideImgWrapper.html().split("/div>")[1]+"/div>")).insertAfter(slideAWra.last())。
(5).jquery动画效果animate:
var turnleftwidth = slideWrapperWidth;
function turnleft(){
turnleftwidth = turnleftwidth+slideWrapperWidth;
if(turnleftwidth>(imgcount-2)*slideWrapperWidth){
slideImgWrapper.css({'left':0});
turnleftwidth = slideWrapperWidth;
}
slideImgWrapper.stop(true).animate({left:-turnleftwidth},animatetime);
}
function turnright(){
turnleftwidth = turnleftwidth-slideWrapperWidth;
if(turnleftwidth==0){
slideImgWrapper.css({'left':-slideWrapperWidth*(imgcount-1)});
turnleftwidth = slideWrapperWidth*(imgcount-2);
}
slideImgWrapper.stop(true).animate({left:-turnleftwidth},animatetime);
}
其中imgcount为进行图片复制后图片的元素个数,slideWrapperWidth为显示窗口的宽。 turnleft()用于无缝左移,turnright()用于无缝右移。
现在来说说触屏支持。主要是用了jquery的on方法监听touch事件。具体怎么写,无非就是设置初始触摸位置,然后监听滑动的位置,根据水平滑动的具体实时改变图片容器的left,实现拖拽的效果。滑动结束后根据结束时的位置与初始位置的差判断左滑还是右滑,再来改变图片容器的left,使图片正好居中显示。跟PC端的鼠标拖拽类似。说到鼠标拖拽,不得不喷俩句。一般拖拽元素,基本都是mousedown、mousemove、mouseup三部曲。但是碰上图片就头疼了,特别是这图片的父亲还是a标签。mousedown没问题,mousemove能一个三五步,mousemove出问题mouseup也就失效了。弄了半天,终于通过 event.preventDefault()实现了对大部分浏览器的支持。废话不多说,让大家一起纠结下。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="UTF-8">
<head>
<meta charset="UTF-8">
<style>
body{
overflow-x:hidden;
margin:0 auto;
padding:0;
width: 100%;
height: 100%;
}
.aWrapper{
position: relative;
margin:0 auto;
width:400px;
height:600px;
overflow:hidden;
//float:left;
}
.testa{
position: relative;
margin:0 auto;
width:400px;
height:600px;
//float:left;
}
.testimg{
position: absolute;
width:400px;
height:600px;
z-index:0;
}
.imgmask{
position: relative;
width:400px;
height:600px;
z-index:1;
opacity:0.2;
background:#333;
}
</style>
</head>
<body>
<div class="aWrapper">
<a href="http://www.baidu.com" class="testa">
<img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/1 (1).jpg" class="testimg"/>
<div class='imgmask'></div>
</a>
</div>
</body>
</html>
上面测试页面只有在Safari内核的浏览器(如Chrome)下才能够拖拽的,而且当图片遮罩层的position设置为absolute或者a标签设置float时都会失效,实在是搞不明白。而且要说一下可以很容易的阻止事件向上冒泡,有什么办法触发父元素事件是不要触发子元素的该事件么?还是以上面的测试页面为例,要拖拽aWrapper的div,就要设置该元素的mousedown、mousemove、mouseup事件。但是这里有一个问题,在mousedown和mouseup之后会触发click事件,导致触发子元素a标签的click而跳转页面。如果仅仅在mouseup时设置a标签的click返回false,那么这个链接就永远失效了。具体处理方法,大家还是看代码吧,反正被我搞得复杂得很,说多了都是泪。
最后说说这个导航栏,就是下面的方方圈圈,用来显示第几张和点击跳转的。如果直接在页面上编写,问题倒还简单。在JS中就复杂多了。为了确保插件的独立性,除了对jquery的依赖外,我不想它有任何其他依赖。所以一般用图片来表示状态的方法就行不通了。我用的是html5的canvas绘制圆形。如果浏览器不支持或者担心浏览器消耗的话,可以关闭掉,直接用背景色表示,只是只能为方块块了。反正我觉得我自己弄的既不美观又不优雅,大家就当参照吧。
支持触屏的jQuery轮播图插件的更多相关文章
- 支持触屏的zepto轮播图插件
占个座,有时间再写,呵呵 关于zepto.js,官方标准版是不支持touch的.可以去github下载压缩包,里面有所有支持的模块.我用的zepto.js,是经过打包的,包括polyfill zept ...
- jquery的fadeTo方法的淡入淡出轮播图插件
由于对基于jquery的简单插件开发有了一定的了解,慢慢的也对基于jquery的插件开发有了兴趣,在上班结束之后就研究各种插件的思路逻辑.最近开发了一款基于jquery的fadeTo方法的轮播图插件, ...
- 原生js写一个无缝轮播图插件(支持vue)
轮播图插件(Broadcast.js) 前言:写这个插件的原因 前段时间准备用vue加上网易云的nodejs接口,模拟网易云音乐移动端.因为想自己写一遍所有的代码以及加固自己的flex布局,所以没有使 ...
- jquery, js轮播图插件Swiper3
轮播图插件Swiper3 HTML代码 如果只是简单的使用轮播图,直接复制我的html代码就可以. 如果想要高级一些,就自己去看文档吧 <!DOCTYPE html> <html l ...
- 学习笔记: js插件 —— SuperSlide 2 (轮播图插件,PC用)
SuperSlide 2 轮播图插件,较老.但还好用. 适用于PC,是绑定到jquery上的方法: $.slide(); 如果在实际中找不到.slide方法,请检查jquery等.js文件的引入次序 ...
- Vue轮播图插件---Vue-Awesome-Swiper
轮播图插件 Vue-Awesome-Swiper 地址:https://github.com/surmon-china/vue-awesome-swiper 安装:npm install vue-aw ...
- 封装一个简单的原生js焦点轮播图插件
轮播图实现的效果为,鼠标移入左右箭头会出现,可以点击切换图片,下面的小圆点会跟随,可以循环播放(为了方便理解,没有补2张图做无缝轮播).本篇文章的主要目的是分享封装插件的思路. 轮播图我一开始是写成非 ...
- 第124天:移动web端-Bootstrap轮播图插件使用
Bootstrap JS插件使用 > 对于Bootstrap的JS插件,我们只需要将文档实例中的代码粘到我们自己的代码中> 然后作出相应的样式调整 Bootstrap中轮播图插件叫作Car ...
- 原生JavaScript(js)手把手教你写轮播图插件(banner)
---恢复内容开始--- 1.轮播图插件 1.什么是插件: 为已有的程序增加功能 2.插件的特点(为什么要做成一个插件)与注意事项: 1.通用性,可移植性强 2.兼容性:不会对其他代码产生影响 3.创 ...
随机推荐
- Django template的html明明改了,前端页面居然没有对应变化?!---Django的小坑
写django的时候,我有个模板的名字叫detail.html,被detail视图函数渲染 因为那个detail写乱了,但是里面有东西要参考,我没删掉它,改名为detail_old.html,又在目录 ...
- zabbix 3.0 快速安装文档
下载地址:http://www.zabbix.com/download.php 官方文档:https://www.zabbix.com/documentation/3.0/manual/install ...
- 使用原生实现jquery中的css方法
由于jquery放在mobile页面上,有时候还是显得有点大,所以今天尝试使用原生来开发,但是习惯了jquery之后,转用原生开发之后,发现原生中,找不到可以替代jquery的css方法,于是对原生的 ...
- linux系统下的日志,此日志对于系统安全来说是非常重要的一 个机制!!
var/log/messages /etc/logrotate.conf 日志切割配置文件 (参考https://my.oschina.net/u/2000675/blog/908189) dmesg ...
- R语言学习笔记(四)
6. 数据转换 本章主要讲述apply系列函数:apply.lapply.sapply.tapply.mapply,以及姊妹函数by.split.适用于批量处理数据,而不许循环. 6.1 向量分组 用 ...
- linux安装PHP7以及扩展
Linux下安装PHP7 事先升级gcc4.8,然后安装PHP7,安装步骤参考:CentOS安装PHP7 1.Linux下编译的php没有php.ini 解决办法:从源代码目录中复制php.ini-d ...
- [转] #!/bin/sh & #!/bin/bash区别
[From] http://blog.51cto.com/meiling/1826201 在shell脚本的开头往往有一句话来定义使用哪种sh解释器来解释脚本.目前研发送测的shell脚本中主要有以下 ...
- PIE SDK线元素的绘制
1. 功能简介 在数据的处理中会用到线元素的绘制,目前PIE SDK支持ILineSymbol的线元素的绘制,LineSymbol对象是用于修饰线状对象的符号,它包括CartographicLineS ...
- java c c++大学补遗
第一次面试时的问题是一个看起来50多数的老工程师问的, 仍然记忆犹新 java(面向对象)的基本特性? 封装 继承 多态 工作几年后,各种框架用来用去, 回想起这个问题,java也就剩下这几个特性了
- python练习七十:图片生成
题目:使用python生成类似于下图的字母验证码图片 实现代码: from PIL import Image,ImageFont,ImageDraw,ImageFilter import random ...