简体   繁体   English

从外部div滚动div

[英]Scrolling a div from an outer div

Check out the small html structure sample below for context. 查看下面的小型html结构示例以获取上下文。 Check out this fiddle for and example of the problem. 查看此小提琴以获取问题的示例。

Short explanation for fiddle users: 小提琴用户的简短说明:

  1. Scroll left - vertical scroll bar not visible 向左滚动-垂直滚动条不可见
  2. Scroll right - vertical visible 向右滚动-垂直可见
  3. I want the vertical scroll bar always visible 我希望垂直滚动条始终可见
  4. Requirement - The header must remain fixed (visible while scrolling) 要求-标头必须保持固定(滚动时可见)

Long explanation: 详细说明:

I have a table with a fixed header and a scrollable body. 我有一个带有固定标题和可滚动主体的表。 The complexities of that requires two tables. 复杂性需要两个表。 That's all good. 很好 In my cause I also have resizable columns. 由于我的原因,我也有可调整大小的列。 table-layout: fixed for that to work. table-layout: fixed为工作。 This is were problems arise. 这是出现问题的地方。

To make the scrolling body work I've got a div that wraps the .rows table for scrolling. 为了使滚动体起作用,我有一个div,该div包装了.rows表以进行滚动。 This works great until the grid, specifically the .rows table, overflows in the x direction. 直到网格(特别是.rows表)在x方向上溢出之前,这一直有效。 In this case the the vertical scroll bar is only visible if the grid is scrolled all the way to the right. 在这种情况下,垂直滚动条仅在网格一直向右滚动时才可见。 Because the scroll bar is on the .row-wrapper div. 因为滚动条位于.row-wrapper div上。 And that overflow is being hidden by the .grid div. .grid div隐藏了该.grid I'd like the scrollbar to be on the .grid-canvas div so that it is visible even when scrolled to the left side. 我希望滚动条位于.grid-canvas div上,以便即使滚动到左侧也可以看到。

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

side note: If you set the table display to block then the wrapping div isn't needed unless you want to support IE8 which I do. 旁注:如果将表显示设置为阻止,则不需要包装div,除非您想支持IE8。 Maybe there's a way around that but that another question for another time. 也许有办法解决这个问题,但这又是另一个问题。

Well after hours of hacking with no luck I decided to disect some of the existing libraries to see how they were accomplishing this. 在经过数小时的黑客攻击后,我决定剖析一些现有的库,看看它们是如何实现的。 Unfortunately I was sorely disappointed. 不幸的是我感到非常失望。 All of them were using javascript. 他们所有人都使用javascript。

The up side to this is that the it only requires a small bit of code not that that means it will perform well. 有利的一面是,它只需要一小段代码,并不意味着它将运行良好。 To make this perform as well as possible I'm updating the header when required in the x direction. 为了使它尽可能地执行,我需要在x方向上更新标头。 Since this will typically be a small area in my case it should be good enough. 因为在我看来,这通常是一个很小的区域,所以它应该足够好。

Hundredth times a charm! 百倍魅力!

fiddle 小提琴

Here's the basic: 基本内容如下:

HTML 的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 Java脚本

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

CSS 的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;
}

What about this one, If you want to use javascript/jQuery ? 那如果您想使用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 demo 现场演示

Sorry, i forgot from where i got it. 对不起,我忘了从哪里买的。 but special thanks to him/her. 但要特别感谢他/她。 And also the author ie Jonas Mosbech. 还有作者乔纳斯·莫斯贝克(Jonas Mosbech)。 Hope, it will helps you. 希望对您有帮助。 Thanks. 谢谢。 !! !!

i edited your css and guess this is what you want: 我编辑了您的CSS,并猜测这是您想要的:

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM