Web前端之九宫格图片、单行或多行样式选择器、动态设置样式变量值、向空数组填充数值、动态设置背景图、随机获取数组项、切图、setProperty、floor、Math


公共部分

Html

<div class="box">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
</div>

Style

:root {
    --num: 300px;
}

body {
    width: 100vw;
    height: 100vh;
    margin: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: #171717;
}

.box {
    width: var(--num);
    height: var(--num);
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    cursor: pointer;
}

解析

Hhtml
html定义一个带有类名为box的div容器,里面包含9个类名为item的子div元素。这些item元素将被用来创建一个3x3的网格布局。


Style
1、:root定义CSS变量–num,其值为300px。变量在.box的宽度和高度中被使用。
2、body设置页面的宽度和高度为视口的100%,移除默认的外边距,并使用Flexbox布局居中显示.box,同时设置背景颜色为深灰色。
3、.box设置宽度和高度为–num变量的值,使用网格布局(display: grid;),并定义三列(grid-template-columns: repeat(3, 1fr);),并且设置鼠标指针为指针形状,暗示可以交互。


代码段创建一个带有9个子项的网格布局,每个子项默认情况下没有特别的样式。当鼠标悬停在.box上时,由于.box的cursor属性被设置为pointer,鼠标指针会变成指针形状,暗示用户可以与.box进行交互。然而,没有提供.box:hover .item的样式规则,所以悬停.box时,.item的样式不会发生变化。
要使.item在悬停时有反应,需要添加额外的CSS规则来定义.box:hover .item的行为。


纯样式版

预览

默认
默认


激活
激活


Style

.item {
    box-shadow: inset 0 0 0 1px #ffffff;
    transition: 0.5s;
    background-image: url('../../image/5_.jpg');
    background-size: var(--num) var(--num);
    position: relative;
}

.item:nth-child(3n+1) {
    left: -20px;
    background-position-x: 0;
}

.item:nth-child(3n+2) {
    left: 0px;
    background-position-x: -100px;
}

.item:nth-child(3n) {
    left: 20px;
    background-position-x: -200px;
}

.item {
    top: 20px;
    background-position-y: -200px;
}

.item:nth-child(-n+6) {
    top: 0;
    background-position-y: -100px;
}

.item:nth-child(-n+3) {
    top: -20px;
    background-position-y: 0px;
}

.box:hover .item {
    left: 0;
    top: 0;
    box-shadow: inset 0 0 0 0 #ffffff;
}

解析

概述
1、代码段定义.item类的样式规则,以及基于:nth-child伪类选择器的特定子项的样式规则。此外,还包含一个悬停效果,当鼠标悬停在.box上时,所有.item元素的样式会发生变化。
2、代码段定义一个网格布局,其中.item元素具有背景图片和内阴影效果,并在鼠标悬停时,所有.item元素会移动到网格的起始位置,并且移除内阴影效果。通过使用CSS变量、网格布局和伪类选择器,实现复杂的布局和交互效果。


item类样式
1、box-shadow: inset 0 0 0 1px #ffffff;为.item元素添加了一个白色的内阴影,边框宽度为1px。
2、transition: 0.5s;定义背景位置和阴影变化的过渡效果,持续时间为0.5秒。
3、background-image: url('../../image/5_.jpg');设置.item的背景图片为…/…/image/5_.jpg。
4、background-size: var(--num) var(--num);设置背景图片的大小,使用之前定义的CSS变量–num,其值为300px,因此背景图片会被缩放至300px*300px。
5、position: relative;将.item元素的定位设置为相对定位,允许使用left和top属性进行偏移。


特定子项x
css规则使用:nth-child选择器来选择特定的.item元素,并为它们设置不同的left偏移和背景图片的水平位置(background-position-x)。


特定子项y
css规则为.item元素设置top偏移和背景图片的垂直位置(background-position-y)。其中,:nth-child(-n+6)和:nth-child(-n+3)选择器分别选择前六个和前三个.item元素,并为它们设置不同的top偏移和背景图片的垂直位置。


悬停效果
当鼠标悬停在.box上时,所有.item元素的left和top偏移会被重置为0,内阴影会消失(变为0宽度的内阴影),使得所有.item元素在悬停时移动到网格的起始位置,并且移除内阴影效果。


JavaScript版

预览

默认
默认


激活
激活


Style

.item {
    box-shadow: inset 0 0 0 1px #ffffff;
    transition: 0.5s;
    background-image: url('../../image/1_.jpg');
    background-size: var(--num) var(--num);
    background-position: var(--bgX, 0) var(--bgY, 0);
    transform: translate(var(--disX, 0), var(--disY, 0));
}

