Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 是否有方法停止dojo onBlur事件处理程序中的所有其他事件?_Javascript_Dojo_Dom Events - Fatal编程技术网

Javascript 是否有方法停止dojo onBlur事件处理程序中的所有其他事件?

Javascript 是否有方法停止dojo onBlur事件处理程序中的所有其他事件?,javascript,dojo,dom-events,Javascript,Dojo,Dom Events,也许我走错了方向 设置: 我有一个相当复杂的完全dojofied的web应用程序。这个问题的重要部分是dijit.layout.BorderContainer的中心区域中的一个较长形式,在其他区域中有一个导航树和一些操作按钮 我想做什么: 如果用户确实输入了数据但没有保存,如果他要离开表单,他们应该会收到一条警告消息(如果他离开了,请点击“新元素”按钮……)。为了获得更好的用户体验,我想提供一个带有选项“保存”、“无论如何都要离开”、“取消”的模式对话框。 May的想法是使用表单的onBlur事

也许我走错了方向

设置: 我有一个相当复杂的完全dojofied的web应用程序。这个问题的重要部分是dijit.layout.BorderContainer的中心区域中的一个较长形式,在其他区域中有一个导航树和一些操作按钮

我想做什么: 如果用户确实输入了数据但没有保存,如果他要离开表单,他们应该会收到一条警告消息(如果他离开了,请点击“新元素”按钮……)。为了获得更好的用户体验,我想提供一个带有选项“保存”、“无论如何都要离开”、“取消”的模式对话框。 May的想法是使用表单的onBlur事件,停止所有其他事件(很可能是在其他小部件上单击一次),检查更改,如果有更改,则显示对话框,否则让其他事件继续。 我不想向所有非窗体活动元素添加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>

console.log(“blur”);//好啊

e、 预防默认值()//event.stopt(e)//return false//只有一个aik
confirm('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();            
    });
});