1. 程式人生 > >使用JavaScript解決網頁圖片拉伸問題

使用JavaScript解決網頁圖片拉伸問題

個人部落格站已經上線了,網址 www.llwjy.com ~歡迎各位吐槽~

-------------------------------------------------------------------------------------------------

      在開始之前先打一個小小的廣告,自己建立一個QQ群:321903218,點選連結加入群【Lucene案例開發】,主要用於交流如何使用Lucene來建立站內搜尋後臺,同時還會不定期的在群內開相關的公開課,感興趣的童鞋可以加入交流。

問題描述

      這段時間在做PM的需求的時候突然發現一個問題,產品上的圖片來自多個第三方,具體的尺寸無法確定,如果直接在樣式中寫死圖片的尺寸大小就會出現圖片拉伸的現象,十分影響產品的美觀,因此希望可以找到一個比較好的解決方案。自己先做了一個簡單的demo來展示問題。

<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<script src="./js/jquery-1.11.1.min.js"></script>
	<style>
		.img1{width:200px;height:200px;border: 1px solid #000;overflow: hidden;margin: 10px;}
		.img2{width:200px;height:90px;border: 1px solid #000;overflow: hidden;margin: 10px;}	
	</style>
</head>	
<body>
	<div class="img1" style="width:">
		<img id="img1" src="./img/1.jpg" height="100%" width="100%">
	</div>
	<div class="img2" style="width:">
		<img id="img2" src="./img/1.jpg" height="100%" width="100%">
	</div>
</body>
</html>


      上述這種情況還是挺影響美觀的,是否可以考慮動態的設定圖片的尺寸呢?

解決思路

      是否可以在瀏覽器載入圖片資源後,獲取圖片的真實尺寸和圖片容器的大小,然後動態地設定圖片的width、height屬性。

獲取圖片的真實尺寸

      html5下已經提供了相應的方法來返回圖片的真實尺寸大小(img.naturalWidth、img.naturalHeight),針對IE6/7/8也可以通過以下方法來獲取真實尺寸的大小

var imgae = new Image();
		image.src = img.src;
		image.onload = function() {
	    	var w = image.width;
	    	var h = image.height;
}

      下面就編寫對應的JS方法獲取圖片的真實尺寸已經圖片容器的尺寸大小

setImgSize : function(img, callback) {
	if (img.naturalWidth) { //html5
		callback(img, img.naturalWidth, img.naturalHeight, img.width, img.height);
	} else { // IE 6 7 8
		var imgae = new Image();
		image.src = img.src;
		image.onload = function() {
                   callback(img, image.width, image.height, img.width, img.height);
                }
	}
}

重新設定圖片尺寸

      在獲取圖片真實尺寸已經容器尺寸之後,我們需要重新設定圖片的尺寸大小。這裡先簡單的介紹下處理目標:如果設定後的尺寸超過展示區域,則展示圖片的中間部分,如果展示區域大於圖片尺寸,則圖片居中顯示。用圖簡單說明下,黑色實線為圖片的顯示區域,綠色部分為圖片的大小。


      下面我們提供三種方法來處理圖片,分別實現上部兩種(寬度一致)、下部兩種(高度一致)、右側兩種(鋪滿顯示區域),下面就分別介紹這三種方法:

一、保證寬度一致

//原始寬度 原始高度 容器寬度 容器高度
//保證寬度一致
resetImgSizeW : function(img, nw, nh, w, h) {
	nwh = nw / nh;
	wh = w / h;
	if (nwh > wh) {
		img.width = w;
		var height = parseInt(1 / nwh * w);
		img.height = height;
		var top = parseInt((h - height) / 2);
		img.style.marginTop = top + "px";
	} else if (nwh < wh) {
		img.width = w;
		var height = parseInt(1 / nwh * w);
		img.height = height;
		var top = parseInt((height - h) / 2) * -1;
		img.style.marginTop = top + "px";
	} else {
		img.height = h;
		img.width = w;
	}
},

      在這裡我們需要判斷圖片原始尺寸的長寬比例以及容器的長寬比例之間的關係,如果高度富裕,那就相應將圖片往上移動一定的畫素,如果高度不足,就將圖片往下移動相應的畫素,至於其他的兩種情況也是同樣的邏輯,先看下處理後的效果:


二、保證高度一致

//原始寬度 原始高度 容器寬度 容器高度
//保證高度一致
resetImgSizeH : function(img, nw, nh, w, h) {
	nwh = nw / nh;
	wh = w / h;
	if (nwh > wh) {
		img.height = h;
		var width = parseInt(nwh * h);
		img.width = width;
		var left = parseInt((width - w) / 2) * -1;
		img.style.marginLeft = left + "px";
	} else if (nwh < wh) {
		img.height = h;
		var width = parseInt(nwh * h);
		img.width = width;
		var left = parseInt((w - width) / 2);
		img.style.marginLeft = left + "px";
	} else {
		img.height = h;
		img.width = w;
	}
}


三、鋪滿顯示區域

//原始寬度 原始高度 容器寬度 容器高度
//鋪滿全屏
resetImgSizeWH : function(img, nw, nh, w, h) {
	nwh = nw / nh;
	wh = w / h;
	if (nwh > wh) {
		img.height = h;
		var width = parseInt(nwh * h);
		img.width = width;
		var left = parseInt((width - w) / 2) * -1;
		img.style.marginLeft = left + "px";
	} else if (nwh < wh) {
		img.width = w;
		var height = parseInt(1 / nwh * w);
		img.height = height;
		var top = parseInt((height - h) / 2) * -1;
		img.style.marginTop = top + "px";
	} else {
		img.height = h;
		img.width = w;
	}
},


如何使用JS

      上面對實現的邏輯以及最終的效果做了簡單的介紹,下面就介紹下如何使用。

<!-- 引用js指令碼 -->
<script src="./js/imageLoad.js"></script>
<script>
	var imageLoad = new ImageLoad();
	//處理網站上所有的圖片,下面三種只能使用一種
	//imageLoad.initImg("w");//保證寬度一致
	//imageLoad.initImg("h");//保證高度一致
	//imageLoad.initImg("wh");//鋪滿顯示區域
	//處理單個圖片,對於多個自己可以寫迴圈語句來實現
	imageLoad.setImgSize(document.getElementById("img1"), imageLoad.resetImgSizeW);
	imageLoad.setImgSize(document.getElementById("img2"), imageLoad.resetImgSizeW);
	imageLoad.setImgSize(document.getElementById("img3"), imageLoad.resetImgSizeH);
	imageLoad.setImgSize(document.getElementById("img4"), imageLoad.resetImgSizeH);
	imageLoad.setImgSize(document.getElementById("img5"), imageLoad.resetImgSizeWH);
	imageLoad.setImgSize(document.getElementById("img6"), imageLoad.resetImgSizeWH);
</script>

ImageLoad原始碼
$(document).ready(function() { 
	new ImageLoad();
});

ImageLoad = function(){
	this.init();
};

ImageLoad.prototype = {
	init : function () {
//		this.initImg("w");
	},
	initImg : function(type) {
		var _this = this;
		var imgs = document.getElementsByTagName('img');
		for (var i=0; i<imgs.length; i++) {
			try {
				var img = imgs[i];
				if ("w" == type) {
					$(img).onload = _this.setImgSize(img, _this.resetImgSizeW);
				} else if ("h" == type) {
					$(img).onload = _this.setImgSize(img, _this.resetImgSizeH);
				} else if ("wh" == type) {
					$(img).onload = _this.setImgSize(img, _this.resetImgSizeWH);
				} 
			} catch(e) {
			}
		}
	},
	//原始寬度 原始高度 容器寬度 容器高度
	//保證高度一致
	resetImgSizeH : function(img, nw, nh, w, h) {
		nwh = nw / nh;
		wh = w / h;
		if (nwh > wh) {
			img.height = h;
			var width = parseInt(nwh * h);
			img.width = width;
			var left = parseInt((width - w) / 2) * -1;
			img.style.marginLeft = left + "px";
		} else if (nwh < wh) {
			img.height = h;
			var width = parseInt(nwh * h);
			img.width = width;
			var left = parseInt((w - width) / 2);
			img.style.marginLeft = left + "px";
		} else {
			img.height = h;
			img.width = w;
		}
	},
	//原始寬度 原始高度 容器寬度 容器高度
	//保證寬度一致
	resetImgSizeW : function(img, nw, nh, w, h) {
		nwh = nw / nh;
		wh = w / h;
		if (nwh > wh) {
			img.width = w;
			var height = parseInt(1 / nwh * w);
			img.height = height;
			var top = parseInt((h - height) / 2);
			img.style.marginTop = top + "px";
		} else if (nwh < wh) {
			img.width = w;
			var height = parseInt(1 / nwh * w);
			img.height = height;
			var top = parseInt((height - h) / 2) * -1;
			img.style.marginTop = top + "px";
		} else {
			img.height = h;
			img.width = w;
		}
	},
	//原始寬度 原始高度 容器寬度 容器高度
	//鋪滿全屏
	resetImgSizeWH : function(img, nw, nh, w, h) {
		nwh = nw / nh;
		wh = w / h;
		if (nwh > wh) {
			img.height = h;
			var width = parseInt(nwh * h);
			img.width = width;
			var left = parseInt((width - w) / 2) * -1;
			img.style.marginLeft = left + "px";
		} else if (nwh < wh) {
			img.width = w;
			var height = parseInt(1 / nwh * w);
			img.height = height;
			var top = parseInt((height - h) / 2) * -1;
			img.style.marginTop = top + "px";
		} else {
			img.height = h;
			img.width = w;
		}
	},
	//獲取圖片真實尺寸以及容器尺寸
	setImgSize : function(img, callback) {
		if (img.naturalWidth) { //html5
			callback(img, img.naturalWidth, img.naturalHeight, img.width, img.height);
		} else { // IE 6 7 8
			var imgae = new Image();
			image.src = img.src;
			image.onload = function() {
	            callback(img, image.width, image.height, img.width, img.height);
	        }
		}
	},
}

      上面程式碼還有很多可以優化的地方,歡迎大家在評論區留言交流

-------------------------------------------------------------------------------------------------
小福利
-------------------------------------------------------------------------------------------------
      個人在極客學院上《Lucene案例開發》課程已經上線了,歡迎大家吐槽~