滚动事件发生时,防止在元素上悬停

时间:2015-01-07 22:10:27

标签: javascript events backbone.js marionette

我使用backbone / marionette构建了一个下拉小部件,让您可以使用键盘在下拉列表中上下导航。我需要区分选择和突出显示,所以我将布尔值存储在列表项模型的isSelected和isHighlighted中。每当项目悬停时,isHighlighted将更改为true。

这是我的问题,我已将下拉列表设置为有一个maxItem,所以当下拉列表中的项目太多时,我会显示一个滚动条,以便人们可以滚动查看更多列表项。当我使用键盘导航导航传递maxItem限制时,我调用一个动画和scrollTop一定的距离,以便突出显示在视图中。问题是如果我碰巧在下拉列表中有鼠标并且发生滚动,它将在鼠标指针所在的项目上触发mouseenter事件。然后它会将悬停元素的isHighlighted更改为true。这意味着突出显示的项目重新启动,当我使用键盘再次向下导航时,它将从顶部向下而不是从我之前的位置继续。

当滚动事件触发时,我是否可以阻止mouseenter事件?

尝试包含所有相关代码,希望这会有所帮助:

onKeyUp: function (event) {
    var key = event.which;

    switch (key) {
        case 38: // UP
            this.onUpArrow();
            break;
        case 40: // DOWN
            this.onDownArrow();
            break;
        default:
            // default method
    }
},
onDownArrow: function () {
    if (!this.isDropdownOpen()) {
        this.openDropdown();
    } else {
        this.dropdown.highlightNext();
        this.dropdown.scroll();
    }
},

在另一个档案中,我有

events: {
    'mouseenter': 'onMouseEnter'
},
onMouseEnter: function (event) {
    this.triggerMethod('dropdown:option:mouseenter', {
        event: event,
        view: this,
        model: this.model
    });
},

在另一个档案中,我有

onDropdownOptionMouseenter: function () {
    var data = _.last(arguments),
        event = data.event,
        view = data.view;
    view.highlight();
}

此时,滚动发生,并且已触发mouseenter触发器并且突出显示已更改。我只是不知道在哪里可以添加代码以防止浏览器识别mouseenter。我想为此添加自定义事件吗?这是很多工作,必须有一个更容易的解决方案。

1 个答案:

答案 0 :(得分:1)

设置事件聚合器

在Backbone中创建事件聚合器是微不足道的,只有extend事件对象,

window.vent = _.extend({}, Backbone.Events);

我们将事件聚合器vent附加到全局范围,以便任何人都可以收听。

如果您正在使用Marionette,您可以使用Backbone.Wreqr内置的Marionette消息系统中的内置聚合器(注意: Wreqr将被切换为一个新的消息传递API,Radio,从Marionette v.3开始,但我从一个很好的来源得到它,更新管理器应该将所有Wreqr个实例迁移到{{1 }})。

创建事件聚合器是一个调用问题,

Radio

现在为了帮助您解决问题,我们将使用事件聚合器来设置pubsub系统,您的项目视图将订阅一个事件,以帮助他们正确地对滚动作出反应。管理滚动的视图将发布此事件。

注意: window.vent = new Backbone.Wreqr.EventAggregator(); 如果要创建独立的消息传递管道,也可以使用Backbone.Wreqr。查看docs

订阅

所以让我们设置订阅。在项目的视图中执行

Channels

出版

我们刚订阅的活动将在initialize: function () { this.listenTo(vent, "dropdown:before:scroll", function() { this.isScrolling = true; } this.listenTo(vent, "dropdown:end:scroll", function() { this.isScrolling = false; } } 来电之前和之后发布,方法是触发scrollTop上的活动。所以你要像这样重写maxlimit checker,

vent

听取这些事件的项目会知道您正在滚动,因为触发事件是同步,并且会以正确的顺序触发。

防止突出显示

最后,既然您要发布if (currItem > maxItem) { vent.trigger("dropdown:before:scroll"); someElement.scrollTop(); vent.trigger("dropdown:end:scroll"); } 事件并且您的项目正在监听它,那么您确保遇到scrollTop的项目知道何时突出显示。

mouseenter