在 dat.gui 中禁用按钮的方法?
Posted
技术标签:
【中文标题】在 dat.gui 中禁用按钮的方法?【英文标题】:Method for disabling a button in dat.gui? 【发布时间】:2014-06-27 23:07:28 【问题描述】:我正在尝试找出一种方法来轻松禁用/启用 dat.gui 中的按钮。
我设置了 dat.gui 来控制动画。当动画结束时,我希望禁用“播放”按钮。我尝试向按钮的 DOM 元素添加“禁用”属性,但在设置此属性后单击按钮时,我仍然看到相应的函数触发。
我目前的方法如下:
-
在dat.gui界面中找到与按钮对应的
li
元素
创建一个新的半透明黑色 DOM 元素,并将其添加到 li
元素中以使按钮的内容变灰。
在绑定到该按钮的函数中,检查按钮内是否存在这个“已禁用”的 DOM 元素,如果存在,则不要执行该函数的其余部分。
这是一个 hack,我很想知道是否有一些方法可以禁用 dat.gui 中内置的按钮,或者我不知道的更好的方法。
【问题讨论】:
【参考方案1】:在 dat.GUI 中,FunctionController
类负责按钮。如果您查看its source code,那里没有条件逻辑。控制器将监听按钮上的click
事件,并始终在单击时调用该函数。这意味着您不会从这里的库中获得任何帮助 - 您需要在处理程序中检查按钮是否被禁用。大致如下:
// Find the GUI controller listening to given property on given object
function getController(gui, object, property)
for (var i = 0; i < gui.__controllers.length; i++)
var controller = gui.__controllers[i];
if (controller.object == object && controller.property == property)
return controller;
return null;
...
object.button = function()
// Don't do anything if the button is disabled
if (getController(gui, this, "button").domElement.hasAttribute("disabled"))
return;
alert("Button clicked");
;
gui.add(object, "button");
...
// Disable button
getController(gui, object, "button").domElement.setAttribute("disabled", "");
请注意,dom.GUI 中的禁用元素没有特殊样式,您必须为此添加自己的样式。鉴于您在按钮的情况下看到的是属性标签而不是实际按钮,这不会很简单 - 我认为您必须将 disabled
属性放在 controller.domElement.parentNode
而不是 controller.domElement
.然后你应该可以使用选择器[disabled] > .property-name
来设置你的样式。
编辑:您实际上可以通过扩展 FunctionController
以更通用的方式执行此操作:
function blockEvent(event)
event.stopPropagation();
Object.defineProperty(dat.controllers.FunctionController.prototype, "disabled",
get: function()
return this.domElement.hasAttribute("disabled");
,
set: function(value)
if (value)
this.domElement.setAttribute("disabled", "disabled");
this.domElement.addEventListener("click", blockEvent, true);
else
this.domElement.removeAttribute("disabled");
this.domElement.removeEventListener("click", blockEvent, true);
,
enumerable: true
);
这将向控制器添加一个属性disabled
,该属性将捕获click
事件,因此不会触发按钮处理程序。然后禁用按钮变得更简单:
getController(gui, object, "button").disabled = true;
并且按钮处理程序可以保持不变,它根本不会被禁用的按钮触发。
【讨论】:
谢谢弗拉基米尔。这与我目前使用的方法基本相同(除了我向 DOM 添加一个元素,而不是一个属性,但想法是相同的)。正如我所怀疑的,使用 dat.gui 代码可能不是一个简单的方法来处理这个问题。 @JeffFohl:我添加了一个更通用的解决方案 - 您可以扩展FunctionController
,这将允许您保持其他代码(如按钮处理程序)不变。
啊 - 伟大的解决方案弗拉基米尔。谢谢!【参考方案2】:
这是我能想到的最直接的方法来禁用 dat GUI 的单个元素:
let gui = new dat.GUI();
let uiElement = gui.add(myObject, 'myPropertyName');
uiElement.__li.style = "opacity: 0.5; filter: grayscale(100%) blur(1px); pointer-events: none;";
旧浏览器可能不支持pointer-events: none;
,因此您可以选择添加:
disableAll(uiElement.__li);
function disableAll(element)
for( var i = 0; i < element.childNodes.length; ++i)
let elt = element.childNodes[i];
disableAll(elt);
elt.disabled = true;
这可能看起来很“hacky”,但在官方dat GUI API 中没有这样的功能,即使它在那里,也很可能会做一些非常相似的事情。
最后,通过 API 你可以完全删除一个元素:
uiElement.remove();
【讨论】:
以上是关于在 dat.gui 中禁用按钮的方法?的主要内容,如果未能解决你的问题,请参考以下文章