【问题标题】:Images don't resize to the grid after hover function悬停功能后图像不会调整为网格
【发布时间】:2021-04-04 16:01:40
【问题描述】:

我想创建一张由 64 张图片组成的地图。每个图像都有两个对应的图像,当用户将鼠标悬停在它们上时,它们会一个接一个地显示,然后返回到第一个图像。那部分正在工作。我遇到的问题是用户将鼠标悬停在图像上后图像不会保持正确的大小。我希望图像保留在网格中。

example

这里是代码(也很抱歉,我还在学习,我希望这不是乱七八糟,也许我正在监督一些非常明显的事情):

<!DOCTYPE html>
<html>
<style>
    * {
        box-sizing: border-box;
    }

    body {
        margin: 0px;
        font-family: Arial;
        background-color: yellow;
    }



    .column {
        margin-top: 3%;
        margin-bottom: 1%;
        float: left;
        width: 12.5%;
        padding: 0px;
    }

    .column img {
        border: 0.5px solid yellow;

        float: left;

        height: 100px;
        background-size: cover;
    }



    .row:after {
        content: "";
        display: table;
        clear: both;
    }
</style>

<body>


    <head>

    </head>

    <div class="row">
        <div class="column">
            <div class="list">
                <img src="A/1.jpg" ; class="preview" ; style="width:100%">
                <img src="B/word1.jpg" ; class="preview" ; style="width:100%">
                <img src="C/1b.jpg" ; class="preview" ; style="width:100%">
            </div>

            <img src="A/9.jpg" style="width:100%">
            <img src="A/17.jpg" style="width:100%">
            <img src="A/25.jpg" style="width:100%">
            <img src="A/33.jpg" style="width:100%">
            <img src="A/41.jpg" style="width:100%">
            <img src="A/49.jpg" style="width:100%">
            <img src="A/57.jpg" style="width:100%">
        </div>
        <div class="column">
            <img src="A/2.jpg" style="width:100%">
            <img src="A/10.jpg" style="width:100%">
            <img src="A/18.jpg" style="width:100%">
            <img src="A/26.jpg" style="width:100%">
            <img src="A/34.jpg" style="width:100%">
            <img src="A/42.jpg" style="width:100%">
            <img src="A/50.jpg" style="width:100%">
            <img src="A/58.jpg" style="width:100%">
        </div>
        <div class="column">
            <img src="A/3.jpg" style="width:100%">
            <img src="A/11.jpg" style="width:100%">
            <img src="A/19.jpg" style="width:100%">
            <img src="A/27.jpg" style="width:100%">
            <img src="A/35.jpg" style="width:100%">
            <img src="A/43.jpg" style="width:100%">
            <img src="A/51.jpg" style="width:100%">
            <img src="A/59.jpg" style="width:100%">
        </div>
        <div class="column">
            <img src="A/4.jpg" style="width:100%">
            <img src="A/12.jpg" style="width:100%">
            <img src="A/20.jpg" style="width:100%">
            <img src="A/28.jpg" style="width:100%">
            <img src="A/36.jpg" style="width:100%">
            <img src="A/44.jpg" style="width:100%">
            <img src="A/52.jpg" style="width:100%">
            <img src="A/60.jpg" style="width:100%">
        </div>
        <div class="column">
            <img src="A/5.jpg" style="width:100%">
            <img src="A/13.jpg" style="width:100%">
            <img src="A/21.jpg" style="width:100%">
            <img src="A/29.jpg" style="width:100%">
            <img src="A/37.jpg" style="width:100%">
            <img src="A/45.jpg" style="width:100%">
            <img src="A/53.jpg" style="width:100%">
            <img src="A/61.jpg" style="width:100%">
        </div>
        <div class="column">
            <img src="A/6.jpg" style="width:100%">
            <img src="A/14.jpg" style="width:100%">
            <img src="A/22.jpg" style="width:100%">
            <img src="A/30.jpg" style="width:100%">
            <img src="A/38.jpg" style="width:100%">
            <img src="A/46.jpg" style="width:100%">
            <img src="A/54.jpg" style="width:100%">
            <img src="A/62.jpg" style="width:100%">
        </div>
        <div class="column">
            <img src="A/7.png" style="width:100%">
            <img src="A/15.jpg" style="width:100%">
            <img src="A/23.jpg" style="width:100%">
            <img src="A/31.jpg" style="width:100%">
            <img src="A/39.jpg" style="width:100%">
            <img src="A/47.jpg" style="width:100%">
            <img src="A/55.jpg" style="width:100%">
            <img src="A/63.jpg" style="width:100%">
        </div>
        <div class="column">
            <img src="A/8.jpg" style="width:100%">
            <img src="A/16.jpg" style="width:100%">
            <img src="A/24.jpg" style="width:100%">
            <img src="A/32.jpg" style="width:100%">
            <img src="A/40.jpg" style="width:100%">
            <img src="A/48.jpg" style="width:100%">
            <img src="A/56.jpg" style="width:100%">
            <img src="A/64.jpg" style="width:100%">
        </div>
    </div>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script>

        $(document).ready(function () {
            $(".preview").hide();
            var myInterval = false;
            $("div.list").each(function () {
                $(".preview:first", this).show();
                $(this).height($(".preview:first", this).height());
            });
            $('.preview').hover(function (e) {
                var $imgGrp = $(e.target);
                var $parent = $imgGrp.parent();
                var $firstImage = $parent.children('.preview:first');
                var iOffSet = $imgGrp.offset();
                myInterval = setInterval(function () {
                    var $nextImg;
                    $firstImage.hide();
                    if ($imgGrp.next('.preview').length == 0) {
                        $imgGrp.fadeOut('normal');
                        $imgGrp = $firstImage;
                        $nextImg = $imgGrp;
                    } else
                        $nextImg = $imgGrp.next('.preview');
                    if ($imgGrp != $nextImg)
                        $imgGrp.fadeOut('normal');
                    $nextImg.css({
                        'top': iOffSet.top,
                        'left': iOffSet.left,
                        'position': 'absolute'
                    });
                    $nextImg.fadeIn('normal');
                    $imgGrp = $nextImg;
                }, 750);
            },
                function () {
                    clearInterval(myInterval);
                    myInterval = false;
                });
        });


    </script>
