有没有办法停止 dojo onBlur 事件处理程序中的所有其他事件
Is there a way to stop all other events in a dojo onBlur event handler?
也许我走错了路...
设置:我有一个相当复杂的完整 dojofied Web 应用程序。这个问题的重要部分是dijit.layout.BorderContainer
中心区域的长形,在其他区域中带有导航树和一些操作按钮。
我想做什么:如果用户确实输入了数据并且没有保存,如果他们要离开表单,他们应该会收到一条警告消息(如果他导航离开,则轻舔"新元素"按钮,...)。为了获得更好的用户体验,我想提供一个带有"保存"、"仍然离开"、"取消"选项的模式对话框。可能的想法是使用表单的onBlur事件,停止所有其他事件(很可能是onClick其他小部件),检查更改,如果有更改,则显示对话框,否则让其他事件继续。我不想为所有非表单活动元素添加 checkChanges 方法!
对于第一次测试,我只是试图停止事件......
这行得通
<div id="formArea" dojoType="dijit.form.Form" encoding="multipart/form-data" action="" class="ContentPane" region="center">
<script type="dojo/connect" event="onBlur" >
alert("I don't think so");
</script>
</div>
。但它很丑,我不能轻易继续
这不行
<div id="formArea" dojoType="dijit.form.Form" encoding="multipart/form-data" action="" class="ContentPane" region="center">
<script type="dojo/connect" event="onBlur" args="e">
console.log("blur"); // ok
e.preventDefault();//event.stopt(e)//return false //<--neither of these
</script>
</div>
问题是,如果我单击表单外部的按钮,onBlur
会触发,但我无法停止按钮上的onClick
。我知道onBlur
不会传递事件对象 - 所以e.something
无法真正工作......有没有办法捕捉另一个元素上的onClick
?
如果未保存数据,则在表单onBlur
中暂停按钮事件侦听器。
查看实际操作:http://jsfiddle.net/phusick/A5DHf/
您有一些按钮事件侦听器,请通过on.pausable(node, event, callback)
而不是on()
注册它们:
var b1Handler = on.pausable(button1Node, "click", function() {
console.log("b1.onClick");
});
var b2Handler = on.pausable(button2Node, "click", function() {
console.log("b2.onClick");
});
将处理程序收集到一个数组中:
var handlersToPause = [b1Handler, b2Handler];
添加onBlur
事件侦听器:
on(form, "blur", function(e) {
if (this.isDirty()) {
// if data are not saved, pause button event listeners
handlersToPause.forEach(function(handler) {
handler.pause();
});
// display modal dialog here
}
});
添加例如 onFocus
事件侦听器以恢复按钮事件侦听器:
on(form, "focus", function(e) {
handlersToPause.forEach(function(handler) {
handler.resume();
});
});
请注意,handler.pause()
暂停onclick
侦听器,而不是事件。onclick
事件在Event queue
中等待,因此在 onblur
的执行时间内无法访问。
我会制定一些更强大的解决方案,但这很快并回答了您的问题。无论如何,请查看dojo/aspect
及其around
建议,以调用checkChanges而无需更改所有非表单活动元素。
afaik confirm('question?')
会像这样"死锁"页面的事件。
不过,我已经进行了类似的设置,我解决这个问题的方式(除非用户在地址栏中输入 url 并点击 enter)是每当单击导航树时都会弹出对话框,将用户发送到新视图。考虑:
----------------------------------------
| Nav 1 | Asset1 ( view controller ) |
| Nav 2 | Asset2 ( hidden ) |
----------------------------------------
导航 1 是默认的加载视图,资产 1 已加载,包含"设置页面"表单或类似表单,可以更改。诀窍是,Asset1和Asset2是从AbstractAsset派生的,而AbstractAsset又是一个简单的ContentPane扩展。
在AbstractAsset中,有一个"必须覆盖功能"的函数,称为isDirty
var Viewcontroller = declare("AbstractAsset", [dijit.ContentPane], {
isDirty: function() { return false; }
});
declare("Asset1", [Viewcontroller], {
startup: function() {
// sets up form
...
// and references inputfields to 'this'
this.inputfields = this.form.getChildren();
// and saves (clones) the state of each field
var self = this;
this.inputfields.forEach(function(inputWidget) {
self.states[inputWidget.id] = inputWidget.get("value");
});
},
isDirty: function() {
var self = this;
var dirty = false;
this.form.getChildren().some(input) {
if(self.states[input.id] != input.get("value")) {
dirty = true;
return false; // breaks .some loop
}
return true;
});
return dirty;
}
})
然后,每次导航单击都必须调用当前可见的视图控制器的 isDirty 函数才能继续。假设用户单击导航树(dijit。树)行节点导航 2。
var navigation = dojo.declare("NavigationController", [dijit.Tree], {
currentView : null,
onLoad: function() {
// start Asset1 in viewNode by default
this.currentView = new Asset1({ }, this.viewNode);
},
onClick : function() {
if(this.currentView.isDirty()) alert("I Dont Think So");
else {
this.loadFunction(this.model.selection.getSelected());
}
}
});
这是实现卸载检查的一般思路,您需要通过"主应用程序控制器"挂钩任何onClick事件以确定应该发生的情况。检查此用作cms导航控制器的应用程序及其页面.js:587以获取isDirty 示例
- 执行php函数的onclick事件的其他替代方案
- 单击其他元素时,我如何使用 jQuery 忽略更改事件
- 如何查明鼠标按下事件是否发生在滚动条上或元素中的其他任何位置
- 为什么不'我的窗口滚动事件根本没有启动.其他答案没有解决问题
- 从其他元素上的单击事件访问image src属性
- Phonegap iOS-设备准备不发射其他事件做
- onbeforeunload事件在我的代码中没有触发,但其他示例可以工作
- 如何将单击事件绑定到其他类
- 停止内部事件处理程序冒泡的其他方法,jQuery
- 存在其他参数时访问Javascript事件
- 如何在不干扰网站其他部分的情况下,在画布上捕捉keydown事件
- Ajax 请求正在取消页面上的其他 JS 事件
- 可以使 jquery 点击事件在所有其他点击事件之后执行
- 捕获在Windows应用程序中启动其他应用程序的用户事件
- 如何使用cURL或其他方式在点击时执行事件
- 当其他事件发生时,用javascript隐藏的文本框将变为可见
- ext.js中还有其他事件我应该使用吗
- 将事件绑定到其他UI组件's函数,在Kendo MVVM中
- 更改时事件会触发其他事件
- 如何根据其他组件中的事件更新组件URL