10年前我用C ++编写了一个GUI布局引擎,我很好奇它的功能如何在浏览器中最接近。
在较旧的GUI库(如Microsoft Windows')中,小部件的位置和大小通常由四个数字给出: left,top,width 和< EM>高度。我的引擎不同之处在于每个数字都加倍,所以你必须指定八个数字:相对左,绝对左;相对顶部,绝对顶部;相对宽度,绝对宽度;相对高度和绝对高度。 相对值应以父窗口小部件的宽度或高度的百分比给出,绝对值应在中给出像素即可。对于顶级窗口,“父窗口小部件”是桌面。
示例:
a)400 x 300 px窗口,以屏幕为中心:
const int WINDOW_WIDTH = 400;
const int WINDOW_HEIGHT = 300;
CWindow mainWindow;
mainWindow.setPosition(0.5, -WINDOW_WIDTH / 2, 0.5, -WINDOW_HEIGHT / 2);
mainWindow.setSize(0.0, WINDOW_WIDTH, 0.0, WINDOW_HEIGHT);
b)主窗口右边缘的150 px宽按钮容器面板:
const int PANEL_WIDTH = 150;
CPanel buttonPanel(mainWindow);
buttonPanel.setPosition(1.0, -PANEL_WIDTH, 0.0, 0);
buttonPanel.setSize(0.0, PANEL_WIDTH, 1.0, 0);
c)容器面板顶部有三个按钮(新建,打开,保存),底部有一个按钮(退出):
const int BUTTON_HEIGHT = 30;
CButton newButton(buttonPanel, "New");
newButton.setPosition(0.0, 0, 0.0, 0 * BUTTON_HEIGHT);
newButton.setSize(1.0, 0, 0.0, BUTTON_HEIGHT);
CButton openButton(buttonPanel, "Open");
openButton.setPosition(0.0, 0, 0.0, 1 * BUTTON_HEIGHT);
openButton.setSize(1.0, 0, 0.0, BUTTON_HEIGHT);
CButton saveButton(buttonPanel, "Save");
saveButton.setPosition(0.0, 0, 0.0, 2 * BUTTON_HEIGHT);
saveButton.setSize(1.0, 0, 0.0, BUTTON_HEIGHT);
CButton exitButton(buttonPanel, "Exit");
exitButton.setPosition(0.0, 0, 1.0, -1 * BUTTON_HEIGHT);
exitButton.setSize(1.0, 0, 0.0, BUTTON_HEIGHT);
手工编写这样的布局代码可能会让您感到尴尬,但是一旦掌握了它就很容易。
Here是我能够共同破解的:
a)主窗口,按钮面板和按钮的层次结构以HTML格式显示:
<div id="mainWindow">
<div id="buttonPanel">
<div id="newButton" class="button"></div>
<div id="openButton" class="button"></div>
<div id="saveButton" class="button"></div>
<div id="exitButton" class="button"></div>
</div>
</div>
b)在CSS中div的位置设置为绝对值:
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body { margin: 0; color: yellow; }
#mainWindow { position: absolute; background: red; }
#buttonPanel { position: absolute; background: green; }
.button { border: 1px solid cyan; }
#newButton { position: absolute; background: blue; }
#openButton { position: absolute; background: blue; }
#saveButton { position: absolute; background: blue; }
#exitButton { position: absolute; background: blue; }
c)布局功能在JavaScript中实现,使用jQuery:
function setPosition(widget, relLeft, absLeft, relTop, absTop) {
$(widget)
.css('left', relLeft * 100 + '%').css('left', '+=' + absLeft + 'px')
.css('top', relTop * 100 + '%').css('top', '+=' + absTop + 'px');
}
function setSize(widget, relWidth, absWidth, relHeight, absHeight) {
$(widget)
.css('width', relWidth * 100 + '%').css('width', '+=' + absWidth + 'px')
.css('height', relHeight * 100 + '%').css('height', '+=' + absHeight + 'px');
}
function setButtonText(button, text, height) {
$(button)
.text(text)
.css('text-align', 'center')
.css('vertical-align', 'middle')
.css('line-height', height + 'px');
}
window.onresize = function () {
var WINDOW_WIDTH = 400,
WINDOW_HEIGHT = 300,
PANEL_WIDTH = 150,
BUTTON_HEIGHT = 30;
setPosition('#mainWindow', 0.5, -WINDOW_WIDTH / 2, 0.5, -WINDOW_HEIGHT / 2);
setSize('#mainWindow', 0.0, WINDOW_WIDTH, 0.0, WINDOW_HEIGHT);
setPosition('#buttonPanel', 1.0, -PANEL_WIDTH, 0.0, 0);
setSize('#buttonPanel', 0.0, PANEL_WIDTH, 1.0, 0);
setButtonText('#newButton', "New", BUTTON_HEIGHT);
setPosition('#newButton', 0.0, 0, 0.0, 0 * BUTTON_HEIGHT);
setSize('#newButton', 1.0, 0, 0.0, BUTTON_HEIGHT);
setButtonText('#openButton', "Open", BUTTON_HEIGHT);
setPosition('#openButton', 0.0, 0, 0.0, 1 * BUTTON_HEIGHT);
setSize('#openButton', 1.0, 0, 0.0, BUTTON_HEIGHT);
setButtonText('#saveButton', "Save", BUTTON_HEIGHT);
setPosition('#saveButton', 0.0, 0, 0.0, 2 * BUTTON_HEIGHT);
setSize('#saveButton', 1.0, 0, 0.0, BUTTON_HEIGHT);
setButtonText('#exitButton', "Exit", BUTTON_HEIGHT);
setPosition('#exitButton', 0.0, 0, 1.0, -1 * BUTTON_HEIGHT);
setSize('#exitButton', 1.0, 0, 0.0, BUTTON_HEIGHT);
};
onresize();
请注意,JavaScript代码与上面显示的C ++代码非常相似!
这个基于JavaScript的布局是否可以构建“真正的”Web应用程序,或者我应该使用CSS代替?由于我基本上是桌面应用程序开发人员,因此需要专家级Web开发人员的意见。谢谢!
===更新===
Here是纯HTML + CSS解决方案。我使用了@Christoph提出的负边距技巧。我唯一的问题是相同的常量被复制到CSS中的很多地方。例如,按钮高度(30px)用于九个位置,这使维护更加困难。
答案 0 :(得分:4)
通常,内联css(通过style=""
附加的css)被认为是一个糟糕的选择。由于您通过脚本动态生成它,因此可以接受。
然而,有一些问题:
window.onresize
中的布局。应谨慎使用此事件。正如您在小提琴中看到的那样,您的示例UI相当小,但在调整窗口大小时已经变得无法响应。 (无论如何,你的例子中的那些值都是静态的)所以我的提示是:
init()
方法进行初始布局window.onresize
或至少使用一些超时机制来减少触发那些绘画事件(reduce number of calls for .resize and .scroll methods)css()
调用,而是在separate stylesheet中为你的元素编写css。答案 1 :(得分:2)
使用CSS设置初始值总是更容易,性能更好,更快。将所有内容设置为绝对可以工作,但是,根据应用程序,可能会成为布局噩梦,因为绝对定位的元素将从正常流中移除。
虽然我看到你来自哪里,曾经为桌面编写图形应用程序,你会发现它对网络效果不佳,除非你期望一个固定的布局,其中布局性能不是是至关重要的。
然而,我正在思考当今世界的布局,你需要适应各种形状和大小的设备。一方面,使用javascript可以更容易地控制所有这些,并且很多时候它是最好的方式,但是,otoh,CSS可以处理大量的媒体查询,以减轻您和编码的负担。 / p>
要考虑很多。
答案 2 :(得分:2)
简短回答:
这太糟糕了!永远不要那样。
答案很长:
这不是网络的工作方式。您的应用程序将无法执行,因为css规则将等待js下载和解释;但这不是这里的主要问题。主要关注的是你。
您永远无法维护像这样的代码。当您构建一个简单的应用程序时,您可以轻松地使用几千个css规则。如果以这种方式组织,则无法阅读。我甚至没有提到媒体查询的东西。以这种方式构建应用程序的复杂性太高了。
如果你想去网络,你必须拥抱网络;不要尝试旧的桌面应用程序开发技巧(这是桌面应用程序的优点)。例如,如果您想在右上角放置一些内容,请转到:right: 0
。不是WINDOW_WIDTH
;如果你的蚂蚁集中在某些地方,你有很多方法可以这样做;但是你没有为这个职位做数学。从来没有这样做过。
作为一个webapplication开发者,我的建议就是这个:
使用罗盘:http://compass-style.org/
其实不行,请使用Yeoman:http://yeoman.io/
使用工具有点复杂,无法完全理解;但它太值得了。
顺便说一句,永远不要绑定onresize
这样的事件。您必须添加debounce
,否则您将遇到严重的表演麻烦。
答案 3 :(得分:1)
我绝对不是专家,但这是我的2美分:
在您的设计中使用JavaScript一直很好。但是为了做到这一点,你还需要一些静态CSS,对于那些没有启用JavaScript的人来说,还有可访问性等等。
Javascript设计一直是关于增强您的Web应用程序,而不是替换它。你绝对应该看一下关于Unobtrusive JavaScript的维基百科页面。
回到你的问题,为什么不默认你的按钮有一个固定的大小,让你的JavaScript功能在可用时替换它?
此外,我在您的Web应用程序中没有得到的是,在这里,一切都可以在CSS中完成,并且速度更快。它会有更好的性能,你甚至不用担心JavaScript。