- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
拖动拆分器时,如何调整 xul 窗口中特定节点的大小?
由于 xul 窗口的复杂性,无法使用 resizebefore/resizeafter 属性。
我试过使用 ondrag
分离器上的事件,但它根本没有触发。 ondragstart
事件触发正常,我可以使用 event.offsetY
捕获分离器移动了多少像素。
使用该值,我可以将其添加到需要元素的高度,这很好用,但不幸的是,每个拖动 session 仅触发一次此事件。
有任何想法吗?
谢谢你。
一个例子来测试它。由于我原来的 xul 的复杂性,我无法改变 xul 结构(用户可以隐藏和更改行的顺序),所以可能只有 javascript 解决方案是可行的):
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window id="testWindow"
title="testing resizing element by splitter"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
style="color: white;"
>
<vbox id="resizeme" flex="1" style="background-color: yellow; color: black;">
<hbox flex="1">
<label value="#1"/>
<hbox flex="1" align="center" pack="center">
<label value="Resizable by top and bottom splitter"/>
</hbox>
</hbox>
</vbox>
<splitter tooltiptext="Top splitter"/>
<grid flex="1">
<columns>
<column/>
<column flex="1"/>
</columns>
<rows>
<row style="background-color: black;">
<label value="#2"/>
<vbox flex="1" pack="center" align="center">
<label value="Must stay constant size at all times"/>
</vbox>
</row>
<row flex="1" style="background-color: blue;">
<label value="#3"/>
<vbox flex="1" pack="center" align="center">
<label value="Resizable by top splitter only"/>
</vbox>
</row>
<row style="background-color: black;">
<label value="#4"/>
<hbox flex="1" pack="center" align="center">
<label value="Must stay constant size at all times, content must fit"/>
<button label="blah"/>
</hbox>
</row>
<splitter tooltiptext="Bottom splitter"/>
<row flex="1" style="background-color: green;">
<label value="#5"/>
<vbox flex="1" pack="center" align="center">
<label value="Resizable by bottom splitter only"/>
</vbox>
</row>
<row style="background-color: black;">
<label value="#6"/>
<vbox flex="1" pack="center" align="center">
<label value="Must stay constant size at all times"/>
</vbox>
</row>
</rows>
</grid>
</window>
最佳答案
没有为 <splitter>
指定特定节点的常用方法。调整大小。
与所有在 XUL 中调整大小一样,目的是您应该能够对 XUL 进行编码,以便您可以使用 <splitter>
调整 UI 布局或其内部部分的大小。元素,自动,无需让您的 JavaScript 监听事件并执行调整大小。但是,您当然可以让 JavaScript 执行 <splitter>
调整大小。当您正在做一些复杂的事情时,您通常会这样做,您遇到了 <splitter>
中的错误之一。实现,您只是发现它比微调您的 XUL 以使用库存功能更容易,或者如果您只是想要编写您自己的代码提供的完整控制。重点是<splitter>
并且底层系统应该为您执行整个调整大小。
然而,<splitter>
元素确实有很大的限制和一些错误,这可能会导致您需要编写自己的调整大小代码。这些限制包括:
flex
属性重载。它用于控制对象最初的放置方式、窗口大小调整时对象的大小调整方式以及所有 <splitters>
对象的大小调整方式。 .您很可能希望在每种情况下都发生不同的事情。 <splitter>
代码。我观察到至少有几个不同的,包括一些明确声明为不灵活的元素仍然调整大小的地方。 IIRC,这些似乎主要是在尝试使用 <splitter>
时即在容器内更改超出该容器的对象的大小。 <splitter>
的元素是调整大小。 <splitter>
的机芯似乎不会触发
drag events .我认为这是因为移动了
<splitter>
不被视为“拖放”操作的一部分(即您实际上并未将其捡起并将其放在放置目标上)。虽然我希望能够听到拖动事件,但很明显它们没有触发。
<splitters>
中缺少的最重要的功能是缺乏通过 ID 指定要调整大小的两个元素的能力。显然,从您的问题的标题来看,很明显,您也发现这是非常缺乏的。
<splitter>
:
<splitter>
元素指定要在
resizebefore
中调整大小的元素的 ID和
resizeafter
XUL 中的属性。
<splitter>
上使用它,您将需要调用公共(public)函数之一来注册
<splitter>
使用
<splitter>
的 ID 或
<splitter>
元素。例如,两个
<spliter>
示例 XUL 中的元素(从您问题中的代码稍作修改)注册为:
splitterById.registerSplitterById("firstSplitter");
splitterById.registerSplitterById("secondSplitter");
/******************************************************************************
* splitterById *
* *
* XUL <splitter> elements which are registered will resize only the two *
* specific elements for which the ID is contained in the <splitter>'s *
* resizebefore and resizeafter attributes. The orient attribute is used to *
* specify if the <splitter> is resizing in the "vertical" or "horizontal" *
* orientation. "vertical" is the default. *
* *
* For a particular <splitter> this is an all or nothing choice. In other *
* words, you _must_ specify both a before and after element (e.g. You can not *
* mix using an ID on the resizebefore and not on resizeafter with the *
* expectation that the after will be resized with the normal <splitter> *
* functionality. *
* *
* On both elements, the attributes minheight, maxheight, minwidth, and *
* maxwidth will be obeyed. It may be necessary to explicitly set these *
* attributes in order to prevent one or the other element from growing or *
* shrinking when the other element is prevented from changing size by other *
* XUL UI constraints. For example, an element can not be reduced in size *
* beyond the minimum needed to display it. This code does not check for these *
* other constraints. Thus, setting these attributes, at least the ones *
* specifying the minimum height or minimum width will almost always be *
* desirable. *
* *
* Public methods: *
* registerSplitterById(id) : registers the <splitter> with that ID *
* registerSplitterByElement(element) : registers the <splitter> element *
* unregisterSplitterById(id) : unregisters the <splitter> with that ID *
* unregisterSplitterByElement(element) : unregisters the <splitter> element *
* *
******************************************************************************/
var splitterById = (function(){
let beforeER = {};
let afterER = {};
let splitIsVertical = true;
let origClientY = -1;
let origClientX = -1;
function ElementRec(_el) {
this.element = _el;
this.origHeight = getElementHeight(_el);
this.origWidth = getElementWidth(_el);
//The .minHeight and .maxHeight attributes/properties
// do not appear to be valid when first starting, so don't
// get them here.
//this.minHeight = getMinHeightAsValue(_el);
//this.maxHeight = getMaxHeightAsValue(_el);
}
function getElementHeight(el) {
//.height can be invalid and does not indicate the actual
// height displayed, only the desired height.
let boundingRec = el.getBoundingClientRect();
return boundingRec.bottom - boundingRec.top;
}
function getElementWidth(el) {
//.width can be invalid and does not indicate the actual
// width displayed, only the desired width.
let boundingRec = el.getBoundingClientRect();
return boundingRec.right - boundingRec.left;
}
function getMaxHeightAsValue(el) {
return asValueWithDefault(el.maxHeight,99999999);
}
function getMinHeightAsValue(el) {
return asValueWithDefault(el.minHeight,0);
}
function getMaxWidthAsValue(el) {
return asValueWithDefault(el.maxHeight,99999999);
}
function getMinWidthAsValue(el) {
return asValueWithDefault(el.minHeight,0);
}
function asValueWithDefault(value,myDefault) {
if(value === null || value === "" || value === undefined) {
value = myDefault;
}
//What is returned by the various attributes/properties is
// usually text, but not always.
value++;
value--;
return value;
}
function storeSplitterStartingValues(el) {
//Remember if the splitter is vertical or horizontal,
// references to the elements being resized and their initial sizes.
splitIsVertical = true;
if(el.getAttribute("orient") === "horizontal") {
splitIsVertical = false;
}
beforeER=new ElementRec(document.getElementById(el.getAttribute("resizebefore")));
afterER=new ElementRec(document.getElementById(el.getAttribute("resizeafter")));
if(beforeER.element === undefined || afterER.element === undefined) {
//Did not find one or the other element. We must have both.
return false;
}
return true;
}
function mousedownOnSplitter(event) {
if(event.button != 0) {
//Only drag with the left button.
return;
}
//Remember the mouse position at the start of the resize.
origClientY = event.clientY;
origClientX = event.clientX;
//Remember what we are acting upon
if(storeSplitterStartingValues(event.target)) {
//Start listening to mousemove and mouse up events on the whole document.
document.addEventListener("mousemove",resizeSplitter,true);
document.addEventListener("mouseup",endResizeSplitter,true);
}
}
function endResizeSplitter(event) {
if(event.button != 0) {
//Only drag with the left button.
return;
}
removeResizeListeners();
}
function removeResizeListeners() {
//Don't listen to document mousemove, mouseup events when not
// actively resizing.
document.removeEventListener("mousemove",resizeSplitter,true);
document.removeEventListener("mouseup",endResizeSplitter,true);
}
function resizeSplitter(event) {
//Prevent the splitter from acting normally:
event.preventDefault();
event.stopPropagation();
//Get the new size for the before and after elements based on the
// mouse position relative to where it was when the mousedown event fired.
let newBeforeSize = -1;
let newAfterSize = -1;
if(splitIsVertical) {
newBeforeSize = beforeER.origHeight + (event.clientY - origClientY);
newAfterSize = afterER.origHeight - (event.clientY - origClientY);
} else {
newBeforeSize = beforeER.origWidth + (event.clientX - origClientX);
newAfterSize = afterER.origWidth - (event.clientX - origClientX);
}
//Get any maximum and minimum sizes defined for the elements we are changing.
//Get these here because they may not have been populated/valid
// when the drag was first initiated (i.e. we should have been able
// to do this only once when the mousedown event fired, but testing showed
// the values are not necessarily valid at that time.
let beforeMinSize;
let beforeMaxSize;
let afterMinSize;
let afterMaxSize;
if(splitIsVertical) {
beforeMinSize = getMinHeightAsValue(beforeER.element);
beforeMaxSize = getMaxHeightAsValue(beforeER.element);
afterMinSize = getMinHeightAsValue(afterER.element);
afterMaxSize = getMaxHeightAsValue(afterER.element);
} else {
beforeMinSize = getMinWidthAsValue(beforeER.element);
beforeMaxSize = getMaxWidthAsValue(beforeER.element);
afterMinSize = getMinWidthAsValue(afterER.element);
afterMaxSize = getMaxWidthAsValue(afterER.element);
}
//Apply the limits to sizes we want to change to.
//These do appear to work better sequentially rather than optimized.
if(newBeforeSize < beforeMinSize) {
//Set to beforeMinSize limit if have passed.
let diff = beforeMinSize - newBeforeSize;
newBeforeSize += diff;
newAfterSize -= diff;
}
if(newBeforeSize > beforeMaxSize) {
//Set to beforeMaxSize limit if have passed.
let diff = beforeMaxSize - newBeforeSize;
newBeforeSize += diff;
newAfterSize -= diff;
}
if(newAfterSize < afterMinSize) {
//Set to afterMinSize limit if have passed.
let diff = afterMinSize - newAfterSize;
newAfterSize += diff;
newBeforeSize -= diff;
}
if(newAfterSize > afterMaxSize) {
//Set to afterMaxSize limit if have passed.
let diff = afterMaxSize - newAfterSize;
newAfterSize += diff;
newBeforeSize -= diff;
}
//Don't make any changes if we are still violating the limits.
//There are some pathological cases where we could still be violating
// a limit (where limits are set such that it is not possible to have
// a valid height).
if(newBeforeSize < beforeMinSize || newBeforeSize > beforeMaxSize
|| newAfterSize < afterMinSize || newAfterSize > afterMaxSize) {
return;
}
//Make the size changes
if(splitIsVertical) {
beforeER.element.height = newBeforeSize;
afterER.element.height = newAfterSize;
} else {
beforeER.element.width = newBeforeSize;
afterER.element.width = newAfterSize;
}
}
function _registerSplitterById(id) {
_registerSplitterByElement(document.getElementById(id));
}
function _registerSplitterByElement(el) {
el.addEventListener("mousedown",mousedownOnSplitter,false);
}
function _unregisterSplitterById(id) {
_unregisterSplitterByElement(document.getElementById(id));
}
function _unregisterSplitterByElement(el) {
el.removeEventListener("mousedown",mousedownOnSplitter,false);
removeResizeListeners();
}
return {
registerSplitterById : function(id) {
_registerSplitterById(id);
},
registerSplitterByElement : function(el) {
_registerSplitterByElement(el);
},
unregisterSplitterById : function(id) {
_unregisterSplitterById(id);
},
unregisterSplitterByElement : function(el) {
_unregisterSplitterByElement(el);
}
};
})();
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window id="testWindow"
title="testing resizing element by splitter"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
style="color: white;"
>
<vbox id="resizeme" height="120" minheight="30" maxheight="250"
style="background-color: yellow; color: black;">
<hbox flex="1">
<label value="#1"/>
<hbox flex="1" align="center" pack="center">
<label id="yellowLabel" value="Resizable by top and bottom splitter"/>
</hbox>
</hbox>
</vbox>
<splitter id="firstSplitter" tooltiptext="Top splitter" orient="vertical"
resizebefore="resizeme" resizeafter="blueVbox"/>
<grid>
<columns>
<column/>
<column flex="1"/>
</columns>
<rows>
<row style="background-color: black;">
<label value="#2"/>
<vbox pack="center" align="center">
<label value="Must stay constant size at all times"/>
</vbox>
</row>
<row id="blueRow" style="background-color: blue;">
<label value="#3"/>
<vbox id="blueVbox" height="120" minheight="30" pack="center" align="center">
<label id="blueLabel" value="Resizable by top splitter only"/>
</vbox>
</row>
<row style="background-color: black;">
<label value="#4"/>
<hbox pack="center" align="center">
<label value="Must stay constant size at all times, content must fit"/>
<button label="blah"/>
</hbox>
</row>
<splitter id="secondSplitter" tooltiptext="Bottom splitter" orient="vertical"
resizebefore="resizeme" resizeafter="greenVbox"/>
<row id="greenRow" style="background-color: green;">
<label value="#5"/>
<vbox id="greenVbox" height="120" minheight="30" pack="center" align="center">
<label id="greenLabel" value="Resizable by bottom splitter only"/>
</vbox>
</row>
<row style="background-color: black;">
<label value="#6"/>
<vbox pack="center" align="center">
<label value="Must stay constant size at all times"/>
</vbox>
</row>
</rows>
</grid>
<script type="application/x-javascript" src="file://b:/SplitterById.js"/>
<script type="application/javascript">
<![CDATA[
splitterById.registerSplitterById("firstSplitter");
splitterById.registerSplitterById("secondSplitter");
]]>
</script>
</window>
<splitters>
,我只测试过垂直
<splitters>
在上面的例子中。]
<splitter>
通常(不监听事件):
<splitter>
以您要求的方式运作。
<splitter>
调整哪个对象或对象的大小。元素,或整体布局的一般调整。其中包括使用
resizebefore
和
resizeafter
<splitter>
的属性结合
flex
的适当值XUL 中元素的属性,并可能包括
box
中的那些元素,
hbox
, 或
vbox
仅用于分发“flex”的元素。此外,可能需要使用各种
attributes available to an XUL element 为正在调整大小的区域内的每个元素指定各种约束。 (其他 MDN 文档:
1 、
2 、
3 )。
flex
属性可以是其他值,而不仅仅是
1
或
0
.该数值用于指定在特定元素上相对于受调整大小影响的其他元素(由于
<splitter>
或容器元素的调整大小(例如
<window>
、
<box>
、
<vbox>
、
<hbox>
等),其中包含您感兴趣的元素)。
<splitter>
容器内(在新示例中为
<grid>
),该容器需要在该容器外调整大小。]
flex
来实现。绿色值
<vbox>
相对于其他元素的较大值。
<vbox>
指定起始大小。元素。为了展示更多关于
<splitter>
发生的事情并为
flex
使用不同的值在绿色
<vbox>
, 我已经包含了一个起始/默认
height
其他
<vbox>
元素。这将导致这些元素从那个高度开始,然后只有在绿色
<vbox>
时才从那个高度缩小到它们的最小高度。已经缩小到最低高度。
style
属性的一部分是
min-height: 30px;
.除非您打算将它放在 CSS 类中,否则使用 XUL 属性
minheight
可能更好/更容易.如果您愿意,这样做将使以编程方式进行更改变得更容易。鉴于这是示例代码,您可能只是内联了它,以便不必还包含 CSS 文件。
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window id="testWindow"
title="testing resizing element by splitter"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
>
<hbox flex="1">
<vbox flex="1">
<vbox flex="1" height="80" pack="center" align="center"
style="background-color: blue; min-height: 30px; color: white;">
<label value="this should stay constant size until green element reached its minimum size"/>
</vbox>
<vbox id="resizeme" flex="10000" height="80" pack="center" align="center"
style="background-color: green; min-height: 30px; color: white;">
<label value="only this should be resized until it reached minimum size of 30px"/>
</vbox>
<vbox flex="1" height="80" pack="center" align="center"
style="background-color: red; min-height: 30px; color: white;">
<label value="this should stay constant size until green element reached its minimum size"/>
</vbox>
</vbox>
</hbox>
<splitter/>
<vbox flex="1"/>
</window>
<splitter>
时的样子调整大小:
关于javascript - splitter - 调整特定节点的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38162895/
我正在使用 JavaFX 8 创建一个应用程序。我使用拖/放动态更改网格 Pane 的内容。我希望每行或每行/列迭代 GridPane 内容。JavaFX 允许通过指定行和列在 GridPane 中添
我正在尝试将图像拖放到div上。图像没有被拖到div上并给出以下错误 Uncaught TypeError: Failed to execute 'appendChild' on 'Node': pa
我正在 android studio 中创建内部构建 AR 导航。我正在寻找一种方法将 anchor 与其他 anchor 或 anchor 节点/节点“连接”起来。我不确定使用哪一个。基于我将强制用
我在 Hive 上运行一些作业:首先是 4 节点,然后是 2 节点。令我惊讶的是,我的 2 节点性能比我的 4 节点更好。 首先,我在一个 4 节点(4 个事件节点)上运行查询,然后关闭 2 个节点(
我有 Node* current ,我在其中存储指向列表“顶部”当前节点的指针。当我将一个新节点设置为当前节点时,出现错误: '=' : cannot convert from 'CircularDo
我是 dcos Mesos 的新手,在本地 Ubuntu 机器上安装了 dc os。 我可以查看 dcos 仪表板。 但我无法使用 dcos node ssh --master-proxy --lea
在 JavaFX 中,是否有类似 setLayout(); 的东西?或 setBounds(); ? 例如,我想将按钮定位到我想要的位置。 最佳答案 JavaFX 场景图上的所有内容都是 Node .
我正在开发一个 JavaFX 应用程序,其中我开发的类(从 javafx.scene.Parent 扩展)是根据用户在 ListView 控件中单击的条目动态创建的。 只是要清楚这个节点,它不是使用像
我正在尝试为节点-边缘关系创建一个类图,因为它可以在有向图中找到。我想传达的是,Nodes 引用了 Edges,Edges 也引用了 Nodes。每个 Edge 都恰好需要两个 Node(源和目标)。
在mapreduce作业期间,单个任务将在随机节点上运行,是否有任何方法限制应在其中运行任务的节点? 最佳答案 Hadoop不会选择节点来随机运行任务。考虑到数据局部性,否则将有很多网络开销。 任务与
有什么区别: a) nodetool 重建 b) nodetool 修复 [-pr] 换句话来说,各个命令到底是做什么的? 最佳答案 nodetool重建:类似于引导过程(当您向集群添加新节点时),但
我已将第一个 OneToMany 关系添加到我的 hibernate 3.6.10 项目中。这是一个类: /** * */ package com.heavyweightsoftware.leal
是否有可能找到正在监听触发当前函数的事件的元素? 在下面的代码中,event.target 返回 #xScrollPane 和 event.currentTarget 和 event 的最低子节点.f
我正在尝试覆盖我数据库中的一些数据。结构很简单,就是: recipes { user_1{ recipe_1{data} recipe_2{data} } user_2{
我使用 setInterval 来运行该函数,但它会多次执行函数 2... 如何在输入中插入一个值后执行函数 第一个输入与其余输入的距离不同 如何在插入 val(tab 选项)后将插入从 1 个输入移
我不知道代码有什么问题,但在 visual studio 中不断收到这些错误消息。 Error 18 error C1903: unable to recover from previous e
我正在尝试从其类中获取 SharePoint 搜索导航节点的对象。 var nodes = $("div.ms-qSuggest-listItem"); 我正在获取节点对象,现在想要获取“_promp
D:\nodeP>node main.js module.js:327 抛出错误; ^ 错误:在 Function.Module 的 Function.Module._resolveFilename
struct node{ int key, prior, cnt, val; node *l, *r; node(){} node(int nkey) : key(nkey),
我有以下代码使用迭代器将项目插入双链表。这就是我们被要求这样做的方式。代码有效,但问题是我有 24 字节的绝对内存泄漏。 NodeIterator insert(NodeIterator & itrP
我是一名优秀的程序员,十分优秀!