div中的粘性元素,滚动上的绝对位置

时间:2022-11-18 18:17:34

I have a div with position: absolute and overflow: auto. Inside this div I have a div that should act sticky and should be fixed(top: 0, bottom: 0, overflow: auto) when I scroll.

我有一个位置的div:绝对和溢出:auto。在这个div里面我有一个div应该是粘性的,当我滚动时应该固定(顶部:0,底部:0,溢出:自动)。

I can fix this div, but I can't return it to original position because I can't attached the scroll event when this div is fixed.

我可以修复这个div,但我不能将它返回到原始位置,因为当修复此div时我无法附加滚动事件。

$('.right').scroll(function() {
    if ($('.scroll').offset().top <= 0) {
        $('.scroll').css({
            'position': 'fixed',
            'top': 0,
            'left': '20px',
            'right': '0',
            'overflow': 'auto'
        })
    }
})

Please check my JSFiddle for more info - JSFIDDLE

请查看我的JSFiddle以获取更多信息 - JSFIDDLE

Thank you.

4 个解决方案

#1


9  

Here's how I would do it. This doesn't position it fixed but it has the same appearance. Once scrollTop is equal to or greater than where the top of the fixed content "should be" then we set the top absolutely to that of scrollTop, if you scroll upwards once the scrollTop reaches the point where the fixed content used to be, it will drop it again.

这是我怎么做的。这不是固定的,但外观相同。一旦scrollTop等于或大于固定内容的顶部“应该”的位置,那么我们将topT绝对设置为scrollTop的顶部,如果在scrollTop到达固定内容的位置时向上滚动,它将会再放下它。

$(document).ready(function() {
  oldOffset = $('.scroll').offset().top;
  $('.right').scroll(function() {
    if ($('.right').scrollTop() > oldOffset) {
      $('.scroll').css({
        'position': 'absolute',
        'top': $('.right').scrollTop(),
        'left': '20px',
        'right': '0',
        'overflow': 'auto'
      });
    }
  });
});

(Demo)

#2


1  

Set the outside div to

将外部div设置为

position: relative;

Set the inside div to

将内部div设置为

position: absolute;
top: 15px;
right: 15px;

This will put the top right corner of the inside div at the designated location within the parent container. When setting position absolute, the image is set relative to the first parent container with position defined to anything other than default, I believe. If there is no DOM element assigned a position, the absolute element will be positioned relative to the viewport.

这会将内部div的右上角放在父容器中的指定位置。设置绝对位置时,我相信图像是相对于第一个父容器设置的,其位置定义为默认值以外的任何值。如果没有为元素分配位置,则绝对元素将相对于视口定位。

#3


1  

It is very strange task you want to accomplish :)

你要完成的任务非常奇怪:)

But anyway there is the problem:

但无论如何有问题:

When you set you inner div to position: fixed you positioned this div above your div.right and it is prevents scrolling event from fire.

当你将内部div设置为position:fixed时,你将这个div定位在div.right之上,这样可以防止滚动事件发生火灾。

So what you need is to set pointer-events: none to the div.scroll to allow your div.right listen scroll events without any problems.

所以你需要的是设置指针事件:none到div.scroll以允许你的div.right听滚动事件没有任何问题。

But when you do that you will face another problem - when you set your div.scroll to position: fixed it will lose its place inside the div.right and div.right jumps to the top of the scroll automatically. To prevent that you need to create clone of the div.scroll and set his height to 0 initially, and to auto when your inner element is fixed.

但是,当你这样做时,你将面临另一个问题 - 当你将div.scroll设置为position:fixed它会在div.right中失去它的位置而div.right会自动跳转到滚动的顶部。为了防止你需要创建div.scroll的克隆并最初将其高度设置为0,并在内部元素被修复时自动设置为auto。

Note pointer-events: none - disable all mouse events including the text selection.

注意pointer-events:none - 禁用所有鼠标事件,包括文本选择。

There is the code:

有代码:

JS

