html - 如何给画布最大空间并在其上放置左侧(可滚动)和右侧“菜单”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
尽可能多的空间和地方leftDiv
,rightDiv
就像它两边的“菜单”一样。这将是一个带有可滚动游戏列表的导航菜单,并且具有与和leftDiv
相同的最大可能高度。myCanvas
rightDiv
所以我尝试了以下代码 -
$(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>
但是,我的屏幕现在完全乱了:
- 元素
myCanvas
,leftDiv
和rightDiv
并排放置,而不是leftDiv
/rightDiv
覆盖myCanvas
在其两侧 myCanvas
占据整个浏览器窗口,推hintDiv
/totalDiv
出屏幕gamesMenu
显示在其全部荣耀中,而不是可滚动的
更新:
这是德里克的解决方案(谢谢!)
$(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');
}
});
解决方案
这可以使用弹性布局来完成。
#fullDiv
使用flex
布局使其flex-direction: column
可以在列上对齐。- 设置
flex: 1 1 auto
为#mainDiv
以便它可以占用除#hintDiv
和之外#totalDiv
的空间#fullDiv
。 - 也设置
#mainDiv
为flex
布局justify-content: space-between
。您将在本指南中了解这一点。 - 由于该指南,交换
#leftDiv
and#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>
推荐阅读
- javascript - 如何将 JavaScript 插入 Power BI 报表服务器
- php - 从外部连接到数据库(在 Windows 服务器中)
- c# - 我正在尝试将我的数据添加到数据库中,但出现了这个错误
- c# - 尝试在嵌套类中设置数据时出错
- angular - 如果数据总是从根向下流动,输出如何影响 Angular 中的父级?
- sql-server - 如何根据 category_id USING SQL SERVER 从表中选择值
- corda - 在重新部署的 Corda Enterprise App 上发布更新状态
- react-native - React Native App 作为 Tcp 客户端
- scala - 如何使用scala为spark数据框中的列添加前缀和后缀值
- php - 如何在 Web 服务器上显示 Plivo 短信文本?