</body>

</html>

如果有人有任何建议,我将非常感激。

【问题讨论】:

    标签: javascript html jquery css image


    【解决方案1】:

    我并没有真正得到您想要的确切机制,但这是一个 8x8 网格,每个网格单元有两个图像 - 图像在悬停时显示。

    // starting the grid
    const imageGrid = () => {
      let html = ''
      for (let i = 0; i < 64; i++) {
        html += `<div class="cell"><img src="https://loremflickr.com/100/100/cat?lock=${i}"/><div class="show-on-hover"><img src="https://loremflickr.com/100/100/cat?lock=${i}"/><img src="https://loremflickr.com/100/100/cat?lock=${i + 64}" /></div></div>`
      }
      return html
    }
    const grid = document.getElementById('grid')
    grid.innerHTML = imageGrid()
    html,
    body {
      margin: 0;
      padding: 16px;
    }
    
    .grid-container {
      display: grid;
      grid-template-columns: repeat(8, 1fr);
      grid-template-rows: repeat(8, 1fr);
      grid-gap: 0;
    }
    
    .cell {
      position: relative;
      box-sizing: border-box;
      border: 1px solid orange;
    }
    
    .cell img {
      width: 100%;
      height: 100%;
      display: block;
    }
    
    .cell>img:hover {
      opacity: 0.7
    }
    
    .cell .show-on-hover {
      display: flex;
      border: 2px solid red;
      box-sizing: border-box;
      background: black;
      position: absolute;
      top: 0;
      left: 0;
      display: none;
    }
    
    .cell:hover .show-on-hover {
      display: block;
      z-index: 10;
      box-shadow: 0 0 15px rgba(0, 0, 0, 1.0);
      transform: scale(1.3, 1.3);
    }
    
    .cell:hover .show-on-hover img {
      cursor: pointer;
    }
    
    .cell:hover .show-on-hover img:hover {
      opacity: 0.7;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="grid" class="grid-container"></div>

    编辑 - 基于评论

    这是一个新的 sn-p,基于对原始问题的澄清

    // creating an object with a getter function
    // the getter function takes care of the cyclic URLs:
    // anytime you call this objects src property, it will
    // return the URL that's next in the cycle
    const tileObj = (urls) => {
      // i is set so it's an internal variable - actually this
      // is the "state" of the tileObj
      let i = -1;
      return {
        get src() {
          return urls[++i % urls.length]
        }
      }
    }
    
    // creating the image objects
    const createImgArr = () => {
      // setting up the size of the image array
      const noTiles = 64
      const ret = []
      for (let i = 0; i < noTiles; i++) {
        // creating the image objects by pushing three URLs
        // per image object (you can push any number of URLs!)
        ret.push(tileObj([`https://loremflickr.com/100/100/cat?lock=${i}`, `https://loremflickr.com/100/100/cat?lock=${i + noTiles}`, `https://loremflickr.com/100/100/cat?lock=${i + 2 * noTiles}`]))
      }
      return ret
    }
    const imgArr = createImgArr();
    
    // starting the grid
    (function(imgArr) {
      // creating the image cells
      let html = ''
      for (let i = 0; i < imgArr.length; i++) {
        html += `
          <div class="cell" data-cellid="${i}">
            <img src="${ imgArr[i].src }" />
          </div>
        `
      }
      // adding the image cells to the grid
      const grid = document.getElementById('grid')
      grid.innerHTML = html
    
      // adding mouseenter event listener to the grid cells
      const cells = document.querySelectorAll('.cell')
      cells.forEach(cell => {
        cell.addEventListener('mouseenter', function(e) {
          // changing the image src on mouseenter
          const idx = Number(e.target.getAttribute('data-cellid'))
          const img = e.target.querySelector('img')
          // the image object takes care of cycling the src values
          // on hover - this is where the getter of that object
          // shows up
          img.src = imgArr[idx].src
        })
      })
    
    })(imgArr);
    html,
    body {
      margin: 0;
      padding: 16px;
    }
    
    .grid-container {
      display: grid;
      grid-template-columns: repeat(8, 1fr);
      grid-template-rows: repeat(8, 1fr);
      grid-gap: 0;
    }
    
    .cell {
      position: relative;
      box-sizing: border-box;
      border: 1px solid orange;
    }
    
    .cell img {
      width: 100%;
      height: 100%;
      display: block;
    }
    
    .cell>img:hover {
      opacity: 0.7
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="grid" class="grid-container"></div>

    我为您的问题创建了一个更高级的解决方案:

    • 有一个对象 (tileObj) 跟踪它应该返回的 URL(使用 getter 函数)
    • createImgArr 通过向函数(返回对象)提供三个不同的图像 URL 来创建所有 tileObjs
    • 网格的创建方式与之前大致相同
    • 一个mouseenter事件监听器被添加到每个cell,它改变了该单元格中图像的src(并且getter函数从它被“馈送”的URL数组中返回适当的URL它的创造)

    所以,关键是 URL 的“循环”隐藏在保存 URL 的对象中,因此代码没有复杂的“循环” - 每个 tileObj 都知道自己的状态,返回的 URL应该的。

    P.S.:您可能需要等待第一次 src 更改,因为必须下载图像

    【讨论】:

    • 感谢您的快速回复,很抱歉让我的问题不清楚。我想要一个 8x8 网格,每个单元格有 3 个图像。当有人将鼠标悬停在图像上时,图像会发生变化,例如首先显示 img01,然后您用光标越过它,网格中的图像会更改为 img02,然后当您再次越过它时,会显示 img03,然后当它返回到 img01 时再次将鼠标悬停在上面。我还研究了鼠标悬停功能,但没有让它在这个循环中工作。我希望这能让它更清楚。
    • 我设法创建了这个循环,但我遇到的问题是图像会缩放到 100% 的宽度并变形,而不是保持网格的大小。
    • @Maya 好的,我想我现在明白了 - 让我为此做一个快速的 sn-p
    • @Maya 我添加了另一个解决方案 - 当您将鼠标悬停在任何图块上时,图像是从“单元格已收到”的集合中设置的。循环很简单,每个项目都会跟踪它所处的循环状态。
    • 哦,哇,非常感谢。这超出了我的预期。还要感谢您添加所有这些注释。如果没有随机化器“loremflickr”,那将是相同的 3 张图像,对吧?我现在想知道的是有没有办法在 64 个图块中的每一个中推送 3 个特定图像?我的示例图像显示了单个图块一起创建了一个区域视图。每个图块应该有两个特定的对应图像,然后在此循环中显示。
    猜你喜欢
    • 1970-01-01
    • 2018-08-16
    • 1970-01-01
    • 2013-01-04
    • 2011-12-22
    • 1970-01-01
    • 2012-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多