首页 > 解决方案 > 如何给画布最大空间并在其上放置左侧(可滚动)和右侧“菜单”div?

问题描述

我为我的问题准备了一个完整而简单的jsFiddle

我的文字游戏目前使用 HTML 表格来布置 HTML 画布和 jQuery UI 按钮。

我想摆脱 HTML 表,而是使用 HTML div 元素,我在屏幕截图中用箭头写在红色/黄色框中:

截屏

我希望 div 元素具有以下结构:

- fullDiv (should occupy 100% width and height of browser window)
-- hintDiv (100% width, min height, visible on top)
-- mainDiv (100% width, max height)
--- gameDiv (100% width, max height)
---- myCanvas (100% width, max height)
-- leftDiv (min width, same height as mainDiv, scrollable) <- relative position
-- rightDiv (min width, same height as mainDiv) <- relative position
-- totalDiv (100% width, min height, visible on bottom)

这个想法是给myCanvas尽可能多的空间和地方leftDivrightDiv就像它两边的“菜单”一样。这将是一个带有可滚动游戏列表的导航菜单,并且具有与和leftDiv相同的最大可能高度。myCanvasrightDiv

所以我尝试了以下代码 -

$(function () {
  $(':button').button();
  $('#fullCheck').checkboxradio();

  var gamesMenu = $('#gamesMenu').menu({
    items: '> :not(.ui-widget-header)'
  });

  for (var game = 1; game <= 50; game++) {
    gamesMenu.append('<LI VALUE="' + game + '">GAME ' + game + '</LI>');
  }
    gamesMenu.menu('refresh');
});
body {
  margin: 0;
  padding: 0;
}

#fullDiv {
  width: 100%;
  height: 100vh;
  background: #FFF;
}

#hintDiv,
#totalDiv {
  text-align: center;
}

#mainDiv,
#gameDiv {
  width: 100%;
  height: 100%;
}

#myCanvas {
  width: 100%;
  height: 100%;
  border: 4px red dotted;
  background: #CCF;
}

#leftDiv {
  position: relative;
  left: 0;
  top: 0;
  /* bottom: 0; */
  text-align: center;
  background: #FCC;
}

#rightDiv {
  position: relative;
  right: 0;
  top: 0;
  /* bottom: 0; */
  text-align: center;
  background: #CFC;
}

#gamesMenu {
  overflow-y: scroll;
}

#hintDiv {
  font-style: italic;
}
<div id="fullDiv">
  <div id="hintDiv">Hint</div>
  <div id="mainDiv">
    <div id="gameDiv">
      <canvas id="myCanvas"></canvas>
    </div>

    <div id="leftDiv">
      <button id="newBtn">New game</button>
      <ul id="gamesMenu"></ul>
    </div>

    <div id="rightDiv">
      <input id="fullCheck" type="checkbox">
      <label for="fullCheck">Full screen</label><br>
      <button id="recallBtn">Recall</button><br>
      <button id="shuffleBtn">Shuffle</button><br>
      <button id="swapBtn">Swap</button><br>
      <button id="skipBtn">Skip</button><br>
      <button id="resignBtn">Resign</button><br>
      <button id="pileBtn">Pile</button><br>
      <button id="movesBtn">Moves history</button><br>
      <button id="shareBtn">Share</button><br>
      <button id="playBtn">Play</button>
    </div>
  </div>
  <div id="totalDiv">Total</div>
</div>

<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> 
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

但是,我的屏幕现在完全乱了:

截屏

更新:

这是德里克的解决方案(谢谢!)

$(function () {
  $(':button').button();
  $('#fullCheck').checkboxradio();

  var gamesMenu = $('#gamesMenu').menu({
    items: '> :not(.ui-widget-header)'
  });

  for (var game = 1; game <= 50; game++) {
    gamesMenu.append('<LI VALUE="' + game + '">GAME ' + game + '</LI>');
  }

    gamesMenu.menu('refresh');
});
body {
  margin: 0;
  padding: 0;
}

#fullDiv {
  width: 100%;
  height: 100vh;
  background: #FFF;
  display: flex;
  flex-direction: column;
}

#hintDiv,
#totalDiv {
  text-align: center;
  background: yellow;
}

#leftDiv {
  text-align: center;
  background: #FCC;
  display: flex;
  flex-direction: column;
}

#gamesMenu {
  overflow-y: auto;
}

#mainDiv {
  flex-grow: 1;
  display: flex;
  justify-content: space-between;
  overflow: hidden;
}

#gameDiv {
  flex-grow: 1;
}

#myCanvas {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  border: 4px red dotted;
  background: #CCF;
}

