cloudgamer出品ImageZoom 图片放大效果


Posted in Javascript onApril 01, 2010

一般用于放大查看商品图片,在凡客,京东商城,阿里巴巴等都有类似的效果。
好处是能在原图附近对图片进行局部放大查看,而且可以通过鼠标控制查看的部位。
前一阵子看到sohighthesky的图片放大效果,心血来潮自己也写一个看看。
这个程序有以下特点:
1,支持使用原图放大或新图片设置大图;
2,大图完成载入前使用原图放大代替,减少操作等待时间;
3,支持鼠标滚动缩放大图;
4,可以通过设置显示范围或显示框大小设置显示尺寸;
5,可以设置是否自动隐藏显示框;
6,支持插件形式的扩展来实现更多的功能(下一篇再详细介绍)。
兼容:ie6/7/8, firefox 3.6.2, opera 10.51, safari 4.0.4, chrome 4.1

var styles; 
if ( !viewer.clientWidth ) { 
var style = viewer.style; 
styles = { 
display: style.display, 
position: style.position, 
visibility: style.visibility 
}; 
$$D.setStyle( viewer, { 
display: "block", position: "absolute", visibility: "hidden" 
}); 
} 
this._viewerWidth = viewer.clientWidth; 
this._viewerHeight = viewer.clientHeight; 
if ( styles ) { $$D.setStyle( viewer, styles ); } 
rangeWidth = Math.ceil( this._viewerWidth / scale ); 
rangeHeight = Math.ceil( this._viewerHeight / scale );

注意,显示范围是通过clientWidth/clientHeight来获取的。
如果显示框是display为none的隐藏状态,就不能直接获取clientWidth/clientHeight。
这种情况下,程序用以下方法获取:
1,记录display/position/visibility的原始值;
2,分别设为"block"/"absolute"/"hidden",这是既能隐藏也能占位的状态;
3,获取参数;
4,重新设回原始值,恢复原来的状态。
得到显示范围后,再配合比例就能得到范围参数了。
ps:这是通用的获取不占位元素尺寸参数的方法,jquery的css也是用这个方法获取width/height的。
比例计算后可能会得到小数,而尺寸大小只能是整数,程序一律使用Math.ceil来取整。
【放大效果】
所有东西都设置好后,就可以执行start设置触发程序了。
程序会自动执行start方法,里面主要是给原图对象的mouseover/mousemove绑定_start程序:
var image = this._image, START = this._START;
$$E.addEvent( image, "mouseover", START );
$$E.addEvent( image, "mousemove", START );
分别对应移入原图对象和在原图对象上移动的情况。
ps:如果使用attachEvent的话还要注意重复绑定同一函数的问题,这里的addEvent就没有这个问题。
绑定的_start程序,主要是进行一些事件的解绑和绑定:
$$E.removeEvent( image, "mouseover", this._START ); 
$$E.removeEvent( image, "mousemove", this._START ); 
$$E.addEvent( document, "mousemove", this._MOVE ); 
$$E.addEvent( document, "mouseout", this._OUT );

为了在移出窗口时能结束放大效果,给document的mouseout绑定了_OUT程序:
this._OUT = $$F.bindAsEventListener( function(e){ 
if ( !e.relatedTarget ) this._END(); 
}, this );

当鼠标移出document会触发mouseout,如果当前relatedTarget是null的话,就延时执行_end结束程序:
var oThis = this, END = function(){ oThis._end(); };
this._END = function(){ oThis._timer = setTimeout( END, oThis.delay ); };
在_end程序中,会先执行stop方法,在里面移除所有可能绑定的事件,再执行start方法继续等待触发。
而mousemove绑定的_move移动程序,主要用来实现鼠标移动到哪里就放大哪里的功能。
为适应更多的情况(例如扩展篇的其他模式),把它绑定到document上,但也因此不能用mouseout事件来触发移出程序。
程序通过鼠标和原图的坐标比较,来判断鼠标是否移出原图对象范围:
var x = e.pageX, y = e.pageY, rect = this._rect; 
if ( x < rect.left || x > rect.right || y < rect.top || y > rect.bottom ) { 
this._END(); 
} else { 
... 
}

