Scrolling a div from an external div

Check out the small html structure example below for context. See the fiddle and problem example.

Short description of script users:

  • Scroll left - vertical scroll bar not visible
  • Scroll Right - Vertical Visibility
  • I want the vertical scrollbar to always be visible.
  • Demand. The title should remain fixed (visible when scrolling).

Long explanation:

I have a table with a fixed header and a scrollable body. The complexity of this requires two tables. This is all good. In my case, I also have resizable columns. table-layout: fixed for this. These were the problems.

To do the scrolling work, I have a div that wraps the .rows table to scroll. This works fine until the grid, in particular the .rows table, overflows in the x direction. In this case, the vertical scroll bar is visible only if the grid scrolls all the way to the right. Since the scrollbar is on a div .row-wrapper . And this overflow is hiding with a .grid div. I would like the scroll bar to be on the .grid-canvas div so that it is visible even when scrolling to the left.

 <div class=grid> <div class=grid-canvas> <table class=header></table> <div class=row-wrapper> <table class=rows></table> </div> </div> </div> 

Note: if you set the table mapping to lock, then the wrapper div is not needed if you do not want to support IE8, which I am doing. Maybe there is a way around this, but this is another question at a different time.

+4
source share
3 answers

Well, after several hours of hacking with no luck, I decided to disconnect some of the existing libraries to see how they do it. Unfortunately, I was very disappointed. They all used javascript.

Aside from this, it only requires a small bit of code, which does not mean that it will work well. To do this as best as possible, I update the header when necessary in the x direction. Since this is usually a small area in my case, it should be good enough.

Hundreds of times lovely!

fiddle

Here's the main one:

HTML

 <div class=grid> <div class=grid-canvas> <div class=header-wrapper> <table class=header></table> </div> <div class=row-wrapper> <table class=rows></table> </div> </div> </div> 

Javascript

 $headerDiv = $('.header-wrapper'); $rowDiv = $('.row-wrapper'); $rowDiv.scroll(function(e) { $headerDiv.css({ left: -$rowDiv[0].scrollLeft + 'px' }); });​ 

CSS

 .grid { height: 500px; width: 350px; } .grid-canvas { position: relative; width: 100%; height: 100%; overflow: hidden; } .header-wrapper { position: absolute; top: 0; width: auto; background-color: white; z-index: 1; } .row-wrapper { position: absolute; top: 0; height: 100%; width: 100%; box-sizing: border-box; -moz-box-sizing: border-box; overflow: auto; padding-top: 18px; background-color: lightgreen; } th, td { width: 80px; min-width: 80px; max-width: 80px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } 

+2
source

How about this if you want to use javascript / jQuery?

 $(function(){ $("table").stickyTableHeaders(); }); /*! Copyright (c) 2011 by Jonas Mosbech - https://github.com/jmosbech/StickyTableHeaders MIT license info: https://github.com/jmosbech/StickyTableHeaders/blob/master/license.txt */ ;(function ($, window, undefined) { 'use strict'; var pluginName = 'stickyTableHeaders'; var defaults = { fixedOffset: 0 }; function Plugin (el, options) { // To avoid scope issues, use 'base' instead of 'this' // to reference this class from internal events and functions. var base = this; // Access to jQuery and DOM versions of element base.$el = $(el); base.el = el; // Cache DOM refs for performance reasons base.$window = $(window); base.$clonedHeader = null; base.$originalHeader = null; // Keep track of state base.isCloneVisible = false; base.leftOffset = null; base.topOffset = null; base.init = function () { base.options = $.extend({}, defaults, options); base.$el.each(function () { var $this = $(this); // remove padding on <table> to fix issue #7 $this.css('padding', 0); $this.wrap('<div class="divTableWithFloatingHeader"></div>'); base.$originalHeader = $('thead:first', this); base.$clonedHeader = base.$originalHeader.clone(); base.$clonedHeader.addClass('tableFloatingHeader'); base.$clonedHeader.css({ 'position': 'fixed', 'top': 0, 'z-index': 1, // #18: opacity bug 'display': 'none' }); base.$originalHeader.addClass('tableFloatingHeaderOriginal'); base.$originalHeader.after(base.$clonedHeader); // enabling support for jquery.tablesorter plugin // forward clicks on clone to original $('th', base.$clonedHeader).click(function (e) { var index = $('th', base.$clonedHeader).index(this); $('th', base.$originalHeader).eq(index).click(); }); $this.bind('sortEnd', base.updateWidth); }); base.updateWidth(); base.toggleHeaders(); base.$window.scroll(base.toggleHeaders); base.$window.resize(base.toggleHeaders); base.$window.resize(base.updateWidth); }; base.toggleHeaders = function () { base.$el.each(function () { var $this = $(this); var newTopOffset = isNaN(base.options.fixedOffset) ? base.options.fixedOffset.height() : base.options.fixedOffset; var offset = $this.offset(); var scrollTop = base.$window.scrollTop() + newTopOffset; var scrollLeft = base.$window.scrollLeft(); if ((scrollTop > offset.top) && (scrollTop < offset.top + $this.height())) { var newLeft = offset.left - scrollLeft; if (base.isCloneVisible && (newLeft === base.leftOffset) && (newTopOffset === base.topOffset)) { return; } base.$clonedHeader.css({ 'top': newTopOffset, 'margin-top': 0, 'left': newLeft, 'display': 'block' }); base.$originalHeader.css('visibility', 'hidden'); base.isCloneVisible = true; base.leftOffset = newLeft; base.topOffset = newTopOffset; } else if (base.isCloneVisible) { base.$clonedHeader.css('display', 'none'); base.$originalHeader.css('visibility', 'visible'); base.isCloneVisible = false; } }); }; base.updateWidth = function () { // Copy cell widths and classes from original header $('th', base.$clonedHeader).each(function (index) { var $this = $(this); var $origCell = $('th', base.$originalHeader).eq(index); this.className = $origCell.attr('class') || ''; $this.css('width', $origCell.width()); }); // Copy row width from whole table base.$clonedHeader.css('width', base.$originalHeader.width()); }; // Run initializer base.init(); } // A really lightweight plugin wrapper around the constructor, // preventing against multiple instantiations $.fn[pluginName] = function ( options ) { return this.each(function () { if (!$.data(this, 'plugin_' + pluginName)) { $.data(this, 'plugin_' + pluginName, new Plugin( this, options )); } }); }; })(jQuery, window); 

live demonstration

Sorry, I forgot where I came from. but special thanks to him. Also by ie Jonas Mosbech. Hope this helps you. Thank you. !!

+1
source

I edited your css and think this is what you want:

 table { table-layout: fixed; } th, td { width: 80px; min-width: 80px; max-width: 80px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .grid { height: 500px; width: 350px; overflow-x: auto; overflow-y: scroll; } .grid-canvas { position: relative; width: 100%; height: 100%; } .header { position: absolute; top: 0; background-color: white; z-index: 10; } .row-wrapper { position: absolute; top: 0; width: auto; height: auto; /* assumed height of the header */ padding-top: 18px; box-sizing: border-box; -moz-box-sizing: border-box; background-color: lightgreen; } 
-1
source

All Articles