javascript - 如何使 html 元素响应其父视口(viewport)而不是浏览器视口(viewport)?

标签 javascript html css vue.js responsive-design

我正在开发一个 Vue 元素,我让用户通过单击每个设备特定的图标(移动设备、平板电脑、笔记本电脑和台式机)来选择应用程序主容器的宽度和高度。类似 Firefox 响应式工具。如何强制主容器内的元素响应其自己的视口(viewport)而不是浏览器视口(viewport)?
我正在使用 UIKit 宽度组件来定义我的断点。我知道我可以通过动态添加/删除类来实现这一点,但我的 Vue 组件是由用户动态添加的,所以它更复杂。
我认为可能有一种更通用的方法来做到这一点。这是示例代码(不同视口(viewport)中可见幻灯片的数量发生变化,如果我的组件是网格元素,则其内部的元素应该换行(基于容器宽度)):

<div id="main-container" :style="{width: deviceWidth, height: deviceHeight}">

  <!-- Dynamically added component -->
  <div class="uk-position-relative uk-visible-toggle uk-light" uk-slider>
  
    
    <!-- UIKit Width classes -->
    <ul class="uk-slider-items uk-child-width-1-2 uk-child-width-1-3@s uk-child-width-1-4@m">
      <li>
        <img src="../../img/01.jpg" alt="">
        <div class="uk-position-center uk-panel"><h1>1</h1></div>
      </li>
      <li>
        <img src="../../img/02.jpg" alt="">
        <div class="uk-position-center uk-panel"><h1>2</h1></div>
      </li>
      <li>
        <img src="../../img/03.jpg" alt="">
        <div class="uk-position-center uk-panel"><h1>3</h1></div>
      </li>
      <li>
        <img src="../../img/04.jpg" alt="">
        <div class="uk-position-center uk-panel"><h1>4</h1></div>
      </li>
    </ul>

    <a class="uk-position-center-left uk-position-small uk-hidden-hover" href="#" uk-slidenav-previous uk-slider-item="previous"></a>
    <a class="uk-position-center-right uk-position-small uk-hidden-hover" href="#" uk-slidenav-next uk-slider-item="next"></a>

  </div>
</div>

最佳答案

说明

这是一个非常简单且最小的答案,它的字面意思是为了简单地说明如何解决您的问题,但正如您在这个答案中看到的,按下不同的按钮会使包含的元素增大/缩小。

正如您在此解决方案中所看到的,所有响应式元素都将根据父元素的大小进行响应。如果您使用固定大小,那么实现这一点非常容易,就像我的示例一样。

尽管请注意,我只选择使用非常小的实现,没有使用 Vue 或任何复杂的东西,这是一个简单的解决方案,仅使用 native 技术。

编辑

确切了解您要寻找的内容之后,长话短说,没有干净且简单的方法可以做到这一点,至少据我所知,您最好的选择就是简单地改变和改变类(class),到目前为止是最有意义的。

因为你的问题有点模糊,对我来说,你似乎正在尝试执行类似于 @arieljuod 所说的逻辑,即你试图在特定 DOM 元素而不是用户的视口(viewport)上运行媒体查询。

我很遗憾地通知您,据我所知,没有干净、简单的方法来实现这一目标,并不是说没有办法,我确信有人已经找到了一种方法,但有一种干净、简洁的方法,易于阅读,解决方案,我高度怀疑是否存在这样的解决方案。

const clickHandler = txt => {
  let clName = '';

  switch (txt) {
    case 'Desktop':
      clName = 'desktop';
      break;
    case 'Tablet':
      clName = 'tablet';
      break;
    case 'Mobile':
      clName = 'mobile';
      break;
    default:
      clName = 'desktop';
  }

  document.getElementById("app").className = clName;
};

document.querySelectorAll("#sizes button").forEach(btn => {
  btn.onclick = () => clickHandler(btn.textContent);
});
#sizes {
  width: 100%;
  display: block;
  overflow: auto;
}

#sizes button {
  float: left;
  margin: 15px;
  padding: 15px;
  border: 1px solid black;
  background: white;
  box-sizing: border-box;
  width: calc(33.33% - 30px);
}

#app {
  height: 100vh;
  background: #eee;
}

#app.desktop {
  width: 960px;
}

#app.tablet {
  width: 700px;
}

#app.mobile {
  width: 320px;
}

.col-2 {
  display: block;
  overflow: auto;
}