如果鼠标移出原图对象的话,就执行_END结束放大效果。
如果鼠标在原图对象上移动,就计算坐标,并通过_repair程序把坐标转化成定位需要的值。
最后设置大图的left/top定位使显示框显示要放大的部位。
ps:我尝试过用scrollLeft/scrollTop来做定位,但发现这样在ie中会像锯齿那样移动,放得越大越明显,所以放弃。
【鼠标滚动缩放】
如果设置mouse属性为true,就会开启鼠标滚动缩放功能。
在执行放大效果期间,可以通过滚动鼠标滚轮对大图进行缩放处理。
其实就是根据滚轮动参数的变化来修改放大比例。
关于鼠标滚动事件,在slider中也提过,不过那时只分析了ie和ff的区别,这里再分析一下。
首先ie是用mousewheel绑定事件的,使用event的wheelDelta来获取滚动参数。
其他浏览器用以下代码测试:
<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<body style="height:1000px;"> 
<script> 
function test(e){ alert(e.type+":"+e.detail+"_"+e.wheelDelta) } 
document.addEventListener( "DOMMouseScroll", test, false ); 
document.addEventListener( "mousewheel", test, false ); 
</script> 
</body> 
</html>

向下滚动一下,可以得到以下结果:
ff:DOMMouseScroll:3_undefined
opera:mousewheel:3_-120
chrome/safari:mousewheel:0_-120
可以看到事件的绑定,ff只支持DOMMouseScroll,其他就只支持mousewheel。
而滚动参数的获取,ff只支持detail,opera两种都支持,chrome/safari就支持wheelDelta。
ps:不明白chrome/safari的detail为什么是0,有其他用途?
而DOMMouseScroll跟mousewheel还有一个不同是前者不能直接绑定元素,后者可以。
即可以elem.onmousewheel,但不能elem.onDOMMouseScroll。
根据以上分析,在_start程序里是这样把_mouse程序绑定到document的滚动事件中:
this.mouse && $$E.addEvent( document, $$B.firefox ? "DOMMouseScroll" : "mousewheel", this._MOUSE );
在_mouse程序里面根据滚动参数和自定义的rate缩放比率得到新的放大比例:
this._scale += ( e.wheelDelta ? e.wheelDelta / (-120) : (e.detail || 0) / 3 ) * this.rate;
修改比例时,程序参数也需要重新计算。
由于_rangeWidth/_rangeHeight会影响计算的过程,要重新恢复成自定义的默认值:
var opt = this.options;
this._rangeWidth = opt.rangeWidth;
this._rangeHeight = opt.rangeHeight;
然后执行_initSize和_initData重新设置尺寸和参数,再执行_move重新定位。
最后记得用preventDefault防止触发页面滚动。
使用技巧
【图片设置】
程序支持大图使用原图放大或用新大图。
如果用新大图而且图片比较大的话,强烈建议设置放大比例,这样程序会自动在大图载入前先使用原图放大,这样就不用等待大图加载完成。
还要注意新大图本身的宽高比例要跟原图一致,否则就对不准坐标了,使用原图放大就没有这个问题。
【显示框设置】
有两个方法可以设置显示框的尺寸:
要固定显示范围的话,先设置rangeWidth/rangeHeight,程序会根据显示范围和放大比例计算显示框的尺寸;
要用显示框当前的尺寸来显示的话,只要不设置rangeWidth/rangeHeight或设为0就可以了。
【reset】
由于各个属性和对象之间有很多的关联,很多属性不能直接修改。
程序设置了一个reset方法专门用来修改这类属性的。
如果程序加载完成后又修改了影响程序计算的样式,例如原图大小,显示框大小等,也要执行一次reset来重新设置参数和属性。
【浮动定位】
程序没有设置显示框浮动定位的功能,需要的话可以自行添加。
简单的定位可以参考实例的方法,还要小心覆盖select的问题。
如果要更复杂的浮动定位,可以参考“浮动定位提示效果”。
【opera的bug】
测试中发现opera 10.10有两个bug。
分别是img元素设置透明时会看到背景图,用js修改鼠标样式会有问题。
不过这两个问题在10.50都已经修复了,还没升级的赶快升啦。
【maxthon的bug】
用maxthon 2.5.1测试时发现一个问题,测试以下代码:
<div id="t" style="width:50px;"></div> 
<script> 
var t=document.getElementById("t"); 
t.clientWidth; 
t.style.display="none"; 
alert(t.clientWidth); 
</script>

