首页 新闻 会员 周边 捐助

新手求助!利用jquery实现等照片的高响应式布局 mvc的怪问题

0
悬赏园豆:10 [待解决问题]

利用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次的图片会是被拉变形的,刷新后才正常

时光刺客的主页 时光刺客 | 初学一级 | 园豆:60
提问于:2014-05-21 13:14
< >
分享
所有回答(1)
0

把开头的这句$(function () { doPhotoLayout(); });放到最后,修改为doPhotoLayout();试试呢~

幻天芒 | 园豆:37205 (高人七级) | 2014-05-21 13:33

刚试了!依然是刷新后才正常!不知道是哪里出了问题,要刷新一次!

支持(0) 反对(0) 时光刺客 | 园豆:60 (初学一级) | 2014-05-21 14:31

@时光刺客: 在doPhotoLayout(),断点,看看执行了没~

支持(0) 反对(0) 幻天芒 | 园豆:37205 (高人七级) | 2014-05-21 15:40

@幻天芒: 是有执行了,只是首次执行和手动刷新再次的不一样!研究了很久了都不知道哪里问题了!那段javascript明明在html文件上测试完全正常的,只是mvc上的图片是循环放进去的

支持(0) 反对(0) 时光刺客 | 园豆:60 (初学一级) | 2014-05-21 17:00

@时光刺客: 那你可以跟踪下代码哦。这个直接不太看得出来~

支持(0) 反对(0) 幻天芒 | 园豆:37205 (高人七级) | 2014-05-21 20:39

@幻天芒: 昨天研究了半天,发现已文件方式保存在本地文件夹的图片完全正常,从内存流中加载的图片则是需要加载完成图片才是正常的,我猜是因为图片未加载完成的时候,Javascript无法获取图片正确的宽高。请问要怎么处理呢!

支持(0) 反对(0) 时光刺客 | 园豆:60 (初学一级) | 2014-05-22 09:27

@时光刺客: 图片的宽和高能不能写在img标签上呢?比如<img src="" alt="" style="width:100px;height:100px;" />

支持(0) 反对(0) 幻天芒 | 园豆:37205 (高人七级) | 2014-05-22 13:41

@幻天芒: 测试证实不行!最主要还是javascript无法获取到在内存中的图片宽高(正确值),这应该是关键所在。而用window.onload再执行,看上去效果正常,但是出现部分图片显示不完整!

支持(0) 反对(0) 时光刺客 | 园豆:60 (初学一级) | 2014-05-24 16:45

@时光刺客: 那就将代码延后执行,放在setTimeout之中。

支持(0) 反对(0) 幻天芒 | 园豆:37205 (高人七级) | 2014-05-25 23:09

@时光刺客:  如果你不确定加载的图片大小,只能做个延时处理了

支持(0) 反对(0) 小小三师弟 | 园豆:205 (菜鸟二级) | 2014-06-10 17:38
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册