$(document).ready(function() {
    var cnt = $('.right');
    var scrollEl = $('.scroll');
    var scrollClone = scrollEl.clone().addClass('clone');
    scrollEl.before(scrollClone);
    cnt.scroll(function() {
        var expression = scrollClone.offset().top <= 0;
        scrollEl.toggleClass('stick', expression);
        scrollClone.toggleClass('stick-clone', expression);
    })
})

CSS

.scroll {
    background: yellow;
    pointer-events: none;
    overflow: hidden; /* Remove top offset from h1*/
}
.scroll.stick {
    position: fixed;
    left: 20px;
    right: 0;
    top: 0;
}
.scroll.clone {
    height: 0;
    overflow: hidden;
}
.scroll.clone.stick-clone {
    height: auto;
}

JSFiddle

#4


0  

You can try the following example:

您可以尝试以下示例:

Firstly, instead of adding the css as inline styles, create a css class that you can add and remove from the .scroll element.

首先,不是将css添加为内联样式,而是创建一个可以在.scroll元素中添加和删除的css类。

CSS

.fixed-top {
    position:fixed;
    top:0;
    left:20px;
    right:20px;
}

Wrap your .scroll element with another div which will be used in the javascript to keep track of the original height of your .scroll div.

将.scroll元素包装在另一个div中,该div将在javascript中用于跟踪.scroll div的原始高度。

HTML

<div class="scroll-wrapper">
    <div class="scroll"></div>
</div>

Lastly, store the scrollTop value in a variable when the fixed position is applied for the first time. You can then use that value to determine when to remove the fixed styles from the .scroll div. Also set the height of the .scroll-wrapper element equal to the height of your .scroll element to make sure the content is scrollable.

最后,在第一次应用固定位置时,将scrollTop值存储在变量中。然后,您可以使用该值来确定何时从.scroll div中删除固定样式。还要将.scroll-wrapper元素的高度设置为等于.scroll元素的高度,以确保内容可滚动。

Javascript

 var startScrollTop = 0;
    $('.right').scroll(function () {
        var $scroll = $('.scroll');
        if ($scroll.offset().top <= 0 && $('.right').scrollTop() > startScrollTop) {
            if (startScrollTop === 0) {
                startScrollTop = $('.right').scrollTop();
            }
             $('.scroll-wrapper').css("height", $('.scroll').height() + 300);
            $scroll.addClass("fixed-top");
        } else {
            $scroll.removeClass("fixed-top");
        }
    })

Take a look at this fiddle. http://jsfiddle.net/a924dcge/25/

看看这个小提琴。 http://jsfiddle.net/a924dcge/25/

Hope that helps!

希望有所帮助!

#1


9  

Here's how I would do it. This doesn't position it fixed but it has the same appearance. Once scrollTop is equal to or greater than where the top of the fixed content "should be" then we set the top absolutely to that of scrollTop, if you scroll upwards once the scrollTop reaches the point where the fixed content used to be, it will drop it again.

这是我怎么做的。这不是固定的,但外观相同。一旦scrollTop等于或大于固定内容的顶部“应该”的位置,那么我们将topT绝对设置为scrollTop的顶部,如果在scrollTop到达固定内容的位置时向上滚动,它将会再放下它。

$(document).ready(function() {
  oldOffset = $('.scroll').offset().top;
  $('.right').scroll(function() {
    if ($('.right').scrollTop() > oldOffset) {
      $('.scroll').css({
        'position': 'absolute',
        'top': $('.right').scrollTop(),
        'left': '20px',
        'right': '0',
        'overflow': 'auto'
      });
    }
  });
});

(Demo)

#2


1  

Set the outside div to

将外部div设置为

position: relative;

Set the inside div to

将内部div设置为

position: absolute;
top: 15px;
right: 15px;

This will put the top right corner of the inside div at the designated location within the parent container. When setting position absolute, the image is set relative to the first parent container with position defined to anything other than default, I believe. If there is no DOM element assigned a position, the absolute element will be positioned relative to the viewport.

这会将内部div的右上角放在父容器中的指定位置。设置绝对位置时,我相信图像是相对于第一个父容器设置的,其位置定义为默认值以外的任何值。如果没有为元素分配位置,则绝对元素将相对于视口定位。