一般来说用display隐藏后,clientWidth应该是0的,但maxthon貌似没有处理这个情况。
这会影响到程序中clientWidth的判断,不过对一般使用没什么影响。
我已经提交了这个问题,不知会不会处理。
使用说明
实例化时,必须有一个img元素作为原图对象,和一个容器作为显示框:
var iz = new ImageZoom( "idImage", "idViewer" );
可选参数用来设置系统的默认属性,包括:
属性: 默认值//说明
mode: "simple",//模式
scale: 0,//比例(大图/原图)
max: 10,//最大比例
min: 1.5,//最小比例
originPic: "",//原图地址
zoomPic: "",//大图地址
rangeWidth: 0,//显示范围宽度
rangeHeight:0,//显示范围高度
delay: 20,//延迟结束时间
autoHide: true,//是否自动隐藏
mouse: false,//鼠标缩放
rate: .2,//鼠标缩放比率
onLoad: $$.emptyFunction,//加载完成时执行
onStart: $$.emptyFunction,//开始放大时执行
onMove: $$.emptyFunction,//放大移动时执行
onEnd: $$.emptyFunction//放大结束时执行
其中模式的使用在下一篇扩展篇再说明。
初始化后,scale、max、min、originPic、zoomPic、rangeWidth、rangeHeight这些属性需要用reset方法来修改。
还提供了以下方法:
start:开始放大程序(程序会自动执行);
stop:停止放大程序;
reset:修改设置;
dispose:销毁程序。
程序源码
var ImageZoom = function(image, viewer, options) { 
this._initialize( image, viewer, options ); 
this._initMode( this.options.mode ); 
this._oninit(); 
this._initLoad(); 
}; 
ImageZoom.prototype = { 
//初始化程序 
_initialize: function(image, viewer, options) { 
this._image = $$(image);//原图 
this._zoom = document.createElement("img");//显示图 
this._viewer = $$(viewer);//显示框 
this._viewerWidth = 0;//显示框宽 
this._viewerHeight = 0;//显示框高 
this._preload = new Image();//预载对象 
this._rect = null;//原图坐标 
this._repairLeft = 0;//显示图x坐标修正 
this._repairTop = 0;//显示图y坐标修正 
this._rangeWidth = 0;//显示范围宽度 
this._rangeHeight = 0;//显示范围高度 
this._timer = null;//计时器 
this._loaded = false;//是否加载 
this._substitute = false;//是否替换 
var opt = this._setOptions(options); 
this._scale = opt.scale; 
this._max = opt.max; 
this._min = opt.min; 
this._originPic = opt.originPic; 
this._zoomPic = opt.zoomPic; 
this._rangeWidth = opt.rangeWidth; 
this._rangeHeight = opt.rangeHeight; 
this.delay = opt.delay; 
this.autoHide = opt.autoHide; 
this.mouse = opt.mouse; 
this.rate = opt.rate; 
this.onLoad = opt.onLoad; 
this.onStart = opt.onStart; 
this.onMove = opt.onMove; 
this.onEnd = opt.onEnd; 
var oThis = this, END = function(){ oThis._end(); }; 
this._END = function(){ oThis._timer = setTimeout( END, oThis.delay ); }; 
this._START = $$F.bindAsEventListener( this._start, this ); 
this._MOVE = $$F.bindAsEventListener( this._move, this ); 
this._MOUSE = $$F.bindAsEventListener( this._mouse, this ); 
this._OUT = $$F.bindAsEventListener( function(e){ 
if ( !e.relatedTarget ) this._END(); 
}, this ); 
}, 
//设置默认属性 
_setOptions: function(options) { 
this.options = {//默认值 
mode: "simple",//模式 
scale: 0,//比例(大图/原图) 
max: 10,//最大比例 
min: 1.5,//最小比例 
originPic: "",//原图地址 
zoomPic: "",//大图地址 
rangeWidth: 0,//显示范围宽度 
rangeHeight:0,//显示范围高度 
delay: 20,//延迟结束时间 
autoHide: true,//是否自动隐藏 
mouse: false,//鼠标缩放 
rate: .2,//鼠标缩放比率 
onLoad: $$.emptyFunction,//加载完成时执行 
onStart: $$.emptyFunction,//开始放大时执行 
onMove: $$.emptyFunction,//放大移动时执行 
onEnd: $$.emptyFunction//放大结束时执行 
}; 
return $$.extend(this.options, options || {}); 
}, 
//根据模式初始化函数属性 
_initMode: function(mode) { 
mode = $$.extend({ 
options:{}, 
init: $$.emptyFunction, 
load: $$.emptyFunction, 
start: $$.emptyFunction, 
end: $$.emptyFunction, 
move: $$.emptyFunction, 
dispose:$$.emptyFunction 
}, (ImageZoom._MODE || {})[ mode.toLowerCase() ] || {} ); 
this.options = $$.extend( mode.options, this.options ); 
this._oninit = mode.init; 
this._onload = mode.load; 
this._onstart = mode.start; 
this._onend = mode.end; 
this._onmove = mode.move; 
this._ondispose = mode.dispose; 
}, 
//初始化加载 
_initLoad: function() { 
var image = this._image, originPic = this._originPic, 
useOrigin = !this._zoomPic && this._scale, 
loadImage = $$F.bind( useOrigin ? this._loadOriginImage : this._loadImage, this ); 
//设置自动隐藏 
if ( this.autoHide ) { this._viewer.style.display = "none"; } 
//先加载原图 
if ( originPic && originPic != image.src ) {//使用自定义地址 
image.onload = loadImage; 
image.src = originPic; 
} else if ( image.src ) {//使用元素地址 
if ( !image.complete ) {//未载入完 
image.onload = loadImage; 
} else {//已经载入 
loadImage(); 
} 
} else { 
return;//没有原图地址 
} 
//加载大图 
if ( !useOrigin ) { 
var preload = this._preload, zoomPic = this._zoomPic || image.src, 
loadPreload = $$F.bind( this._loadPreload, this ); 
if ( zoomPic != preload.src ) {//新地址重新加载 
preload.onload = loadPreload; 
preload.src = zoomPic; 
} else {//正在加载 
if ( !preload.complete ) {//未载入完 
preload.onload = loadPreload; 
} else {//已经载入 
this._loadPreload(); 
} 
} 
} 
}, 
//原图放大加载程序 
_loadOriginImage: function() { 
this._image.onload = null; 
this._zoom.src = this._image.src; 
this._initLoaded(); 
}, 
//原图加载程序 
_loadImage: function() { 
this._image.onload = null; 
if ( this._loaded ) {//大图已经加载 
this._initLoaded(); 
} else { 
this._loaded = true; 
if ( this._scale ) {//有自定义比例才用原图放大替换大图 
this._substitute = true; 
this._zoom.src = this._image.src; 
this._initLoaded(); 
} 
} 
}, 
//大图预载程序 
_loadPreload: function() { 
this._preload.onload = null; 
this._zoom.src = this._preload.src; 
if ( this._loaded ) {//原图已经加载 
//没有使用替换 
if ( !this._substitute ) { this._initLoaded(); } 
} else { 
this._loaded = true; 
} 
}, 
//初始化加载设置 
_initLoaded: function(src) { 
//初始化显示图 
this._initSize(); 
//初始化显示框 
this._initViewer(); 
//初始化数据 
this._initData(); 
//开始执行 
this._onload(); 
this.onLoad(); 
this.start(); 
}, 
//初始化显示图尺寸 
_initSize: function() { 
var zoom = this._zoom, image = this._image, scale = this._scale; 
if ( !scale ) { scale = this._preload.width / image.width; } 
this._scale = scale = Math.min( Math.max( this._min, scale ), this._max ); 
//按比例设置显示图大小 
zoom.width = Math.ceil( image.width * scale ); 
zoom.height = Math.ceil( image.height * scale ); 
}, 
//初始化显示框 
_initViewer: function() { 
var zoom = this._zoom, viewer = this._viewer; 
//设置样式 
var styles = { padding: 0, overflow: "hidden" }, p = $$D.getStyle( viewer, "position" ); 
if ( p != "relative" && p != "absolute" ){ styles.position = "relative"; }; 
$$D.setStyle( viewer, styles ); 
zoom.style.position = "absolute"; 
//插入显示图 
if ( !$$D.contains( viewer, zoom ) ){ viewer.appendChild( zoom ); } 
}, 
//初始化数据 
_initData: function() { 
var zoom = this._zoom, image = this._image, viewer = this._viewer, 
scale = this._scale, rangeWidth = this._rangeWidth, rangeHeight = this._rangeHeight; 
//原图坐标 
this._rect = $$D.rect( image ); 
//修正参数 
this._repairLeft = image.clientLeft + parseInt($$D.getStyle( image, "padding-left" )); 
this._repairTop = image.clientTop + parseInt($$D.getStyle( image, "padding-top" )); 
//设置范围参数和显示框大小 
if ( rangeWidth > 0 && rangeHeight > 0 ) { 
rangeWidth = Math.ceil( rangeWidth ); 
rangeHeight = Math.ceil( rangeHeight ); 
this._viewerWidth = Math.ceil( rangeWidth * scale ); 
this._viewerHeight = Math.ceil( rangeHeight * scale ); 
$$D.setStyle( viewer, { 
width: this._viewerWidth + "px", 
height: this._viewerHeight + "px" 
}); 
} else { 
var styles; 
if ( !viewer.clientWidth ) {//隐藏 
var style = viewer.style; 
styles = { 
display: style.display, 
position: style.position, 
visibility: style.visibility 
}; 
$$D.setStyle( viewer, { 
display: "block", position: "absolute", visibility: "hidden" 
}); 
} 
this._viewerWidth = viewer.clientWidth; 
this._viewerHeight = viewer.clientHeight; 
if ( styles ) { $$D.setStyle( viewer, styles ); } 
rangeWidth = Math.ceil( this._viewerWidth / scale ); 
rangeHeight = Math.ceil( this._viewerHeight / scale ); 
} 
this._rangeWidth = rangeWidth; 
this._rangeHeight = rangeHeight; 
}, 
//开始 
_start: function() { 
clearTimeout( this._timer ); 
var viewer = this._viewer, image = this._image, scale = this._scale; 
viewer.style.display = "block"; 
this._onstart(); 
this.onStart(); 
$$E.removeEvent( image, "mouseover", this._START ); 
$$E.removeEvent( image, "mousemove", this._START ); 
$$E.addEvent( document, "mousemove", this._MOVE ); 
$$E.addEvent( document, "mouseout", this._OUT ); 
this.mouse && $$E.addEvent( document, $$B.firefox ? "DOMMouseScroll" : "mousewheel", this._MOUSE ); 
}, 
//移动 
_move: function(e) { 
clearTimeout( this._timer ); 
var x = e.pageX, y = e.pageY, rect = this._rect; 
if ( x < rect.left || x > rect.right || y < rect.top || y > rect.bottom ) { 
this._END();//移出原图范围 
} else { 
var zoom = this._zoom, 
pos = this._repair( 
x - rect.left - this._repairLeft, 
y - rect.top - this._repairTop 
); 
this._onmove( e, pos ); 
//设置定位 
zoom.style.left = pos.left + "px"; 
zoom.style.top = pos.top + "px"; 
this.onMove(); 
} 
}, 
//修正坐标 
_repair: function(x, y) { 
var scale = this._scale, zoom = this._zoom, 
viewerWidth = this._viewerWidth, 
viewerHeight = this._viewerHeight; 
//修正坐标 
x = Math.ceil( viewerWidth / 2 - x * scale ); 
y = Math.ceil( viewerHeight / 2 - y * scale ); 
//范围限制 
x = Math.min( Math.max( x, viewerWidth - zoom.width ), 0 ); 
y = Math.min( Math.max( y, viewerHeight - zoom.height ), 0 ); 
return { left: x, top: y }; 
}, 
//结束 
_end: function() { 
this._onend(); 
this.onEnd(); 
if ( this.autoHide ) { this._viewer.style.display = "none"; } 
this.stop(); 
this.start(); 
}, 
//鼠标缩放 
_mouse: function(e) { 
this._scale += ( e.wheelDelta ? e.wheelDelta / (-120) : (e.detail || 0) / 3 ) * this.rate; 
var opt = this.options; 
this._rangeWidth = opt.rangeWidth; 
this._rangeHeight = opt.rangeHeight; 
this._initSize(); 
this._initData(); 
this._move(e); 
e.preventDefault(); 
}, 
//开始 
start: function() { 
if ( this._viewerWidth && this._viewerHeight ) { 
var image = this._image, START = this._START; 
$$E.addEvent( image, "mouseover", START ); 
$$E.addEvent( image, "mousemove", START ); 
} 
}, 
//停止 
stop: function() { 
clearTimeout( this._timer ); 
$$E.removeEvent( this._image, "mouseover", this._START ); 
$$E.removeEvent( this._image, "mousemove", this._START ); 
$$E.removeEvent( document, "mousemove", this._MOVE ); 
$$E.removeEvent( document, "mouseout", this._OUT ); 
$$E.removeEvent( document, $$B.firefox ? "DOMMouseScroll" : "mousewheel", this._MOUSE ); 
}, 
//修改设置 
reset: function(options) { 
this.stop(); 
var viewer = this._viewer, zoom = this._zoom; 
if ( $$D.contains( viewer, zoom ) ) { viewer.removeChild( zoom ); } 
var opt = $$.extend( this.options, options || {} ); 
this._scale = opt.scale; 
this._max = opt.max; 
this._min = opt.min; 
this._originPic = opt.originPic; 
this._zoomPic = opt.zoomPic; 
this._rangeWidth = opt.rangeWidth; 
this._rangeHeight = opt.rangeHeight; 
//重置属性 
this._loaded = this._substitute = false; 
this._rect = null; 
this._repairLeft = this._repairTop = 
this._viewerWidth = this._viewerHeight = 0; 
this._initLoad(); 
}, 
//销毁程序 
dispose: function() { 
this._ondispose(); 
this.stop(); 
if ( $$D.contains( this._viewer, this._zoom ) ) { 
this._viewer.removeChild( this._zoom ); 
} 
this._image.onload = this._preload.onload = 
this._image = this._preload = this._zoom = this._viewer = 
this.onLoad = this.onStart = this.onMove = this.onEnd = 
this._START = this._MOVE = this._END = this._OUT = null 
} 
}