.box:hover .item {
    transform: translate(0, 0);
    box-shadow: inset 0 0 0 0 #ffffff;
}

JavaScript

function init() {
    const items = document.querySelectorAll('.item');

    for (let i = 0; i < items.length; i++) {
        const item = items[i];
        const r = Math.floor(i / 3);
        const c = i % 3;
        const bgX = -c * 100 + '%';
        const bgY = -r * 100 + '%';
        const disX = (c - 1) * 20 + 'px';
        const disY = (r - 1) * 20 + 'px';

        item.style.setProperty('--bgX', bgX);
        item.style.setProperty('--bgY', bgY);
        item.style.setProperty('--disX', disX);
        item.style.setProperty('--disY', disY);
    }
}

init();

解析

Style
1、.item设置内阴影、过渡效果、背景图片、背景大小和位置,以及变换效果。背景位置和变换使用了CSS自定义属性(变量)–bgX、–bgY、–disX和–disY。
2、.box:hover .item规则定义鼠标悬停在.box上时,所有.item元素的变换效果会被重置,内阴影也会消失。


JavaScript
1、init函数通过查询所有.item元素,然后为每个元素设置CSS自定义属性–bgX、–bgY、–disX和–disY的值。这些值基于元素在网格中的位置(行r和列c)计算得出。
2、–bgX和–bgY控制背景图片的位置,而–disX和–disY控制元素在网格中的偏移量。


总结
代码段创建一个带有9个子项的网格布局,每个子项都有一个背景图片,并且在鼠标悬停时,所有子项会移动到网格的起始位置,并且移除内阴影效果。使用CSS变量、网格布局和JavaScript,实现复杂的布局和交互效果。


拓展版(完整的JavaScript版代码)

Html

<div class="box"></div>

Style

:root {
    --num: 300px;
}

body {
    width: 100vw;
    height: 100vh;
    margin: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: #171717;
}

.box {
    width: var(--num);
    height: var(--num);
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    cursor: pointer;
}

.item {
    box-shadow: inset 0 0 0 1px #ffffff;
    transition: 0.5s;
    background-image: var(--url);
    background-size: var(--num) var(--num);
    background-position: var(--bgX, 0) var(--bgY, 0);
    transform: translate(var(--disX, 0), var(--disY, 0));
}

.box:hover .item {
    transform: translate(0, 0);
    box-shadow: inset 0 0 0 0 #ffffff;
}

JavaScript

let oldImg = '';
const list = Array.from({ length: 5 }, (v, i) => i + 1);
const runRandom = () => list[Math.floor(Math.random() * list.length)];
const runItems = () => document.querySelectorAll('.item');

function handleTaBar() {
    const items = runItems();
    const img = runRandom();
    let url = ``;

    if (img === oldImg) {
        handleTaBar();
    } else {
        let i = 0;

        oldImg = img;
        url = `url(../../image/${img}_.jpg)`;
        for (; i < items.length; i++) items[i].style.setProperty('--url', url);
    }
}

function runInit() {
    const box = document.querySelector('.box');
    const elStr = '<div class="item" οnclick="handleTaBar()"></div>';
    let el = '';

    for (let i = 0; i < 9; i++) el += elStr;
    box.innerHTML = el;
    setTimeout(() => {
        const items = runItems();

        handleTaBar();
        for (let i = 0; i < items.length; i++) {
            const item = items[i];
            const r = Math.floor(i / 3);
            const c = i % 3;
            const bgX = -c * 100 + '%';
            const bgY = -r * 100 + '%';
            const disX = (c - 1) * 20 + 'px';
            const disY = (r - 1) * 20 + 'px';

            item.style.setProperty('--bgX', bgX);
            item.style.setProperty('--bgY', bgY);
            item.style.setProperty('--disX', disX);
            item.style.setProperty('--disY', disY);
        }
    });
}

runInit();

解析

1、承载背景图片的div通过JavaScript生成,并绑定触发函数(handleTaBar)。
2、使用JavaScript版样式规则。
3、点击handleTaBar方法随意切换图片,获取的图片与上一张不重复。


补充知识

前言
向空的list数组中生成1到5个值。


for

const list = [];

for (let i = 1; i <= 5; i++) list.push(i);
console.log(list);
// (5) [1, 2, 3, 4, 5]

代码段创建一个空数组list,然后使用for循环从1迭代到5,每次迭代都将当前的数字i添加到list数组中。循环结束后,list数组将包含从1到5的整数。


Array.from

const list = Array.from({ length: 5 }, (v, i) => i + 1);

console.log(list);
// (5) [1, 2, 3, 4, 5]

展开运算符(keys+map)

const list = [...Array(5).keys()].map(e => e + 1);

console.log(list);
// (5) [1, 2, 3, 4, 5]
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值