#3


1  

It is very strange task you want to accomplish :)

你要完成的任务非常奇怪:)

But anyway there is the problem:

但无论如何有问题:

When you set you inner div to position: fixed you positioned this div above your div.right and it is prevents scrolling event from fire.

当你将内部div设置为position:fixed时,你将这个div定位在div.right之上,这样可以防止滚动事件发生火灾。

So what you need is to set pointer-events: none to the div.scroll to allow your div.right listen scroll events without any problems.

所以你需要的是设置指针事件:none到div.scroll以允许你的div.right听滚动事件没有任何问题。

But when you do that you will face another problem - when you set your div.scroll to position: fixed it will lose its place inside the div.right and div.right jumps to the top of the scroll automatically. To prevent that you need to create clone of the div.scroll and set his height to 0 initially, and to auto when your inner element is fixed.

但是,当你这样做时,你将面临另一个问题 - 当你将div.scroll设置为position:fixed它会在div.right中失去它的位置而div.right会自动跳转到滚动的顶部。为了防止你需要创建div.scroll的克隆并最初将其高度设置为0,并在内部元素被修复时自动设置为auto。

Note pointer-events: none - disable all mouse events including the text selection.

注意pointer-events:none - 禁用所有鼠标事件,包括文本选择。

There is the code:

有代码:

JS

$(document).ready(function() {
    var cnt = $('.right');
    var scrollEl = $('.scroll');
    var scrollClone = scrollEl.clone().addClass('clone');
    scrollEl.before(scrollClone);
    cnt.scroll(function() {
        var expression = scrollClone.offset().top <= 0;
        scrollEl.toggleClass('stick', expression);
        scrollClone.toggleClass('stick-clone', expression);
    })
})

CSS

.scroll {
    background: yellow;
    pointer-events: none;
    overflow: hidden; /* Remove top offset from h1*/
}
.scroll.stick {
    position: fixed;
    left: 20px;
    right: 0;
    top: 0;
}
.scroll.clone {
    height: 0;
    overflow: hidden;
}
.scroll.clone.stick-clone {
    height: auto;
}

JSFiddle

#4


0  

You can try the following example:

您可以尝试以下示例:

Firstly, instead of adding the css as inline styles, create a css class that you can add and remove from the .scroll element.

首先,不是将css添加为内联样式,而是创建一个可以在.scroll元素中添加和删除的css类。

CSS

.fixed-top {
    position:fixed;
    top:0;
    left:20px;
    right:20px;
}

Wrap your .scroll element with another div which will be used in the javascript to keep track of the original height of your .scroll div.

将.scroll元素包装在另一个div中,该div将在javascript中用于跟踪.scroll div的原始高度。

HTML

<div class="scroll-wrapper">
    <div class="scroll"></div>
</div>

Lastly, store the scrollTop value in a variable when the fixed position is applied for the first time. You can then use that value to determine when to remove the fixed styles from the .scroll div. Also set the height of the .scroll-wrapper element equal to the height of your .scroll element to make sure the content is scrollable.

最后,在第一次应用固定位置时,将scrollTop值存储在变量中。然后,您可以使用该值来确定何时从.scroll div中删除固定样式。还要将.scroll-wrapper元素的高度设置为等于.scroll元素的高度,以确保内容可滚动。

Javascript

 var startScrollTop = 0;
    $('.right').scroll(function () {
        var $scroll = $('.scroll');
        if ($scroll.offset().top <= 0 && $('.right').scrollTop() > startScrollTop) {
            if (startScrollTop === 0) {
                startScrollTop = $('.right').scrollTop();
            }
             $('.scroll-wrapper').css("height", $('.scroll').height() + 300);
            $scroll.addClass("fixed-top");
        } else {
            $scroll.removeClass("fixed-top");
        }
    })

Take a look at this fiddle. http://jsfiddle.net/a924dcge/25/

看看这个小提琴。 http://jsfiddle.net/a924dcge/25/

Hope that helps!

希望有所帮助!