Javascript 是否有方法停止dojo onBlur事件处理程序中的所有其他事件?
也许我走错了方向 设置: 我有一个相当复杂的完全dojofied的web应用程序。这个问题的重要部分是dijit.layout.BorderContainer的中心区域中的一个较长形式,在其他区域中有一个导航树和一些操作按钮 我想做什么: 如果用户确实输入了数据但没有保存,如果他要离开表单,他们应该会收到一条警告消息(如果他离开了,请点击“新元素”按钮……)。为了获得更好的用户体验,我想提供一个带有选项“保存”、“无论如何都要离开”、“取消”的模式对话框。 May的想法是使用表单的onBlur事件,停止所有其他事件(很可能是在其他小部件上单击一次),检查更改,如果有更改,则显示对话框,否则让其他事件继续。 我不想向所有非窗体活动元素添加checkChanges方法 在第一次测试中,我只是试图阻止这些事件 这很有效Javascript 是否有方法停止dojo onBlur事件处理程序中的所有其他事件?,javascript,dojo,dom-events,Javascript,Dojo,Dom Events,也许我走错了方向 设置: 我有一个相当复杂的完全dojofied的web应用程序。这个问题的重要部分是dijit.layout.BorderContainer的中心区域中的一个较长形式,在其他区域中有一个导航树和一些操作按钮 我想做什么: 如果用户确实输入了数据但没有保存,如果他要离开表单,他们应该会收到一条警告消息(如果他离开了,请点击“新元素”按钮……)。为了获得更好的用户体验,我想提供一个带有选项“保存”、“无论如何都要离开”、“取消”的模式对话框。 May的想法是使用表单的onBlur事
<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>
console.log(“blur”);//好啊
e、 预防默认值()//event.stopt(e)//return false//只有一个aikconfirm('question?)
会像这样“死锁”页面的事件
不过我也做了类似的设置,我解决这个问题的方法(除非用户在addressbar中输入url并点击enter)是每当单击导航树时弹出一个对话框,将用户发送到一个新视图。考虑:
----------------------------------------
| Nav 1 | Asset1 ( view controller ) |
| Nav 2 | Asset2 ( hidden ) |
----------------------------------------
Nav 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函数才能继续。假设用户单击nav树(dijit.tree)行节点nav 2
这是实现on-unload检查的总体思路,您需要通过“主应用程序控制器”钩住任何onClick事件,以确定应该发生什么。作为cms导航控制器,如果数据未保存,则在表单的onBlur
中作为isDirty示例的its
在行动中看到它:
如果您有一些按钮事件侦听器,请通过on.pausable(节点、事件、回调)注册它们,而不是通过on()注册它们。
:
将处理程序聚集到数组中:
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
事件正在事件队列中等待,因此在执行onblur
时无法访问
我会想出一些更可靠的解决方案,但这很快就能回答您的问题。无论如何,看看dojo/aspect
及其调用checkChanges的方法,无需更改所有非表单活动元素。问题是浏览器可能运行了N个事件。上面的onBlur仅阻止对其中一个进行操作,即当前的onBlur-event。感谢您的想法!我需要考虑一下。对于Phusick的回答,我有点难过,因为我仍然需要接触其他(非形式)元素,但这似乎是唯一的方法,我恐怕是这样的:)在一个DOM中触发的事件对从另一个DOM中触发的事件是隐藏的,我想这更接近于我可以在我们的架构中使用的内容。感谢您的想法on()
和dojo/aspect
对我来说是新的,我确实需要看看它们。目前,我们仍然使用dojo 1.6,尽管:/dojo 1.6或多或少也可以这样做,只需使用dojo.connect
,而不是dojo/on
和dojo/aspect
。是的,暂停是不必要的^^^但是,在没有控制器的情况下工作都是匿名架构最终会受到伤害。。问题是,如果所有浏览器都同步调用onblur和onclick,那么只需在FF中测试您的小提琴,它就会正常工作。在小提琴中所做的更改,在窗体每次聚焦时保存值,并且isDirty根据当前值检查这些值
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
}
});
on(form, "focus", function(e) {
handlersToPause.forEach(function(handler) {
handler.resume();
});
});