利用jquery实现等照片的高响应式布局,我在HTML文档中调好了script和css,确保一切正常了。但应用到Asp.net mvc 5中却出现了很怪的问题:
1.运行(F5)后第1次执行该页面,什么都图片没有显示,原因多了display:none。那是图片宽高被拉到变形了,script中有对变形了的做隐藏!
2.只要刷新一次页面之后就一切正常,无论你怎么操作!图片不变形,根据浏览器大小自动缩放!完全的正常。
简单来说就是F5后第一次是失败的
script
$(function () { $(function () { doPhotoLayout(); }); $(window).resize(function () { doPhotoLayout(); }); function getContainerWidth() { return $(window).width() || ""; } //判断浏览器宽度范围,相当于media-query function getStandardHeight() { var sHeight = 0; var bWidth = getContainerWidth(); if (bWidth <= 800) { sHeight = 250; } else if (bWidth <= 960) { sHeight = 300; } else if (bWidth <= 960) { sHeight = 350; } else if (bWidth <= 1366) { sHeight = 400; } else if (bWidth <= 1440) { sHeight = 450; } else if (bWidth <= 1536) { sHeight = 500; } else if (bWidth <= 1920) { sHeight = 550; } else if (bWidth <= 2048) { sHeight = 600; } else if (bWidth <= 3840) { sHeight = 650; } else { sHeight = 700; } return sHeight; } //获取容器对象 function getContainer() { var $container = $(".imagelist"); return $container; } var $imgItems; var index = 1; //获取所有imgItem对象 function getItems() { if (typeof ($imgItems) == "undefined") { var $container = getContainer(); $imgItems = $container.find(".imgItem"); } return $imgItems; } //保存图片初始宽高 var widths; var heights; function getWidths() { if (typeof (widths) == "undefined") { var $items = getItems(); widths = new Array(); $.each($items, function (key, val) { var $imgs = $(this).find("img"); widths[key] = $imgs.width(); }); } var tmpWidths = widths.slice();//不污染原数组 return tmpWidths; } function getHeights() { if (typeof (heights) == "undefined") { var $items = getItems(); heights = new Array(); $.each($items, function (key, val) { var $imgs = $(this).find("img"); heights[key] = $imgs.height(); }); } var tmpHeights = heights.slice();//不污染原数组 return tmpHeights; } //调整主函数 function doPhotoLayout() { var sHeight = getStandardHeight(); var bWidth = getContainerWidth(); var $container = getContainer(); var $items = getItems(); var widthAry = getWidths() var heightAry = getHeights(); var itemsLength = $items.length || 0; var border = 1;//边框值 if (itemsLength == 0) { var $para = $("<p>无照片</p>"); $para.css({ "font-size": "18px", "text-align": "center" }); $container.append($para); } else { //记录每个图片转化后的高度 for (var i = 0; i < itemsLength ; i++) { if (heightAry[i] != sHeight) { widthAry[i] = Math.round(widthAry[i] * (sHeight / heightAry[i])); heightAry[i] = sHeight; } } //创建每行父容器,并寻找各自子节点 $(".row").remove();//清楚旧容器 var rowWidth = 2 * border;//记录每行宽度,初始为容器左右padding宽 var i = 0, j = 0; var rowDivs = new Array(); var rowSonsLen = new Array(); while (i < itemsLength) { var rowDiv = $("<div></div>"); rowDiv.attr("class", "row"); rowDiv.width(bWidth - border * 2); rowSonsLen[j] = 0; for (i ; i < itemsLength ; i++) { rowWidth += widthAry[i] + 2 * border; rowDiv.append($items[i]); rowSonsLen[j] += 1; //装不下下一个图片则保存该行,然后继续下一行 if (i + 1 < itemsLength && (rowWidth + widthAry[i + 1] + 2 * border) > bWidth) { rowDivs[j++] = rowDiv; rowWidth = 2 * border; i++; break; } else if (i + 1 == itemsLength) { rowDivs[j] = rowDiv; } } } var rowDivsLen = rowDivs.length; //只有1行不做调整 if (rowDivsLen > 1) { //计算调整后差距 var rowTotalWidth = 0; var restAry = new Array(); var j = 0;//记录宽度数组下标 var maxLen = 0; var containerWidth = 0; for (var i = 0 ; i < rowDivsLen ; i++) { var k = j; containerWidth = bWidth - 2 * border; rowTotalWidth = 0; maxLen += rowSonsLen[i]; for (j ; j < maxLen ; j++) { rowTotalWidth += widthAry[j]; containerWidth -= 2 * border; } //比例=目标宽度/实际宽度=目标高度/实际高度 //var rate = parseFloat(containerWidth/rowTotalWidth); var afterHeight = Math.round(parseFloat(sHeight * containerWidth / rowTotalWidth)); heightAry[i] = afterHeight; restAry[i] = 2 * border; //算出高度列表后再更新宽度列表 for (k ; k < maxLen ; k++) { widthAry[k] = Math.round(parseFloat(widthAry[k] * afterHeight / sHeight)); restAry[i] += widthAry[k] + 2 * border;//调整后宽度 } } //调整最后间距 var gap = 0;//间距值 var acIndex = 0; for (var i = 0; i < rowDivsLen; i++) { gap = bWidth - restAry[i]; //小于容器宽度 if (gap > 0) { while (gap != 0) { var j = 0; widthAry[acIndex + j] = widthAry[acIndex + j] + 1; gap--; j = (j + 1 + rowSonsLen[i]) % rowSonsLen[i]; } } //大于容器宽度 else if (gap < 0) { while (gap != 0) { var j = 0; widthAry[acIndex + j] = widthAry[acIndex + j] - 1; gap++; j = (j + 1 + rowSonsLen[i]) % rowSonsLen[i]; } } acIndex += rowSonsLen[i]; }; } //把宽度和高度列表赋予图片 var i = 0, j = 0; $.each($items, function (key, val) { $(this).css({ "width": widthAry[key], "height": heightAry[i], "margin": border }); var $img = $(this).find("img"); $img.css({ "width": widthAry[key], "height": heightAry[i] }); if (j < rowSonsLen[i] - 1) { j++; } else { i++; j = 0; } }); $container.css("padding", "0 " + border + "px"); $container.append(rowDivs); //有如下情况则舍弃一行 //1)原始宽高比与转换后宽高比大于rate; //2)转换后宽度大于原始宽度1.5倍 //3)转换后高度大于原始高度1.5倍 var $lastImgs = $container.find("img"); var rate = 1; var heightRaw = 0, heightNow = 0, widthRaw = 0, widthNow = 0; $.each($lastImgs, function (key, val) { heightRaw = parseFloat(heights[key] / widths[key]); heightNow = parseFloat($(this).height() / $(this).width()); widthRaw = parseFloat(widths[key] / heights[key]); widthNow = parseFloat($(this).width() / $(this).height()); if (Math.abs(heightRaw - heightNow) > rate || Math.abs(widthRaw - widthNow) > rate || heights[key] * 1.5 < $(this).height() || widths[key] * 1.5 < $(this).width()) { $(this).parents(".row").css("display", "none"); } }); } } })
View
<div class="imagelist"> @foreach (var item in Model.Photo) { <div class="imgItem"> <a href="#"><img src="@Url.Action("PhotoOriginalSize", "Photo", new { id = item.PhotoID })" /></a> <div class="title"> <div class="text">Demo</div> </div> </div> } </div>
CSS
.imagelist { margin: 0 auto; } .imgItem { overflow: hidden; vertical-align: top; display: inline-block; border: 0; position: relative; } .imgItem a { text-decoration:none; display: inline-block; } .imgItem a img { display: inline-block; border:0; } .title { width:100%; height: 60px; background: rgba(0,0,0,0.75); position: absolute; bottom: 0; display: none; border: 0; } .title .hide { display:none; } .text { height: 60px; line-height: 60px; margin: 0; overflow: hidden; color: #FFF; font-size: 1.5em; font-weight: bold; text-align: center; border: 0; }
浏览器为IE11
照片来自保存在数据库中
请教各位高手,请问这是哪里出错了。造成这样的现象。javascript是别人写的,对于script我新手不是太懂,基本能看懂。
为什么第1次的图片会是被拉变形的,刷新后才正常
把开头的这句$(function () { doPhotoLayout(); });放到最后,修改为doPhotoLayout();试试呢~
刚试了!依然是刷新后才正常!不知道是哪里出了问题,要刷新一次!
@时光刺客: 在doPhotoLayout(),断点,看看执行了没~
@幻天芒: 是有执行了,只是首次执行和手动刷新再次的不一样!研究了很久了都不知道哪里问题了!那段javascript明明在html文件上测试完全正常的,只是mvc上的图片是循环放进去的
@时光刺客: 那你可以跟踪下代码哦。这个直接不太看得出来~
@幻天芒: 昨天研究了半天,发现已文件方式保存在本地文件夹的图片完全正常,从内存流中加载的图片则是需要加载完成图片才是正常的,我猜是因为图片未加载完成的时候,Javascript无法获取图片正确的宽高。请问要怎么处理呢!
@时光刺客: 图片的宽和高能不能写在img标签上呢?比如<img src="" alt="" style="width:100px;height:100px;" />
@幻天芒: 测试证实不行!最主要还是javascript无法获取到在内存中的图片宽高(正确值),这应该是关键所在。而用window.onload再执行,看上去效果正常,但是出现部分图片显示不完整!
@时光刺客: 那就将代码延后执行,放在setTimeout之中。
@时光刺客: 如果你不确定加载的图片大小,只能做个延时处理了