【问题标题】:How to scale so that container also grows and takes up space如何扩展以使容器也增长并占用空间
【发布时间】:2018-02-19 15:41:07
【问题描述】:

所以我有一个容器,我想放大和缩小(放大和缩小)但也有它的扩展/缩小形式来占用空间,而不是仅仅重叠其他东西。

更新

有一个图像,其中有 absolute div 放置在坐标中,它们在调整大小时必须保持它们的相对位置(这就是我使用比例的原因)。

var b = document.getElementById("outer");
var scale = 1;

function increase() {
  scale += 0.1
  b.style.transform = `scale(${scale})`;
}

function decrease() {
  scale -= 0.1
  b.style.transform = `scale(${scale})`;
}
#outer {
  overflow-x: auto position: relative;
  transform-origin: left top;
}

.pointer {
  width: 20px;
  height: 20px;
  background-color: orange;
  position: absolute;
}

#a1 {
  top: 50px;
  left: 150px;
}

#a2 {
  top: 150px;
  left: 50px;
}

#a3 {
  top: 250px;
  left: 550px;
}
<div>
  <button onclick="increase()">Increase</button>
  <button onclick="decrease()">Decrease</button>
</div>
<div id=outer>
  <img src="http://via.placeholder.com/600x350" />
  <div id="a1" class='pointer'>
  </div>
  <div id="a2" class='pointer'>
  </div>
  <div id="a3" class='pointer'>
  </div>
</div>
<div>
  please don't cover me
</div>

宁愿没有第三方库(除了 jQuery),但可以考虑。