转载请注明出处:http://www.cnblogs.com/cloudgamer/

如有任何建议或疑问,欢迎留言讨论。
打包下载地址

Javascript 相关文章推荐
js中查找最近的共有祖先元素的实现代码
Dec 30 Javascript
js获取IFRAME当前的URL的方法
Nov 13 Javascript
JQuery实现鼠标移动到图片上显示边框效果
Jan 09 Javascript
两种方法基于jQuery实现IE浏览器兼容placeholder效果
Oct 14 Javascript
onclick和onblur冲突问题的快速解决方法
Apr 28 Javascript
jQuery插件easyUI实现通过JS显示Dialog的方法
Sep 16 Javascript
基于js文件加载优化(详解)
Jan 03 Javascript
vue使用axios上传文件(FormData)的方法
Apr 14 Javascript
vue路由拦截器和请求拦截器知识点总结
Nov 08 Javascript
JS中间件设计模式的深入探讨与实例分析
Apr 11 Javascript
vue模块移动组件的实现示例
May 20 Javascript
基于JavaScript实现简单抽奖功能代码实例
Oct 20 Javascript
js 异步处理进度条
Apr 01 #Javascript
JavaScript中String和StringBuffer的速度之争
Apr 01 #Javascript
Cookie 小记
Apr 01 #Javascript
javascript操作cookie的文章(设置,删除cookies)
Apr 01 #Javascript
在模板页面的js使用办法
Apr 01 #Javascript
使用Microsoft Ajax Minifier减小JavaScript文件大小的方法
Apr 01 #Javascript
JS控制显示隐藏兼容问题(IE6、IE7、IE8)
Apr 01 #Javascript
You might like
SMARTY学习手记
2007/01/04 PHP
php 正则 过滤html 的超链接
2009/06/02 PHP
php 模拟post_验证页面的返回状态(实例讲解)
2013/10/28 PHP
php数组中包含中文的排序方法
2014/06/03 PHP
用PHP代替JS玩转DOM的思路及示例代码
2014/06/15 PHP
php实现用于验证所有类型的信用卡类
2015/03/24 PHP
PHP封装的PDO数据库操作类实例
2017/06/21 PHP
PHP使用Redis长连接的方法详解
2018/02/12 PHP
IE8 原生JSON支持
2009/04/13 Javascript
JavaScript 全角转半角部分
2009/10/28 Javascript
jQuery旋转插件—rotate支持(ie/Firefox/SafariOpera/Chrome)
2013/01/16 Javascript
javascript跨浏览器的属性判断方法
2014/03/16 Javascript
node+express+jade制作简单网站指南
2014/11/26 Javascript
jquery.cookie.js实现用户登录保存密码功能的方法
2016/04/15 Javascript
在Javascript操作JSON对象,增加 删除 修改的简单实现
2016/06/02 Javascript
提高Web性能的前端优化技巧总结
2017/02/27 Javascript
浅谈React组件之性能优化
2018/03/02 Javascript
Vue项目实现换肤功能的一种方案分析
2019/08/28 Javascript
js实现移动端图片滑块验证功能
2020/09/29 Javascript
python对html代码进行escape编码的方法
2015/05/04 Python
python机器学习实战之最近邻kNN分类器
2017/12/20 Python
python方法生成txt标签文件的实例代码
2018/05/10 Python
python利用微信公众号实现报警功能
2018/06/10 Python
django之跨表查询及添加记录的示例代码
2018/10/16 Python
Python基于Dlib的人脸识别系统的实现
2020/02/26 Python
Django如何使用jwt获取用户信息
2020/04/21 Python
python numpy库np.percentile用法说明
2020/06/08 Python
巴西家用小家电购物网站:Polishop
2016/08/07 全球购物
梅西百货澳大利亚:Macy’s Australia
2017/07/26 全球购物
澳大利亚最好的在线时尚精品店:Princess Polly
2018/01/03 全球购物
台湾菁英交友:结识黄金单身的台湾人
2018/01/22 全球购物
《口技》教学反思
2014/02/21 职场文书
设计大赛策划方案
2014/06/13 职场文书
交通安全教育心得体会
2016/01/15 职场文书
nginx 多个location转发任意请求或访问静态资源文件的实现
2021/03/31 Servers
sql中mod()函数取余数的用法
2021/05/29 SQL Server