4

Its a wierd bug and it was hard to figure out.

We create a map application and there is a select element on a pop-up. It has size attribute setted. The parent of select element has overflow:auto style. When scroll is appered, trying to select something on select element scrolls body down. But body has overflow:hidden style and it kills us.

Here is two fiddles i created:

http://jsfiddle.net/e6BK3/1/

http://jsfiddle.net/e6BK3/8/

Try to select first option on select element when its not focused on google chrome. Then see it scrolls all parent elements avalibale to scroll.

Google Chrome Version : 34.0.1847.131

5
  • You can apply overflow:scroll; when mouse is hovered at the element, otherwise overflow:hidden; Commented May 14, 2014 at 3:57
  • It doesn't matter if it's overflow:hiddeon or overflow:scroll. There are two fiddles for both values. But the result is same. Commented May 14, 2014 at 12:03
  • I'm not sure what behavior you're classifying as a bug. The parent element is too small to contain the entire select element. If Chrome didn't scroll the parent element, only half of the options would ever be visible. You want to prevent Chrome from trying to display the entire select element? Commented May 15, 2014 at 20:23
  • No, i want Google chrome to prevent scroll all parent elements. If you have a look at fiddles carefully, it scrolls all parent elements. It does behave same while overflow property is hidden. Commented May 18, 2014 at 13:26
  • Also when it scrolls, it select a different option than I try to select Commented May 18, 2014 at 13:27

2 Answers 2

2
+50

I think I did it! :)

The point is to prevent any other propagation on the option tag mousedown event, and manage manually the focusing of the select box.

See the jsFiddle

I tried to make it as clear as I can :

$('option')
.on('mousedown', function(e){
    // Prevent any other propagations
    e.stopImmediatePropagation();

    // Focus on the select DOM element
    // but saving the scrollTop of each parent before
    $(this)
    .parents()
    .filter(function(){
        // filter only those which have a scroll visible
        return $(this)[0].scrollHeight > $(this)[0].clientHeight;
    })
    .each(function(_,elt){
        // and for each, save the scroll value in data set
        $(elt).data('saveScroll', $(elt).scrollTop());
    })

    // Then trigger the focus option of the select DOM element
    // And finally the custom 'scrollback' event
    $(this).parent('select')
    .trigger('focus')
    .trigger('scrollback');

});

$('select')
// This customized event is for getting back the value of the scroll of all parents
// only if this value exists
.on('scrollback'
    , function(e){
        $(this)
        .parents()
        .filter(function(){
            // filter only those which have this data in data-set
            return 0 === $(this).data('saveScroll') || ~~$(this).data('saveScroll');
        })
        .each(function(_,elt){
            // and for each, putting back the right scroll value
            $(elt).scrollTop($(elt).data('saveScroll'));
            $(elt).removeData('saveScroll');
        })
    });

This is probably not perfect because it is a hack.

At least it even worked with multiple-typed select. And it is cross-browser compliant.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for your answer, it works for all elements but body. Body still scrolls while it has overflow:hidden style. Any idea on this? I'll accept your answer, but waiting if any other comes.
If you click outside the select, why does the select remain focused?
@paulalexandru: because it does not ;)
Actually i solved my problem. I used your code. But for body element, i found the element causes body to oveflow, and changed it's 'display' to 'none', than back to 'block'. It caused the body element to scrolltop. Its complicated to tell :) Thanks for your answer.
@HalilIbrahim: Sometimes, simpler things are the hardest to implement. that's why it's funny! Good if your pb is solved. Do not forget to 'check' me!
2

If you want to achieve this in google chrome all you have to do is to:

  • Load jQuery in you project (probably you already did)
  • Put this code into your CSS

CSS:

select:focus {
    outline: 0;
}

Put this code into your javascript:

$('.innder-div').on('scroll', function() {
    $(this).scrollTop(0);     
})

$('.root').on('scroll', function() {
    $(this).scrollTop(0);     
})

$('select').on('mouseover', function(){
    $(this).focus();
})

Jsfiddle here

Update: Another solution is to use middle click (wheel button) before the left click on the select box and all will work as normal. So the solution is to use javascript to detect the first click and trigger the middle button click before it and only after that the mouse left button.

3 Comments

With your solution, the user cannot scroll at all (I mean 'on purpose') and most of the select box is definitely hidden. :(
Actually i hoped the soulution would be short as yours, but it prevents scrolling totaly.
I've scroll visible and hidden elements as parent in my stuation. I upvoted your answer, yes it solves overflow:hidden stuation. Thanks again for answering, its really short.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.