【CSON原创】 图片滑动展开效果发布
功能說(shuō)明:
鼠標(biāo)移動(dòng)到不同圖片上,該圖片滑動(dòng)展開,其它圖片折疊。
支持IE 6 7 8 firefox chrome
效果預(yù)覽:
?
實(shí)現(xiàn)原理:
當(dāng)鼠標(biāo)移動(dòng)到某張圖片,該圖片以及該圖片前的圖片以相同速度向左運(yùn)動(dòng),該圖片之后的圖片也以相同速度向右運(yùn)動(dòng),形成展開選中圖片的效果。
代碼分析:
var flow_slide_imgs = function(options) {this._init();
} 使用構(gòu)造函數(shù)模式,構(gòu)造函數(shù)內(nèi)部調(diào)用私有方法_init(); flow_slide_imgs.prototype = {
_init: function(options) {
var defaults = {
containerId: 'container',
ImgsWidth: 0.6
};
var opts = util.extend(defaults, options);
this.container = util.$(opts.containerId);
this.imgs = this.container.getElementsByTagName('img');
this.imgWidth = parseInt(util.getComputedStyle(this.container).width) * opts.ImgsWidth;
this.containerWidth = parseInt(util.getComputedStyle(this.container).width);
this.containerHeight = parseInt(util.getComputedStyle(this.container).height);
this.aveWidth = this.containerWidth / this.imgs.length;
this.newAveWidth = (this.containerWidth - parseInt(this.imgWidth)) / (this.imgs.length - 1);
this.selectedIndex;
this.movePath = 80;
this.canLeft = true;
this.canRight = true;
this._setContainerStyle();
this._setImgsStyle();
this._bindClickEvent();
},
_init方法中,復(fù)制傳入的參數(shù)對(duì)象,并使用extend方法把傳入?yún)?shù)與默認(rèn)參數(shù)結(jié)合,再以對(duì)象屬性形式保存。最后調(diào)用其他私有函數(shù)進(jìn)行初始化。
_setContainerStyle: function() {this.container.style.cssText = 'overflow:hidden; position:relative;';
},
設(shè)置容器的樣式,由于容器內(nèi)圖片使用絕對(duì)定位并改變位置來(lái)實(shí)現(xiàn)圖片的展開和折疊,所以容器設(shè)置為相對(duì)定位,并且隱藏超出容器的圖片。
_setImgsStyle: function() {for (var i = 0; i < this.imgs.length; i++) {
this.imgs[i].style.cssText = 'position:absolute;'
+ 'left:' + i * this.aveWidth + 'px;'
+ 'top:0px;'
+ 'width:' + this.imgWidth + ';'
+ 'height:' + this.containerHeight + 'px;'
+ 'z-index:' + i + ';'
+ 'display:block';
}
},
獲取容器內(nèi)圖片,并批量設(shè)置圖片樣式,aveWidth為圖片初始的平均寬度,該數(shù)值在_init方法中通過(guò)容器寬度除以圖片數(shù)量得出。以每張圖片的索引為值設(shè)置圖片的層疊級(jí)別,這樣可以保證由最左邊開始,一張圖片疊在其右邊的圖片的上面。由于圖片為行內(nèi)元素,所以再設(shè)置其display為block。
_getSelectedIndex: function(target) {for (var i = 0, len = this.imgs.length; i < len; i++) {
if (target == this.imgs[i]) {
if (this.selectedIndex && this.selectedIndex < i) {
this.canLeft = true;
this.canRight = false;
}
if (this.selectedIndex && this.selectedIndex > i) {
this.canLeft = false;
this.canRight = true;
}
break;
}
}
return i;
},
獲取所選擇圖片,并且把該圖片的索引和之前已打開的圖片的索引進(jìn)行比較,如果所選圖片在已打開的圖片左邊,則圖片組只何以向左移動(dòng),否則圖片只可以向右移動(dòng),這樣是為了解決鼠標(biāo)移動(dòng)過(guò)快造成的左邊圖片和右邊圖片作相反方向移動(dòng)的問題。總之,這里保證的所有圖片向同一個(gè)方向移動(dòng)。
_resetImgsSizeAndPos: function(obj, selectedIndex) {if (typeof obj.selectedIndex == 'undefined') {
if (parseInt(util.getComputedStyle(obj.imgs[1]).left) > obj.newAveWidth) {
for (var i = 1; i < obj.imgs.length; i++) {
if (i <= selectedIndex)
obj.imgs[i].style.left = Math.max(parseInt(obj.imgs[i].style.left) - obj.movePath * i, i * obj.newAveWidth) + 'px';
else
obj.imgs[i].style.left = Math.min(parseInt(obj.imgs[i].style.left) + obj.movePath * (obj.imgs.length - i), obj.containerWidth - (obj.imgs.length - i) * obj.newAveWidth) + 'px';
}
obj.timeId = window.setTimeout(arguments.callee, 100, obj, selectedIndex);
}
if (parseInt(util.getComputedStyle(obj.imgs[1]).left) == obj.newAveWidth || parseInt(util.getComputedStyle(obj.imgs[1]).left) == obj.imgWidth) {
obj.selectedIndex = selectedIndex;
}
}
else if (obj.selectedIndex > selectedIndex) {
if (parseInt(util.getComputedStyle(obj.imgs[selectedIndex + 1]).left) < (selectedIndex + 1) * obj.newAveWidth + (obj.imgWidth - obj.newAveWidth) && obj.canRight) {
for (var j = selectedIndex + 1; j <= obj.selectedIndex; j++) {
obj.imgs[j].style.left = Math.min(parseInt(obj.imgs[j].style.left) + obj.movePath, obj.newAveWidth * (j - 1) + obj.imgWidth) + 'px';
}
obj.timeId = window.setTimeout(arguments.callee, 100, obj, selectedIndex);
}
else {
obj.canLeft = true;
obj.selectedIndex = selectedIndex;
}
}
else if (obj.selectedIndex < selectedIndex) {
if (parseInt(util.getComputedStyle(obj.imgs[selectedIndex]).left) > (selectedIndex) * obj.newAveWidth && obj.canLeft) {
for (var j = selectedIndex; j > obj.selectedIndex; j--) {
obj.imgs[j].style.left = Math.max(parseInt(obj.imgs[j].style.left) - obj.movePath, j * obj.newAveWidth) + 'px';
}
obj.timeId = window.setTimeout(arguments.callee, 100, obj, selectedIndex);
}
else {
obj.canRight = true;
obj.selectedIndex = selectedIndex;
}
}
},
根據(jù) 所有圖片均未打開(第一次選擇圖片),已打開圖片在所選擇圖片的前面,已打開圖片在所選擇圖片的后面 這三種情況,圖片組作不同方向的運(yùn)動(dòng),通過(guò)setTimeout每隔100ms移動(dòng)一個(gè)單位位移。
_bindClickEvent: function() {util.addEventHandler(this.container, 'mouseover', (function(obj) {
return function(eve) {
eve = eve || window.event;
var target = eve.srcElement || eve.target,
selectedIndex = obj._getSelectedIndex(target);
obj._resetImgsSizeAndPos(obj, selectedIndex);
}
})(this));
}
為容器的mouseover事件綁定事件處理程序,利用事件冒泡在容器的處理程序里產(chǎn)生選中圖片時(shí)的效果。
這里由于需要為事件處理傳遞參數(shù),所以利用閉包,使傳入的obj對(duì)象可訪問。鼠標(biāo)移動(dòng)到圖片上方時(shí),調(diào)用上面分析過(guò)的resetImgsSizeAndPos方法,根據(jù)實(shí)際情況讓圖片作出不同的運(yùn)動(dòng)。
new flow_slide_imgs();最后是調(diào)用方法,這里沒有傳入?yún)?shù),則控件里面使用默認(rèn)值。
完整demo代碼:
html:?
View Code <div id="container">
<img src="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_cat1.jpg" />
<img src="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_cat2.jpg" />
<img src="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_cat3.jpg" />
<img src="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_cat4.jpg" />
<img src="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_cat5.jpg" />
</div>
css:
View Code #container{width:600px; height:300px; background-color:Black;}#container img{display:none;}
base.js:
View Code var util = {$: function(sId) { return document.getElementById(sId); },
addEventHandler: function(elem, type, handler) {
if (elem.addEventListener) {
elem.addEventListener(type, handler, false);
}
else {
elem.attachEvent("on" + type, handler);
}
},
removeEventHandler: function(elem, type, handler) {
if (elem.removeEventListener) {
elem.removeEventListener(type, handler, false);
}
else {
elem.detachEvent("on" + type, handler);
}
},
getComputedStyle: function(elem) {
if (elem.currentStyle)
return elem.currentStyle;
else {
return document.defaultView.getComputedStyle(elem, null);
}
},
getElementsByClassName: function(className, parentElement) {
var elems = (parentElement || document.body).getElementsByTagName("*");
var result = [];
for (i = 0; j = elems[i]; i++) {
if ((" " + j.className + " ").indexOf(" " + className + " ") != -1) {
result.push(j);
}
}
return result;
},
extend: function(destination, source) {
for (var name in source) {
destination[name] = source[name];
}
return destination;
}
};
(function() {
var st = window.setTimeout;
window.setTimeout = function(fn, mDelay) {
var t = new Date().getTime();
if (typeof fn == 'function') {
var args = Array.prototype.slice.call(arguments, 2);
var f = function() {
args.push(new Date().getTime() - t - mDelay);
fn.apply(null, args)
};
return st(f, mDelay);
}
return st(fn, mDelay);
}
})();
flow_slide_imgs.js:
View Code /*created by cson
supports ie 6 7 8 firefox and chrome
*/
/*constructor of 'flow images controller' */
var flow_slide_imgs = function(options) {
this._init();
}
flow_slide_imgs.prototype = {
/* init container and images and set object's properties */
_init: function(options) {
var defaults = {
containerId: 'container',
ImgsWidth: 0.6
};
var opts = util.extend(defaults, options);
this.container = util.$(opts.containerId);
this.imgs = this.container.getElementsByTagName('img');
this.imgWidth = parseInt(util.getComputedStyle(this.container).width) * opts.ImgsWidth;
this.containerWidth = parseInt(util.getComputedStyle(this.container).width);
this.containerHeight = parseInt(util.getComputedStyle(this.container).height);
this.aveWidth = this.containerWidth / this.imgs.length;
this.newAveWidth = (this.containerWidth - parseInt(this.imgWidth)) / (this.imgs.length - 1);
this.selectedIndex;
this.movePath = 80;
this.canLeft = true;
this.canRight = true;
this._setContainerStyle();
this._setImgsStyle();
this._bindClickEvent();
},
/* set container's style */
_setContainerStyle: function() {
this.container.style.cssText = 'overflow:hidden; position:relative;';
},
/* set styles of images in container */
_setImgsStyle: function() {
for (var i = 0; i < this.imgs.length; i++) {
this.imgs[i].style.cssText = 'position:absolute;'
+ 'left:' + i * this.aveWidth + 'px;'
+ 'top:0px;'
+ 'width:' + this.imgWidth + ';'
+ 'height:' + this.containerHeight + 'px;'
+ 'z-index:' + i + ';'
+ 'display:block';
}
},
/* get current selected image's index */
_getSelectedIndex: function(target) {
for (var i = 0, len = this.imgs.length; i < len; i++) {
if (target == this.imgs[i]) {
if (this.selectedIndex && this.selectedIndex < i) {
this.canLeft = true;
this.canRight = false;
}
if (this.selectedIndex && this.selectedIndex > i) {
this.canLeft = false;
this.canRight = true;
}
break;
}
}
return i;
},
/* reset images' size and position for three situation */
_resetImgsSizeAndPos: function(obj, selectedIndex) {
if (typeof obj.selectedIndex == 'undefined') {
if (parseInt(util.getComputedStyle(obj.imgs[1]).left) > obj.newAveWidth) {
for (var i = 1; i < obj.imgs.length; i++) {
if (i <= selectedIndex)
obj.imgs[i].style.left = Math.max(parseInt(obj.imgs[i].style.left) - obj.movePath * i, i * obj.newAveWidth) + 'px';
else
obj.imgs[i].style.left = Math.min(parseInt(obj.imgs[i].style.left) + obj.movePath * (obj.imgs.length - i), obj.containerWidth - (obj.imgs.length - i) * obj.newAveWidth) + 'px';
}
obj.timeId = window.setTimeout(arguments.callee, 100, obj, selectedIndex);
}
if (parseInt(util.getComputedStyle(obj.imgs[1]).left) == obj.newAveWidth || parseInt(util.getComputedStyle(obj.imgs[1]).left) == obj.imgWidth) {
obj.selectedIndex = selectedIndex;
}
}
else if (obj.selectedIndex > selectedIndex) {
if (parseInt(util.getComputedStyle(obj.imgs[selectedIndex + 1]).left) < (selectedIndex + 1) * obj.newAveWidth + (obj.imgWidth - obj.newAveWidth) && obj.canRight) {
for (var j = selectedIndex + 1; j <= obj.selectedIndex; j++) {
obj.imgs[j].style.left = Math.min(parseInt(obj.imgs[j].style.left) + obj.movePath, obj.newAveWidth * (j - 1) + obj.imgWidth) + 'px';
}
obj.timeId = window.setTimeout(arguments.callee, 100, obj, selectedIndex);
}
else {
obj.canLeft = true;
obj.selectedIndex = selectedIndex;
}
}
else if (obj.selectedIndex < selectedIndex) {
if (parseInt(util.getComputedStyle(obj.imgs[selectedIndex]).left) > (selectedIndex) * obj.newAveWidth && obj.canLeft) {
for (var j = selectedIndex; j > obj.selectedIndex; j--) {
obj.imgs[j].style.left = Math.max(parseInt(obj.imgs[j].style.left) - obj.movePath, j * obj.newAveWidth) + 'px';
}
obj.timeId = window.setTimeout(arguments.callee, 100, obj, selectedIndex);
}
else {
obj.canRight = true;
obj.selectedIndex = selectedIndex;
}
}
},
/*bind handler for mouseover event of images */
_bindClickEvent: function() {
util.addEventHandler(this.container, 'mouseover', (function(obj) {
return function(eve) {
eve = eve || window.event;
var target = eve.srcElement || eve.target,
selectedIndex = obj._getSelectedIndex(target);
obj._resetImgsSizeAndPos(obj, selectedIndex);
}
})(this));
}
}
歡迎轉(zhuǎn)載,請(qǐng)標(biāo)明出處:http://www.cnblogs.com/Cson/archive/2011/04/03/2004717.html
轉(zhuǎn)載于:https://www.cnblogs.com/Cson/archive/2011/04/03/2004717.html
總結(jié)
以上是生活随笔為你收集整理的【CSON原创】 图片滑动展开效果发布的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 自定义ListView背景(解决了拖动变
- 下一篇: 两不同网段主机直连通信过程的建立(3个实