在Sciter中,事件的流通分为两个阶段:沉没阶段,冒泡阶段
通俗点说,沉没阶段就是父元素像子元素传递消息的一个过程,此时事件并没有真正发生。它给机会我们在事件发生前处理它,使得拦截事件成为可能。
<html> <head> <script type="text/tiscript"> self.on("~click", "button", function(evt) { stdout.println("~click"); return false; }); self.on("click", "button", function(evt) { stdout.println("click"); }); $(button).onControlEvent = function(evt) { if (evt.type == (Event.BUTTON_CLICK || Event.SINKING)) { stdout.println("button.SINKING"); } else if (evt.type == (Event.BUTTON_CLICK || Event.HANDLED)) { stdout.println("button.HANDLED"); } else if (evt.type == Event.BUTTON_CLICK) { stdout.println("button.BUTTON_CLICK"); } } $(body).onControlEvent = function(evt) { if (evt.type == (Event.BUTTON_CLICK || Event.SINKING)) { stdout.println("body.SINKING"); } else if (evt.type == (Event.BUTTON_CLICK || Event.HANDLED)) { stdout.println("body.HANDLED"); } else if (evt.type == Event.BUTTON_CLICK) { stdout.println("body.BUTTON_CLICK"); } } </script> </head> <body> <button>button</button> </body> </html>依次输出:
~click
body.SINKING
button.SINKING
button.BUTTON_CLICK
body.BUTTON_CLICK
click
在用户点击按钮时,Sciter首先调用sinking阶段的处理程序,在消息流通的过程中,sinking阶段永远都是最先执行的。这个阶段的处理程序会有返回值,返回true表示该消息已经处理,无须再将消息派发到子元素,反之,消息会继续向子元素传递。所以,在sinking阶段,父元素永远比子元素能更先处理消息。
如果在sinking阶段消息没有被处理的话,每经过一个元素,都会触发该元素的onControlEvent方法,并且事件中带有Event.SINKING标记。如果消息在到达目标元素后都没有被处理过,那么才会产生事件,这时事件会从目标元素像父元素传递(会调用所有事件处理程序)。
反之,如果在sinking阶段消息被处理了的话(返回true),则元素不会收到带有Event.SINKING标记的消息了,而会收到带有Event.HANDLED标记的消息
<html> <head> <script type="text/tiscript"> self.on("~click", "button", function(evt) { stdout.println("~click"); return true; }); self.on("click", "button", function(evt) { stdout.println("click"); }); $(button).onControlEvent = function(evt) { if (evt.type == (Event.BUTTON_CLICK || Event.SINKING)) { stdout.println("button.SINKING"); } else if (evt.type == (Event.BUTTON_CLICK || Event.HANDLED)) { stdout.println("button.HANDLED"); } else if (evt.type == Event.BUTTON_CLICK) { stdout.println("button.BUTTON_CLICK"); } } $(body).onControlEvent = function(evt) { if (evt.type == (Event.BUTTON_CLICK || Event.SINKING)) { stdout.println("body.SINKING"); } else if (evt.type == (Event.BUTTON_CLICK || Event.HANDLED)) { stdout.println("body.HANDLED"); } else if (evt.type == Event.BUTTON_CLICK) { stdout.println("body.BUTTON_CLICK"); } } </script> </head> <body> <button>button</button> </body> </html>仅仅是修改了第6行,返回true即可。输出结果如下:
~click
button.HANDLED
body.HANDLED
可以看到,当收到HANDLED标记的消息时,表示消息在sinking阶段就被处理了,消息流通即刻终止,不会再触发后面的事件处理程序了。
最后献上一张图,更加直观了
补充:
mouseenter/mouseleave事件比较特殊,流通方向不像图中所示,详情请看另一篇:https://blog.csdn.net/aqtata/article/details/82688199