小部件内类中的气泡事件
Bubbling event from Class inside a Widget?
我拼命想从我编写的类中激发一个事件。我在我的YUI小部件中使用这个类,并且我希望我的YUI小部件响应被激发的事件。我知道事件Bubbling是如何工作的,所以这里的代码工作得非常好:
YUI().use('event-custom', 'node', function (Y) {
function Publisher(bubbleTo) {
this.addTarget(bubbleTo);
this.publish("testEvent", {
emitFacade: true
});
this.fire("testEvent");
}
function BubbleTarget() {
this.on("testEvent", function (e) {Y.log("Bubbling in Test.js succeed!")});
var newPublisher = new Publisher(this);
}
// To fire events or be a bubble target, augment a class with EventTarget
Y.augment(Publisher, Y.EventTarget);
Y.augment(BubbleTarget, Y.EventTarget);
var bubbleTarget = new BubbleTarget();});
然而,当我试图将这个概念应用于我的Widget时,我很难失败。
YUI.add("SlideShow", function(Y) {
function SlideShow(config) {
SlideShow.superclass.constructor.apply(this, arguments);
}
SlideShow.NAME = "SlideShow";
Y.extend(SlideShow, Y.Widget, {
initializer: function() {
Y.log("Widget loaded!");
this.on("testEvent", function () {
Y.log("This should, but won't appear despite how hard I try!");
});
},
renderUI: function(){
var testSlide = new Slide("text", this);
}
});
Y.SlideShow = SlideShow;
function Slide(sendTo)
{
this.addTarget(sendTo);
this.publish("testEvent", {
defaultFn: function(){Y.log('Event published.')},
emitFacade: true
});
this.fire("testEvent");
}
Y.augment(Slide,Y.EventTarget, true, null, {emitFacade: true});
}, "0.0.1", {requires:["widget","event-custom","node","anim"]});
Chromium中的日志输出为:
- 在Test.js中冒泡成功
- 小工具已加载
- 事件已发布
我似乎真的很怀念Widgets的一些精髓。请帮我更好地理解这个主题。
我想答案在Mitch的帖子里。您需要在气泡目标订阅上添加事件前缀。因此:
this.on("testEvent", function () {
Y.log("This should, but won't appear despite how hard I try!");
});
尝试:
this.on("*:testEvent", function () {
Y.log("This should, but won't appear despite how hard I try!");
});
或者在幻灯片类上设置.NAME(无论如何你都应该这样做):
Slide.NAME = "Slide";
然后你的前缀使用这个值:
this.on("Slide:testEvent", function () {
Y.log("This should, but won't appear despite how hard I try!");
});
使用Y.Base.create将删除大量样板。
当一个普通的JS对象和一个Y.Widget必须交互时,我无法告诉你为什么它会失败,而它可以与两个普通的JavaScript对象一起工作。
然而,扩展Y.Base将解决您的问题,同时充分利用Y.Base的力量:
function Slide(config)
{
Slide.superclass.constructor.apply(this, config);
}
Slide.NAME = "slide";
Y.extend(Slide, Y.Base, {
initializer : function() {
this.publish("testEvent", {
emitFacade: true//you do not need to specify this,
//it will be set implicitly to true
//when using Y.Base
});
},
test : function(arg) {
this.addTarget(arg);
this.fire("testEvent");
}
});
这里重要的是NAME属性-它将成为小部件要监听的前缀:
Y.extend(SlideShow, Y.Widget, {
initializer: function() {
Y.log("Widget loaded!");
this.on("slide:testEvent", function () {
Y.log("This will work!");
});
this.on("*:testEvent", function () {
Y.log("This will work, too no matter what's the Event's prefix!");
});
this.on("Slide:testEvent", function () {
Y.log("This won't work, since the prefix doesn't match the NAME-Attribute!");
});
},
//rendering etc.
});
在renderUI中,您将调用:
renderUI: function(){
var testSlide = new Slide();
testSlide.on('testEvent', function(e) {
Y.log('You can listen for testEvent without a prefix on a Slide-object.');
});
testSlide.test(this);//adds this Widget as the target for the testSlide.
}
有趣的问题!
因此,我试图深入研究并将问题脱钩。
首先,我测试了@Mitch的例子——正如预期的那样,它有效!证明:http://jsfiddle.net/pqr7/hQBHH/3/
但如果Slide是普通对象(不是从Y.Base扩展而来)呢?我测试了@brian-j-miller的例子,但它不起作用。证明:http://jsfiddle.net/pqr7/hQBHH/4/
然后我运行我的firebug并逐步深入YUI源代码。现在我知道它是如何详细工作的!
让我们看看带有普通对象Slide的示例http://jsfiddle.net/pqr7/hQBHH/4/当我在普通对象Slide上执行this.fire("testEvent");
时,YUI在内部调用链中的许多函数,并使用字符串="testEvent"
的事件type
进行操作(我称之为"类型",因为在源代码中,它总是保存在名为"type"的变量上)。我发现事件泡沫和丰富你的目标(SlideShow的实例)如预期。然后它检查SlideShow是否有一些订阅type
=="testEvent"
的事件?回答:没有!
如果您在SlideShow中订阅为this.on('testEvent', ...)
,则它实际上存储为字符串type
=="SlideShow:testEvent"
如果您在SlideShow中订阅为this.on('*:testEvent', ...)
,它实际上存储为字符串type
=="*:testEvent"
如果您在SlideShow中订阅为this.on('Slide:testEvent', ...)
,则它实际上存储为字符串type
=="Slide:testEvent"
但冒泡的是:简单的type
=="testEvent"
,所以SlideShow实例中没有订阅者。
然后,YUI用*:testEvent
检查更复杂的规则。不幸的是,我们的简单字符串testEvent
与模式*:testEvent
不匹配这是原始代码http://yuilibrary.com/yui/docs/api/files/event-custom_js_event-target.js.html#693
if (type.indexOf(PREFIX_DELIMITER) > -1) { /* make a magic to execute a subscriber */ }
type
这是我们的冒泡字符串testEvent
,它不包含PREFIX_DELITER(它是冒号)
这就是当你从Y扩展Slide时的区别。Base-firered事件不是简单的testEvent
,而是Slide:testEvent
,它模拟了模式*:testEvent
(http://jsfiddle.net/pqr7/hQBHH/3/)
- 分派点击事件并保留击键修饰符
- 模糊事件的Javascript测试
- 小部件内类中的气泡事件
- 在Javascript捕获和气泡中执行所有事件
- 点击文本框事件时出现气泡
- 捕获给定类型的所有事件,而不考虑气泡/目标
- HERE 地图 (JS v3) - 将事件侦听器添加到信息气泡
- 如何在 easljs 中停止事件气泡
- D3 数据映射:气泡上的单击事件
- D3 数据映射:传入气泡属性的气泡上的 OnClick 事件
- 奇怪的点击事件气泡在iPhone safari上,它在冒泡到document.body之前停止
- 是否可以在事件气泡期间传递参数
- IE/Firefox气泡事件
- 如何防止气泡事件后,我将焦点设置为文本区域
- 实现jquery气泡弹出的点击事件
- 来自transcluded指令的角度气泡事件
- 使用Ember组件中的Morris.js图,使用自定义对象从组件到控制器的气泡动作事件
- 事件气泡或循环回调
- 气泡滚动/鼠标滚轮事件
- 谷歌地图标记点击事件气泡