#rightDiv {
  text-align: center;
  background: #CFC;
  overflow-y: auto;
}

#hintDiv {
  font-style: italic;
}
<div id="fullDiv">
  <div id="hintDiv">Hint</div>
  <div id="mainDiv">
    <div id="leftDiv">
      <button id="newBtn">New game</button>
      <ul id="gamesMenu"></ul>
    </div>

    <div id="gameDiv">
      <canvas id="myCanvas"></canvas>
    </div>

    <div id="rightDiv">
      <input id="fullCheck" type="checkbox">
      <label for="fullCheck">Full screen</label><br>
      <button id="recallBtn">Recall</button><br>
      <button id="shuffleBtn">Shuffle</button><br>
      <button id="swapBtn">Swap</button><br>
      <button id="skipBtn">Skip</button><br>
      <button id="resignBtn">Resign</button><br>
      <button id="pileBtn">Pile</button><br>
      <button id="movesBtn">Moves history</button><br>
      <button id="shareBtn">Share</button><br>
      <button id="playBtn">Play</button>
    </div>
  </div>
  <div id="totalDiv">Total</div>
</div>

<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> 
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

更新 2:

出于某种原因,jQuery UI 菜单不可悬停(尽管在官方演示中它是)...

到目前为止,我的解决方法是(至少看到所选项目):

li.selected {
  font-weight: bold;
  background-color: yellow;
}

var gamesMenu = $('#gamesMenu').menu({
  items: '> :not(.ui-widget-header)',
  select: function(ev, ui) {
    ui.item.addClass('selected').siblings().removeClass('selected');
  }
});

标签: htmlcsscss-position

解决方案


这可以使用弹性布局来完成。

  • #fullDiv使用flex布局使其flex-direction: column可以在列上对齐。
  • 设置flex: 1 1 auto#mainDiv以便它可以占用除#hintDiv和之外#totalDiv的空间#fullDiv
  • 也设置#mainDivflex布局justify-content: space-between您将在本指南中了解这一点。
  • 由于该指南,交换#leftDivand #gameDiv
  • #gameDiv,我更新了画布的宽度和高度,calc(100% - 8px)因为边框大小将添加到真实的画布大小。所以现在,画布边框宽度为 4px,因此画布宽度将为(100% - 8px) + 8px(border size) = 100%.

/*$(function () {
  $(':button').button();
  $('#fullCheck').checkboxradio();

  var gamesMenu = $('#gamesMenu').menu({
    items: '> :not(.ui-widget-header)'
  });

  for (var game = 1; game <= 50; game++) {
    gamesMenu.append('<LI VALUE="' + game + '">GAME ' + game + '</LI>');
  }
});*/
body {
  font-family: Arial, Helvetica, sans-serif;
  margin: 0;
  padding: 0;
}

#fullDiv {
  width: 100%;
  height: 100vh;
  background: #FFF;
}

#hintDiv,
#totalDiv {
  text-align: center;
}

#myCanvas {
  width: calc(100% - 8px);
  height: calc(100% - 8px);
  border: 4px red dotted;
  background: #CCF;
}

#leftDiv {
  text-align: center;
  background: #FCC;
}

#rightDiv {
  text-align: center;
  background: #CFC;
}

#gamesMenu {
  overflow-y: scroll;
}

#publishBtn {
  max-width: 200px;
}

#timer1,
#timer2 {
  color: red;
}

#hintDiv {
  font-style: italic;
}


/*** Additional Codes ***/
#fullDiv {
  display: flex;
  flex-direction: column;
}

#mainDiv {
  flex: 1 1 auto;
  display: flex;
  justify-content: space-between;
}

#gameDiv {
  flex: 1 1 auto;
}
<div id="fullDiv">
  <div id="hintDiv">Hint</div>
  <div id="mainDiv">
    <div id="leftDiv">
      <button id="newBtn">New game</button>
      <ul id="gamesMenu"></ul>
    </div>
    
    <div id="gameDiv">
      <canvas id="myCanvas"></canvas>
    </div>

    <div id="rightDiv">
      <input id="fullCheck" type="checkbox">
      <label for="fullCheck">Full screen</label><br>
      <button id="recallBtn">Recall</button><br>
      <button id="shuffleBtn">Shuffle</button><br>
      <button id="swapBtn">Swap</button><br>
      <button id="skipBtn">Skip</button><br>
      <button id="resignBtn">Resign</button><br>
      <button id="pileBtn">Pile</button><br>
      <button id="movesBtn">Moves history</button><br>
      <button id="shareBtn">Share</button><br>
      <button id="playBtn">Play</button>
    </div>
  </div>
  <div id="totalDiv">Total</div>
</div>

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


推荐阅读