【问题讨论】:

    标签: javascript jquery html css


    【解决方案1】:

    CSS3 scale 转换就像那样。不幸的是,缩放 与其他元素重叠,因为它通过创建 新的堆叠上下文 将容器的内容从流中取出(基本上将其所有内容放置在 relative 到容器) - 请参阅相关文档说明:

    如果属性的值不同于 none,则为堆栈上下文 将被创建。

    来源:MDN

    查看下面的演示,通过蛮力缩放所有元素:

    var b, scale = 1, offset, pointers;
    
    window.onload = function() {
      b = document.getElementById("outer");
      offset = b.getBoundingClientRect();
      pointers = Array.prototype.map.call(b.querySelectorAll('.pointer'), function(e) {
        return {
          el: e,
          offset: e.getBoundingClientRect()
        }
      });
    }
    
    function increase() {
      scale += 0.1;
      scaleIt();
    }
    
    function decrease() {
      scale -= 0.1;
      scaleIt();
    }
    
    function scaleIt() {
      b.style.width = scale * offset.width + 'px';
      b.style.height = scale * offset.height + 'px';
      Array.prototype.forEach.call(pointers, function(e) {
        e.el.style.width = scale * e.offset.width + 'px';
        e.el.style.height = scale * e.offset.height + 'px';
        e.el.style.top = scale * e.offset.top + 'px';
        e.el.style.left = scale * e.offset.left + 'px';
      });
    }
    #outer {
      /*overflow-x: auto;*/
      position: relative;
      transform-origin: left top;
    }
    .pointer {
      width: 20px;
      height: 20px;
      background-color: orange;
      position: absolute;
    }
    #outer > img {
      height: 100%;
    }
    
    #a1 {
      top: 50px;
      left: 150px;
    }
    #a2 {
      top: 150px;
      left: 50px;
    }
    #a3 {
      top: 250px;
      left: 550px;
    }
    <div>
        <button onclick="increase()">Increase</button>
        <button onclick="decrease()">Decrease</button>
    </div>
    <div id=outer>
      <img src="http://via.placeholder.com/600x350" />
      <div id="a1" class='pointer'>
      </div>
      <div id="a2" class='pointer'>
      </div>
      <div id="a3" class='pointer'>
      </div>
    </div>
    <div>
        please don't cover me
    </div>

    【讨论】:

    • 指针(黄色框)没有按比例缩放:\。我目前正在解决这个问题,只需随时调整高度即可。
    • @A.Lau 我想添加一个 onload 来解决高度问题...请现在检查一下,谢谢!
    • .style.left 和 top 是干什么用的?
    • 我认为我所做的只是减少宽度/高度,以便其他元素会自动跟随,因为比例确实保持它们的相对位置。
    • 解决问题的方法太糟糕了,不应该在任何情况下使用
    【解决方案2】:

    我尝试了宽度和高度,我认为它的工作方式与你想要的一样,添加一个小动画,你可以使用它。

    var b = document.getElementById("outer");
    var b_width = document.getElementById("outer").offsetWidth;
    var b_height = document.getElementById("outer").offsetHeight;
    
    function increase()
    {
        b_width += 10
        b_height += 10
        b.style.width = b_width+"px";
        b.style.height = b_height+"px";
    }
    
    function decrease()
    {
        b_width -= 10
        b_height -= 10
        b.style.width = b_width+"px";
        b.style.height = b_height+"px";
    }
    #outer {
      background-color: red;
      padding: 1em;
      height: 80px;
      width: 80px;
      transform-origin: left top;
    }
    
    #inner {
      background-color: yellow;
      height: 50px;
      width: 100%;
    }
    <div>
        <button onclick="increase()">Increase</button>
        <button onclick="decrease()">Decrease</button>
    </div>
    <div id=outer>
      <div id=inner>
      </div>
    </div>
    <div>
        please don't cover me
    </div>

    【讨论】:

    • 对不起,我想我应该更新我的小提琴,因为它不能准确地反映我当前的问题。我有一个图像和一组较小的 div,它们充当图像的指针,所以我需要它们保持它们的相对位置。我马上更新
    【解决方案3】:

    编辑:抱歉匆匆忙忙,我的意思是更新容器

    你可以,添加一个容器。存储此容器的初始大小。现在,当您缩放内部元素时,将 容器 宽度/高度更新为相同的比例。

    var a = document.getElementById("outer-wrapper");
    var b = document.getElementById("outer");
    var scale = 1;
    var aWidth = a.offsetWidth;
    var aHeight = a.offsetHeight;
    
    function increase()
    {
        scale += 0.1
        b.style.transform = `scale(${scale})`;
        a.style.width = `${scale * aWidth}px`;
        a.style.height = `${scale * aHeight}px`;
    }
    
    function decrease()
    {
        scale -= 0.1
        b.style.transform = `scale(${scale})`;
        a.style.width = `${scale * aWidth}px`;
        a.style.height = `${scale * aHeight}px`;
    }
    #outer {
      position: relative;
      transform-origin: left top;
    }
    
    .pointer {
      width: 20px;
      height: 20px;
      background-color: orange;
      position: absolute;
    }
    
    #a1 {
      top: 50px;
      left: 150px;
    }
    #a2 {
      top: 150px;
      left: 50px;
    }
    #a3 {
      top: 250px;
      left: 550px;
    }
    <div>
        <button onclick="increase()">Increase</button>
        <button onclick="decrease()">Decrease</button>
    </div>
    <div id="outer-wrapper">
      <div id="outer">
        <img src="http://via.placeholder.com/600x350" />
        <div id="a1" class='pointer'>
        </div>
        <div id="a2" class='pointer'>
        </div>
        <div id="a3" class='pointer'>
        </div>
      </div>
    </div>
    <div>
        please don't cover me
    </div>

    【讨论】:

    • 您确实意识到您已经涵盖了文本,对吗?这不应该发生。
    【解决方案4】:

    如果您的用例与您的示例一样简单,我认为您可能过于复杂了。如果你需要你的子元素保持它们与父元素的相对位置,你只需要使用相对单位而不是绝对单位来定义它们的位置,然后让 CSS 渲染引擎来做它的事情。

    在这里我设置了父级的宽度(而不是比例),让图像自动调整大小以适应容器来设置其高度,并使用百分比而不是像素。

    var b = document.getElementById("outer");
    var width = 600;
    
    function increase() {
      width = width * 1.1
      b.style.width = width + 'px';
    }
    
    function decrease() {
      width = width / 1.1
      b.style.width = width + 'px';
    }
    #outer {
      position: relative;
    }
    
    #outer img {
        width: 100%;
        height: auto;
    }
    
    .pointer {
      width: 3.333%;
      height: 5.714%;
      background-color: orange;
      position: absolute;
    }
    
    #a1 {
      top: 8.333%;
      left: 14.285%;
    }
    
    #a2 {
      top: 42.857%;
      left: 8.333%;
    }
    
    #a3 {
      top: 71.428%;
      left: 91.667%;
    }
    <div>
      <button onclick="increase()">Increase</button>
      <button onclick="decrease()">Decrease</button>
    </div>
    <div id=outer>
      <img src="http://via.placeholder.com/600x350" />
      <div id="a1" class='pointer'>
      </div>
      <div id="a2" class='pointer'>
      </div>
      <div id="a3" class='pointer'>
      </div>
    </div>
    <div>
      please don't cover me
    </div>

    【讨论】:

      【解决方案5】:

      最好的办法是为每个子元素使用动态百分比 (%) 高度、宽度和位置。

      我们只是根据需要将所有像素值除以宽度或高度,并在 JS 中简单地更改父容器的宽度并观察奇迹发生;)

      请在下面找到代码,在值发生变化的地方添加了适当的 cmets。

      var b = document.getElementById("outer");
      var scale = 1;
      
      function increase() {
        scale += 0.1
        // Just change the width of parent
        b.style.width = 600 * scale + "px";
      }
      
      function decrease() {
        scale -= 0.1
        // Just change the width of parent
        b.style.width = 600 * scale + "px";
      }
      #outer {
        overflow-x: auto;
        position: relative;
        transform-origin: left top;
        width: 600px; /* Give div static width for children to position correctly */
      }
      
      #outer img {
        width: 100%; /* Set image to stretch full width */
      }
      
      .pointer {
        width: 3.33%; /* 20px/600px*100% */
        padding-top: 3.33%;/* Don't use static height */
        background-color: orange;
        position: absolute;
      }
      
      #a1 {
        top: 14.28%;/* 50px/350px*100% */
        left: 25%;/* 150px/600px*100% */
      }
      
      #a2 {
        top: 42.85%;/* 150px/350px*100% */
        left: 8.33%;/* 50px/600px*100% */
      }
      
      #a3 {
        top: 71.42%;/* 250px/350px*100% */
        left: 91.66%; /* 550px/600px*100% */
      }
      <div>
        <button onclick="increase()">Increase</button>
        <button onclick="decrease()">Decrease</button>
      </div>
      <div id=outer>
        <img src="http://via.placeholder.com/600x350" />
        <div id="a1" class='pointer'>
        </div>
        <div id="a2" class='pointer'>
        </div>
        <div id="a3" class='pointer'>
        </div>
      </div>
      <div>
        please don't cover me
      </div>

      附:要将标记显示为框,我们将其宽度设置为顶部填充(设置为百分比时相对于父宽度),因此它始终显示为正方形。 ;)

      在我看来,这更易于管理,因为您不必在 JS 中处理每个元素。

      【讨论】:

        【解决方案6】:

        我会使用比例以外的其他属性,这与比例不同会影响流程。您可以更改 div 的高度、宽度、边距、填充、字体大小等。

        编辑:如果您真的想使用缩放以统一的方式更改元素内所有内容的大小,您可以拥有一个可以更改宽度和高度的外部元素,以及一个您可以将缩放更改为的内部元素匹配外部元素的宽度和高度。外部元素会影响内容的流动。但是我真的不认为这是可取的,因为如果您只是放大容器内的所有最终图标和文本,无论如何它看起来都不会那么好,您可能希望将容器内的许多元素保持在相同的大小,不管容器的大小。

        【讨论】:

          猜你喜欢
          • 2020-08-21
          • 1970-01-01
          • 1970-01-01
          • 2012-06-04
          • 1970-01-01
          • 1970-01-01
          • 2021-01-23
          • 1970-01-01
          • 2016-08-18
          相关资源
          最近更新 更多