开发者

Issue with tabbing between form fields when using jQuery custom scrollbars

I'm working on project to provide a bolt-on tool for websites, which makes heavy use of jQuery. Presentation / design is crucial, and I want to replace the standard (ugly) scrollbar applied by the browser to html elements with overflowing content, with something better looking.

There are numerous jQuery plug-ins around that apply custom scrollbars and allow styling via CSS which is great, but all the ones I've tried seem to suffer from the same problem which is this: if the scrollable content contains a form with text fields etc, tabbing between fields does not activate the scrollbar, and in some cases can screw up the custom scrollbar layout altogether.

Two examples of plug-ins I've tried:

http://manos.malihu.gr/jquery-custom-content-scroller http://baijs.nl/tinyscrollbar/

I've tried others also, but in all demos / examples the content is plain text. I've done a lot of searching on this already, but it seems no-one has tried using these plug-ins with form-based content.

All these plug-ins seem to work in more or less the same way, and I can see exactly what happens and why, but just wondered if anyone else has had this problem and / or found a solution?

This issue can be easily replicated as follows (using the tinyscrollbar plug-in):

Add this to a standard html test page -

CSS:

<style>
    #tinyscrollbartest { width: 520px; height: 250px;  padding-right: 20px; background-color: #eee; }
    #tinyscrollbartest .viewport { width: 500px; height: 200px; overflow: hidden; position: relative; }
    #tinyscrollbartest .overview { list-style: none; position: absolute; left: 0; top: 0; }
    #tinyscrollbartest .scrollbar { position: relative; float: right; width: 15px; }
    #tinyscrollbartest .track { background: #d8eefd; height: 100%; width: 13px; position: relative; padding: 0 1px; }
    #tinyscrollbartest .thumb { height: 20px; width: 13px; cursor: pointer; overflow: hidden; position: absolute; top: 0; }
    #tinyscrollbartest .thumb .end { overflow: hidden; height: 5px; width: 13px; }
    #tinyscrollbartest .thumb, #tinyscrollbartest .thumb .end { background-color: #003d5d; }
    #tinyscrollbartest .disable { display: none; }
</style>

Html:

<div id="tinyscrollbartest">
    <div class="scrollbar">
        <div class="track">
            <div class="thumb">
                <div class="end"></div>
            </div>
        </div>
    </div>
    <div class="viewport">
        <div class="overview">
            </p>Here's a text field: <input type="text"/><p>
            ...
            // lots of content to force scrollbar to appear,开发者_StackOverflow中文版
            // and to push the next field out of sight ..
            ...
            <p>Here's another field: <input type="text"/></p>
        </div>
    </div>
</div>

Plug-in reference (assuming jquery libraries etc are referenced also):

<script type="text/javascript" src="scripts/jquery.tinyscrollbar.min.js"></script>

Jquery code:

<script type="text/javascript">
    $(document).ready(function () {
        $('#tinyscrollbartest').tinyscrollbar();
    });
</script>

Now click in the first text field so it has focus, hit the tab key to move to the next one and see what happens.


I understand your problem.. But is hard to find a good solution to this. You could try to set a focus event on your form elements. And let this event trigger the scrollbar_update function of tinyscrollbar. You can set the offsetTop of the form element that currently has focus as the methods parameter. I think that would work.

$('formelements').focus(function(){ YourScrollbar.tinyscrollbar_update(this.offsetTop); });


I had to overwrite the standard tabbing functionality with my own:

  $(".scrollable").each(function() {
    if (!$(this).data("scrollbar"))
    {
      $(this).data("scrollbar", new Scrollbar({
        holder:$(this)
      }));
      $(this).find("input").bind("keydown", function(e) 
      {
        var keyCode = e.keyCode || e.which; 

        if (keyCode == 9) 
        {
          e.preventDefault();

          var scrollTo = $(this);

          if (e.shiftKey) 
          {
            var nextInput = $(this).prevAll("input:not([type=hidden])").first();
            scrollTo = nextInput.prevAll("input:not([type=hidden]), label").first();
          }
          else 
          {
            var nextInput = $(this).nextAll("input:not([type=hidden])").first();
          }

          if (nextInput.length) 

          {
            console.log(scrollTo);
            $(this).closest(".scrollable").data("scrollbar").scrollTo(scrollTo, function()
            {
              nextInput.focus().select();
            });
          }
        }
      }); 
    }
  });

It's a bit annoying to have to wait for the scroll but I don't see any other option.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