猿问

在循环中多次覆盖元素的样式?

我有一个简单的菜单,它当前正在使用我想要动画的 CSS 网格。但是,grid-template-columns不能流畅地动画。我现在正在做完全不同的菜单,但是在我寻找解决方案的过程中,我遇到了一些我无法弄清楚的事情。我的第一个想法是,虽然它可能根本不是一个好主意,并且可能不是关键帧动画的合适替代方案,但我的第一个想法是在 while 循环中更新样式以使项目的大小增加动画。它不起作用。


相关的JS:


    $('#select-oak').hover(function () {

            let start = new Date().getTime();

            let elapsed = 0;


            while (elapsed <= 1000) {

                elapsed = new Date().getTime() - start;

                let val = elapsed / 1000;


                if (elapsed % 100 === 0) {

                    $('.selector-block').css('grid-template-columns', `${1.0 + val}fr 1fr 1fr 1fr`);

                    console.log(1 + val);

                    console.log(elapsed);

                }

            }

        }

CSS:


.selector-block {

    position: relative;

    overflow: hidden;

    top: -32.5vh;

    background-color: white;

    gap: 5px;

    width: 100vw;

    height: 90vh;

    display: grid;

    grid-template-columns: 1fr 1fr 1fr 1fr;

    clip-path: polygon(0 36%, 100% 0, 100% 60%, 0% 100%);

    z-index: 3;

}


#select-oak {

    position: relative;

    overflow: hidden;

    text-align: center;

    background-color: rgb(94, 80, 21);

    top: 21.5%;

    width: 100%;

    height: 200%;

}


#select-oak img {

    position: relative;

    left: -10vw;

    transform: scale(1.06);

    filter: blur(5px);

}


#select-oak img:hover {

    filter: none;

    transform: scale(1.1);

    transition: ease-in-out 0.5s;

}

这似乎是一种非常规的方法,所以我对它不起作用并不感到惊讶,但由于我对 CSS、JS 和 JQuery 相对较新,我很好奇是什么阻止了它的工作,只是为了帮助我理解使用 JQuery 和 CSS。这是结果。如您所见,即使打印出正确的值,它也不会更新,直到循环中的最后一次传递。

所以我有两个问题:

  1. 这是我的代码有问题,还是您不能做的事情?

  2. 如果可以更新这样的样式,这是一种不好的做法,为什么?


BIG阳
浏览 134回答 2
2回答

子衿沉夜

该while循环阻塞渲染过程,因为它是同步的。我想出了一种使用 CSS 转换的方法,不知道子元素的数量。 它还处理鼠标离开甚至从一个菜单项移动到另一个菜单项。$('.selector-block > *').hover(function() {&nbsp; let frValues = Array($(this).siblings().length+1).fill('1fr');&nbsp; frValues[$(this).prevAll().length] = '2fr';&nbsp; $('.selector-block').css({&nbsp; &nbsp; 'grid-template-columns': frValues.join(' ')&nbsp; });}, function() {&nbsp; let frValues = Array($(this).siblings().length+1).fill('1fr');&nbsp; $('.selector-block').css({&nbsp; &nbsp; 'grid-template-columns': frValues.join(' ')&nbsp; });});.selector-block {&nbsp; display: grid;&nbsp; grid-template-columns: 1fr 1fr 1fr 1fr;&nbsp; transition: all 1s ease-in-out;}.selector-block > * {&nbsp; border: solid red 1px;}<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><div class="selector-block"><div id="select-oak">select-oak</div><div>foobar</div><div>baz</div><div>bat</div></div>实际上,您不能,因为您需要从子项的悬停触发父项的属性动画,这是不可能的。

潇湘沐

执行 JavaScript 会阻止呈现页面,这仅在代码执行返回到事件循环后发生。虽然更改样式属性可能会更新 DOM 并影响元素位置和大小的动态计算,但更新屏幕会延迟到脚本完成。这就是为什么您只能看到上次更新的结果。A1:您不能影响同步 JavaScript 循环内的页面显示。A2:这不是坏习惯,因为它无法完成:-)
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答