.col-2>* {
  float: left;
  width: calc(50% - 30px);
  padding: 15px;
  margin: 15px;
  box-sizing: border-box;
  border: 1px solid black;
}


/* Just for a demo */

#redBlock {
  background: red;
  height: 100px;
  width: 75%;
}
<!-- UIkit CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-rc.25/css/uikit.min.css" />

<!-- UIkit JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-rc.25/js/uikit.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-rc.25/js/uikit-icons.min.js"></script>

<div id="sizes">
  <button>Desktop</button>
  <button>Tablet</button>
  <button>Mobile</button>
</div>

<div id="app" class="desktop">
  <div class="col-2">
    <p>Hello</p>
    <p>World!</p>
  </div>

  <div id="redBlock"></div>

  <div uk-slider>
    <div class="uk-position-relative uk-visible-toggle uk-light">
      <ul class="uk-slider-items uk-child-width-1-2 uk-child-width-1-3@s uk-child-width-1-4@m">
        <li>
          <img src="https://getuikit.com/docs/images/slider1.jpg" alt="">
          <div class="uk-position-center uk-panel">
            <h1>1</h1>
          </div>
        </li>
        <li>
          <img src="https://getuikit.com/docs/images/slider2.jpg" alt="">
          <div class="uk-position-center uk-panel">
            <h1>2</h1>
          </div>
        </li>
        <li>
          <img src="https://getuikit.com/docs/images/slider3.jpg" alt="">
          <div class="uk-position-center uk-panel">
            <h1>3</h1>
          </div>
        </li>
        <li>
          <img src="https://getuikit.com/docs/images/slider4.jpg" alt="">
          <div class="uk-position-center uk-panel">
            <h1>4</h1>
          </div>
        </li>
        <li>
          <img src="https://getuikit.com/docs/images/slider5.jpg" alt="">
          <div class="uk-position-center uk-panel">
            <h1>5</h1>
          </div>
        </li>
        <li>
          <img src="https://getuikit.com/docs/images/slider1.jpg" alt="">
          <div class="uk-position-center uk-panel">
            <h1>6</h1>
          </div>
        </li>
        <li>
          <img src="https://getuikit.com/docs/images/slider2.jpg" alt="">
          <div class="uk-position-center uk-panel">
            <h1>7</h1>
          </div>
        </li>
        <li>
          <img src="https://getuikit.com/docs/images/slider3.jpg" alt="">
          <div class="uk-position-center uk-panel">
            <h1>8</h1>
          </div>
        </li>
        <li>
          <img src="https://getuikit.com/docs/images/slider4.jpg" alt="">
          <div class="uk-position-center uk-panel">
            <h1>9</h1>
          </div>
        </li>
        <li>
          <img src="https://getuikit.com/docs/images/slider5.jpg" alt="">
          <div class="uk-position-center uk-panel">
            <h1>10</h1>
          </div>
        </li>
      </ul>

      <a class="uk-position-center-left uk-position-small uk-hidden-hover" href="#" uk-slidenav-previous uk-slider-item="previous"></a>
      <a class="uk-position-center-right uk-position-small uk-hidden-hover" href="#" uk-slidenav-next uk-slider-item="next"></a>

    </div>

    <ul class="uk-slider-nav uk-dotnav uk-flex-center uk-margin"></ul>
  </div>
</div>

可能的解决方案

在这种情况下我会做的如上所述,改变 slider 上的类,就像这样,我的意思是您可以使用额外/附加逻辑来检查用户的宽度等,但这可能 可能的最简单的方法。

const clickHandler = txt => {
  const slider = document.getElementById("mySlider");
  let clName = '';

  switch (txt) {
    case 'Desktop':
      clName = 'desktop';
      slider.className = 'uk-slider-items uk-child-width-1-4';
      break;
    case 'Tablet':
      clName = 'tablet';
      slider.className = 'uk-slider-items uk-child-width-1-3';
      break;
    case 'Mobile':
      clName = 'mobile';
      slider.className = 'uk-slider-items uk-child-width-1-2';
      break;
    default:
      clName = 'desktop';
      slider.className = 'uk-slider-items uk-child-width-1-4';
  }

  document.getElementById("app").className = clName;
};

document.querySelectorAll("#sizes button").forEach(btn => {
  btn.onclick = () => clickHandler(btn.textContent);
});
#sizes {
  width: 100%;
  display: block;
  overflow: auto;
}

