繁体   English   中英

防止在发生滚动事件时将鼠标悬停在元素上

[英]Prevent hover on an element when scrolling event happened

我使用主干/牵线木偶构建了一个下拉小部件,可让您使用键盘在下拉列表中上下导航。 我需要区分选择和突出显示,因此我将布尔值存储在列表项模型的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。 我是否应该为此添加自定义事件? imo要做很多工作,必须有一个更简单的解决方案。

设置事件聚合器

在Backbone中创建事件聚合器很简单,只需extend events对象,

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

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

如果您使用的是Marionette,则可以在Backbone.Wreqr使用内置的聚合器Wreqr内置的Marionette消息传递系统( 注意: Wreqr将从新的消息传递API Radio开始,从Marionette v.3开始,但我有一个很好的消息来源,即更新管理器应将所有Wreqr实例迁移到Radio )。

创建事件聚合器只需调用即可,

window.vent = new Backbone.Wreqr.EventAggregator();

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

注意:如果要创建独立的消息传递管道,也可以使Backbone.Wreqr能够使用Channels 查看文档

订阅

因此,让我们设置订阅。 在项目视图中

initialize: function ()  {
  this.listenTo(vent, "dropdown:before:scroll", function() {
    this.isScrolling = true;
  }
  this.listenTo(vent, "dropdown:end:scroll", function() {
    this.isScrolling = false;
  }
}

出版

通过在vent上触发事件,我们刚刚订阅的事件将在scrollTop调用之前和之后发布。 因此,您需要像这样重写maxlimit检查器,

if (currItem > maxItem) {
  vent.trigger("dropdown:before:scroll");
  someElement.scrollTop();
  vent.trigger("dropdown:end:scroll");
}

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

防止高光

最后,既然您正在发布scrollTop事件,并且您的项目正在监听它,那么请确保遇到mouseenter的项目知道何时突出显示。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM