一直想实现博客文章中图片并列排版,因为有些图片比较长如果单占一行就会很不好看,但奈何没有啥实现思路。前几天看到大佬熊猫小A的Typecho博客主题VOID中实现了这个功能。于是厚着脸皮看了大佬的HTML结构,花了一个下午的时间用JQuery模仿了出来(捂脸)。先展示一下最终效果:

[photos]
![](https://cdn.jsdelivr.net/gh/zhengyujie/img/img/71663996.jpg)
![](https://cdn.jsdelivr.net/gh/zhengyujie/img/img/72611749.jpg)
![](https://cdn.jsdelivr.net/gh/zhengyujie/img/img/72279144.jpg)
[/photos]

实现思路

由于每张图片有不同的长宽比,所以将图片放在同一行,给每张图片安排的宽度也是不同的。这里使用了CSS中的flex布局,通过给每个图片块指定不同的flex-grow来分配不同的宽度。主要的HTML结构如下:

<div class="photos">
<figure class="photo"><img src="..." alt></figure>
<figure class="photo"><img src="..." alt></figure>
<figure class="photo"><img src="..." alt></figure>
</div>

主要的CSS代码:

div.photos {
    display: flex;
    flex-wrap: wrap;
}
figure.photo {
    margin: 2.5px;
}
.photo img {
    max-width: 100%;
    display: block;
}

接下来的重点就是怎么计算每个图片块的flex-grow。由于每个图片块需要有相同的高度,所以每个图片块分配到的宽度之间的比例应该和每张图片的宽长比之间的比例相同。所以我们直接将每张图片的宽长比作为该图片块的flex-grow,这样就实现了所有图片块高度相同。

jQuery实现

首先我们需要获取每张图片的长和宽:

jQuery('img').each(function(i, item){
    var img = new Image();
    img.onload = function () {
        var w = img.width;
        var h = img.height;
    };
    img.src = jQuery(item).attr('src');
})

然后我们需要为每张图片外嵌套一层<figure></figure>

jQuery(item).wrap("<figure></figure>");

接着计算每张图片的宽长比并给每个图片块分配flex-grow

jQuery(item).parent().css('flex', (w * 50 / h) + ' 1 0%');

同时我还实现了灯箱的功能,其实就是在图片外加一层<a></a>,链接为图片的地址:

jQuery(item).wrap("<a></a>");
jQuery(item).parent().attr("href",img.src);
jQuery(item).parent().attr("data-fancybox","gallery");

这样就实现了点击放大的功能。最后附上最终的jQuery代码:

jQuery('img').each(function(i, item){
    var img = new Image();
    img.onload = function () {
        var w = img.width;
        var h = img.height;
        console.log(w,h);
        jQuery(item).wrap("<figure></figure>");
        jQuery(item).parent().css('flex', (w * 50 / h) + ' 1 0%');
        jQuery(item).wrap("<a></a>");
        jQuery(item).parent().attr("href",img.src);
        jQuery(item).parent().attr("data-fancybox","gallery");
    };
    img.src = jQuery(item).attr('src');
})

当然还有最后一步,我们需要将markdown中的[photos][/photos]替换成<div class="photos"></div>。在function.php文件中添加以下代码:

function replace_text($text){
    $replace = array(
        '<p>[photos]<br />' => '<div class="photos flex">',
        '[/photos]</p>' => '</div>'
    );
    $text = str_replace(array_keys($replace), $replace, $text);
    return $text;
}
add_filter('the_content', 'replace_text');