#sizes button {
  float: left;
  margin: 15px;
  padding: 15px;
  border: 1px solid black;
  background: white;
  box-sizing: border-box;
  width: calc(33.33% - 30px);
}

#app {
  height: 100vh;
  background: #eee;
}

#app.desktop {
  width: 960px;
}

#app.tablet {
  width: 700px;
}

#app.mobile {
  width: 320px;
}

.col-2 {
  display: block;
  overflow: auto;
}

.col-2>* {
  float: left;
  width: calc(50% - 30px);
  padding: 15px;
  margin: 15px;
  box-sizing: border-box;
  border: 1px solid black;
}


/* Just for a demo */

#redBlock {
  background: red;
  height: 100px;
  width: 75%;
}
<!-- UIkit CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-rc.25/css/uikit.min.css" />

<!-- UIkit JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-rc.25/js/uikit.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-rc.25/js/uikit-icons.min.js"></script>

<div id="sizes">
  <button>Desktop</button>
  <button>Tablet</button>
  <button>Mobile</button>
</div>

<div id="app" class="desktop">
  <div class="col-2">
    <p>Hello</p>
    <p>World!</p>
  </div>

  <div id="redBlock"></div>

  <div uk-slider>
    <div class="uk-position-relative uk-visible-toggle uk-light">
      <ul id="mySlider" class="uk-slider-items uk-child-width-1-4">
        <li>
          <img src="https://getuikit.com/docs/images/slider1.jpg" alt="">
          <div class="uk-position-center uk-panel">
            <h1>1</h1>
          </div>
        </li>
        <li>
          <img src="https://getuikit.com/docs/images/slider2.jpg" alt="">
          <div class="uk-position-center uk-panel">
            <h1>2</h1>
          </div>
        </li>
        <li>
          <img src="https://getuikit.com/docs/images/slider3.jpg" alt="">
          <div class="uk-position-center uk-panel">
            <h1>3</h1>
          </div>
        </li>
        <li>
          <img src="https://getuikit.com/docs/images/slider4.jpg" alt="">
          <div class="uk-position-center uk-panel">
            <h1>4</h1>
          </div>
        </li>
        <li>
          <img src="https://getuikit.com/docs/images/slider5.jpg" alt="">
          <div class="uk-position-center uk-panel">
            <h1>5</h1>
          </div>
        </li>
        <li>
          <img src="https://getuikit.com/docs/images/slider1.jpg" alt="">
          <div class="uk-position-center uk-panel">
            <h1>6</h1>
          </div>
        </li>
        <li>
          <img src="https://getuikit.com/docs/images/slider2.jpg" alt="">
          <div class="uk-position-center uk-panel">
            <h1>7</h1>
          </div>
        </li>
        <li>
          <img src="https://getuikit.com/docs/images/slider3.jpg" alt="">
          <div class="uk-position-center uk-panel">
            <h1>8</h1>
          </div>
        </li>
        <li>
          <img src="https://getuikit.com/docs/images/slider4.jpg" alt="">
          <div class="uk-position-center uk-panel">
            <h1>9</h1>
          </div>
        </li>
        <li>
          <img src="https://getuikit.com/docs/images/slider5.jpg" alt="">
          <div class="uk-position-center uk-panel">
            <h1>10</h1>
          </div>
        </li>
      </ul>

      <a class="uk-position-center-left uk-position-small uk-hidden-hover" href="#" uk-slidenav-previous uk-slider-item="previous"></a>
      <a class="uk-position-center-right uk-position-small uk-hidden-hover" href="#" uk-slidenav-next uk-slider-item="next"></a>

    </div>

    <ul class="uk-slider-nav uk-dotnav uk-flex-center uk-margin"></ul>
  </div>
</div>

关于javascript - 如何使 html 元素响应其父视口(viewport)而不是浏览器视口(viewport)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53987489/

相关文章:

javascript - React-router:传播路由组件 props/state 的真正方法

javascript - 如何在jquery中给定的id之后添加表行

javascript - 覆盖核心 JS 命令?

javascript - 使用 id 和值自动完成下拉列表

javascript - 如何将水平滚动条添加到 jquery.bootgrid

html - 菜单 - 将文本中间与底部对齐的边框对齐

javascript - 如何使用纯 JavaScript 进行 AJAX 调用?

html - 为什么在 HTML Canvas 下添加小 div 时会出现水平滚动条?

html - 如何在html和css中将图像放在圆圈内?

javascript - 如何在没有抗锯齿的情况下调整 Canvas 大小?