如何在用户使用键盘时禁用鼠标悬停效果?

时间:2014-03-20 14:34:18

标签: javascript

我尝试在您的网站上键入功能时实施搜索。我现在正在前端工作,并使用mockjax来提取假数据。

我的问题:当弹出下拉菜单时,您可以选择重复选择(以黄色突出显示)。我今天意识到,如果您使用箭头键滚动选择并将鼠标移到菜单上,那么它将导致两个选项突出显示!我不想让我的用户感到困惑,所以我只想让它一次突出显示一个。如果他们使用键盘并将鼠标悬停在鼠标上,则键盘选择将跳转到鼠标所在的位置。

(如果我不清楚,你需要一个例子,去亚马逊并用你的箭头键进行搜索,然后将鼠标悬停在一个选项上,它会改变。我想要那样!)

大多数html,css和mockjax都不能包含在这个小提琴中,所以它看起来很时髦 - 但只是有人需要查看我的代码。

http://jsfiddle.net/2JGHu/

(function (Backbone, _, context) {

"use strict";

var SuggestiveSearch = Backbone.View.extend({

    tracking: function (action, label) {

        _gaq.push(['_trackEvent', 'SearchAsYouType2.0', action, label]);
    },

    fetchTemplate: function (name) {

        var callback = _.bind(function (template) {
            this.template = tmpl(template);
        }, this);

        $.get("/js/templates/" + name + ".html", callback);

    },

    close: function () {

        this.$suggestionList.addClass("hide");
        this.tracking('Close', 'Clicked-Off');


        // Reset our list selection index
        this.model.set("currentIndex", null);

    },

    open: function () {

        this.$suggestionList.removeClass("hide");
        this.tracking('Open', 'Clicked-On');

    },

    preventCloseHandler: function (e) {

        e.stopPropagation();

    },

    directionSelectionHandler: function (keyCode) {

        var currentIndex = this.model.get("currentIndex"),
            incr = keyCode === 40 ? 1 : -1,
            newIndex = currentIndex + incr,
            choicesLen = this.$choices.length - 1,
            isOutOfRange = newIndex > choicesLen || newIndex < 0;

        // If index is out of range set it either to the first or last choice
        if (isOutOfRange) {
            newIndex = newIndex < 0 ? choicesLen : 0;
        }

        // Remove previous selected
        // class on li's
        this.$choices
            .removeClass("is-selected");

        this.$choices
            .eq(newIndex)
            .addClass("is-selected");

        // Store our index
        this.model.set("currentIndex", newIndex);


    },


    enterHandler: function (e) {

        var currentIndex = this.model.get("currentIndex");

        if (currentIndex !== 0) {

            this.tracking('Enter', 'Selected-Choice');

            window.location = this.$choices.eq(currentIndex).find("a").attr('href');

        }

    },

    keyDownHandler: function (e) {

        var keyCode = e.which,
            isArrowKeys = keyCode === 40 || keyCode === 38;

        if (!isArrowKeys) {
            return;
        }

        e.preventDefault();

    },

    keyUpHandler: function (e) {

        var $input = $(e.currentTarget),
            query = $input.val(),
            keyCode = e.which;

        switch (keyCode) {
        case 40:
        case 38:
            this.directionSelectionHandler(keyCode);
            this.tracking('Keyboard navigate', 'Selected-Choice');
            e.preventDefault();
            break;
        case 13:
            this.enterHandler(e);
            break;
        default:
            this.model.set("query", query);
        }
    },

    choiceClickHandler: function (e) {

        this.tracking('Click', 'Selected-Choice');

        e.stopPropagation();

    },

    render: function () {

        this.$suggestionList
            .html(this.template(_.pick(this.model.attributes, "ProductSuggestions", "FilterSuggestions")));

        // Store our list of choices but also add our already cached input to that collection
        this.$choices = this.$suggestionList.find(".autocomplete__choice", this.$el).add(this.$input);

        this.open();

    },

    events: {

        "keyup input": "keyUpHandler",
        "keydown input": "keyDownHandler",
        "click .autocomplete__choice": "choiceClickHandler",
        "click": "preventCloseHandler"

    },

    bindings: function () {

        this.listenTo(this.model, "sync", this.render);
        $(document).on('click', _.bind(this.close, this));

    },

    initialize: function () {

        this.fetchTemplate("suggestions");
        this.$suggestionList = this.$el.find(".autocomplete");
        this.$input = this.$el.find("input");
        this.bindings();

    }
});


context.Views = context.Views || {};
context.Views.SuggestiveSearch = SuggestiveSearch;

}(Backbone, _, =|| {}));

如果我需要提供更多信息,请告诉我。提前谢谢!

1 个答案:

答案 0 :(得分:1)

由于你的JSFiddle没有产生这种行为,我编写解决你问题的代码并不容易,但我可以给你一些可以帮助你自己做的建议。

我建议解决此问题的方法是删除CSS中的.hover突出显示并实现一个函数,该函数将一个对象is-selected添加到对象中,并将其从中移除所有其他元素。这样,它将与您当前的directionSelectionHandler:

兼容