سؤال

I am working with the JQuery UI autocomplete 1.8 with JQuery 1.6.1. (Getting newer versions of software is extremely difficult in my company so I am stuck with these.)

I have a long list of strings placed in the autocomplete pane, so I styled the .ui-autocomplete class like this

.ui-autocomplete {height:200px; overflow-y:scroll; overflow-x: hidden;}

Now when the autocomplete dropdown pops up it, it has a scroll bar as desired. However, when I use arrow keys to navigate the dropdown, the panel does not scroll with the selection. The selections still happen. Eventually I run off the bottom of the list and the cursor is returned to the top. Everything behaves as expected except that the scroll pane does not scroll.

In tests outside of work where I have access to other browsers, I find that chrome scrolls properly and IE 8 scrolls properly. Is this a bug with the firefox 3.6 linux browser or am I missing something?

I am handcuffed to Firefox 3.6 ua:(Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv1.9.2.12) Gecko/20101026 Firefox/3.6.1.2)

Is this a bug with this version of the browser or am I missing something?

EDIT: I was able to find a machine with ie6 and one with firefox 3.5.3. ie6 scrolled and firefox 3.5.3 did not. It appears it might be an issue with firefox.

هل كانت مفيدة؟

المحلول

I had similar issue with our app running on jQuery v1.7.2 and jQuery UI v1.8.11 on any browser. However I have found out that it was fixed on jQuery UI v1.8.13 changelog.

So according to the fix in the changeset, all I did was just override two functions as below and it fixes the issue.

$.widget("ui.menu", $.extend({ }, $.ui.menu.prototype, {
activate: function (event, item) {
    this.deactivate();
    if (this.hasScroll()) {
        var offset = item.offset().top - this.element.offset().top,
            scroll = this.element.scrollTop(),
            elementHeight = this.element.height();
        if (offset < 0) {
            this.element.scrollTop(scroll + offset);
        } else if (offset >= elementHeight) {
            this.element.scrollTop(scroll + offset - elementHeight + item.height());
        }
    }
    this.active = item.eq(0)
                      .children("a")
                      .addClass("ui-state-hover")
                      .attr("id", "ui-active-menuitem")
                      .end();
    this._trigger("focus", event, { item: item });
},

hasScroll: function () {
    return this.element.height() < this.element[$.fn.prop ? "prop" : "attr"]("scrollHeight");
}}));

نصائح أخرى

Solution: Upgrading to jQuery UI 1.8.18 fixed this problem for me.

This isn't an answer but it might provide more information on the issue. If you follow the calls when you press the up or down keys when the menu is open, you get to the activate method of the menu widget which calls the hasScroll method (Line 5487 using v1.8.11);

hasScroll: function() {
    return this.element.height() < this.element.attr("scrollHeight");
},

It seems like the problem is that the scrollHeight attribute is not defined for the menu ul element and thus this method always returns false.

Here is the activate method:

activate: function( event, item ) {
        this.deactivate();
        if (this.hasScroll()) {
            var offset = item.offset().top - this.element.offset().top,
                scroll = this.element.attr("scrollTop"),
                elementHeight = this.element.height();
            if (offset < 0) {
                this.element.attr("scrollTop", scroll + offset);
            } else if (offset >= elementHeight) {
                this.element.attr("scrollTop", scroll + offset - elementHeight + item.height());
            }
        }
        this.active = item.eq(0)
            .children("a")
                .addClass("ui-state-hover")
                .attr("id", "ui-active-menuitem")
            .end();
        this._trigger("focus", event, { item: item });
    }

Even if you force the hasScroll method to return true, you run into another problem as the scrollTop attribute is not defined either.

I'll let you know if I figure out a solution to this as it is plaguing my application as well.

I noticed that this.element.attr("scrollHeight") in

hasScroll: function () {
        return this.element.height() < this.element.attr("scrollHeight");
    },

returns undefined. If you change this.element.attr("scrollHeight") to this.element.prop("scrollHeight") instead, you will get a scrollHeight.

But then the same problem appears in activate: function (event, item) {, so you will also need to change all occurrences of

this.element.attr("scrollTop") to this.element.prop("scrollTop")

in that function as well to make it work.

You can read about .prop() in the jQuery API but basically the reason for this is

Before jQuery 1.6, the .attr() method sometimes took property values into account when retrieving some attributes, which could cause inconsistent behavior. As of jQuery 1.6, the .prop() method provides a way to explicitly retrieve property values, while .attr() retrieves attributes.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top