Javascript 触发位置:粘滞时要检测的事件

Javascript 触发位置:粘滞时要检测的事件,javascript,jquery,html,css,position,Javascript,Jquery,Html,Css,Position,我正在使用新的位置:sticky()创建一个类似iOS的内容列表 它工作得很好,远远优于以前的JavaScript替代方案(),但据我所知,在触发它时不会触发任何事件,这意味着与以前的解决方案不同,当该条到达页面顶部时,我无法执行任何操作 当位置:sticky的元素点击页面顶部时,我想添加一个类(例如,卡住了)。有没有一种方法可以用JavaScript来听这个?jQuery的使用很好。在添加了Chrome后位置:sticky,发现它是和。保罗·爱尔兰的“特色是在一个奇怪的边缘状态” 我一直在用,

我正在使用新的
位置:sticky
()创建一个类似iOS的内容列表

它工作得很好,远远优于以前的JavaScript替代方案(),但据我所知,在触发它时不会触发任何事件,这意味着与以前的解决方案不同,当该条到达页面顶部时,我无法执行任何操作


位置:sticky
的元素点击页面顶部时,我想添加一个类(例如,
卡住了
)。有没有一种方法可以用JavaScript来听这个?jQuery的使用很好。

在添加了Chrome后
位置:sticky
,发现它是和。保罗·爱尔兰的“特色是在一个奇怪的边缘状态”

我一直在用,直到它变得非常头痛。它可以很好地工作,但也有一些特殊情况,比如CORS问题,它通过对所有CSS链接执行XHR请求并将其重新划分为浏览器忽略的“position:sticky”声明来减缓页面加载


现在我正在使用,我更喜欢它,因为它不会用包装器弄乱我的布局。

目前没有本机解决方案。看见不过,我有一个CoffeeScript解决方案,它既可以与本机
position:sticky
一起使用,也可以与实现粘性行为的polyfills一起使用

将“粘滞”类添加到要粘滞的元素:

.sticky {
  position: -webkit-sticky;
  position: -moz-sticky;
  position: -ms-sticky;
  position: -o-sticky;
  position: sticky;
  top: 0px;
  z-index: 1;
}
CoffeeScript监控“粘性”元素位置,并在“粘性”状态下添加“卡住”类:

$ -> new StickyMonitor

class StickyMonitor

  SCROLL_ACTION_DELAY: 50

  constructor: ->
    $(window).scroll @scroll_handler if $('.sticky').length > 0

  scroll_handler: =>
    @scroll_timer ||= setTimeout(@scroll_handler_throttled, @SCROLL_ACTION_DELAY)

  scroll_handler_throttled: =>
    @scroll_timer = null
    @toggle_stuck_state_for_sticky_elements()

  toggle_stuck_state_for_sticky_elements: =>
    $('.sticky').each ->
      $(this).toggleClass('stuck', this.getBoundingClientRect().top - parseInt($(this).css('top')) <= 1)
$->新的粘性监视器
类粘滞监视器
滚动\u操作\u延迟:50
构造函数:->
$(窗口)。如果$('.sticky'),则滚动@scroll\u处理程序。长度>0
滚动\u处理程序:=>
@scroll_timer | |=设置超时(@scroll_handler_throttled,@scroll_ACTION_DELAY)
滚动\u处理程序\u已限制:=>
@滚动定时器=空
@为粘滞元素()切换粘滞状态
切换粘滞元素的粘滞状态:=>
$('.sticky')。每个->

$(this).toggleClass('stack',this.getBoundingClientRect().top-parseInt($(this).css('top'))我知道问题提出已经有一段时间了,但我找到了一个很好的解决方案。该插件在支持的地方使用
position:sticky
,并在元素“卡住”时应用一个类。我最近使用它,效果很好,在撰写本文时,它是一个积极的开发(这对我来说是一个优点):)

如果有人通过谷歌来到这里,他们自己的一名工程师有一个使用IntersectionObserver、自定义事件和哨兵的解决方案:


我想出了这个解决方案,它就像一个符咒,而且非常小。:)

不需要额外的元素

它确实在窗口滚动事件上运行,尽管这是一个小缺点

apply_stickies()
addEventListener('scroll',function(){
使用胶粘物()
})
函数apply_stickies(){
var$stickies=[].slice.call(document.querySelectorAll('.sticky'))
_$stickies.forEach(函数($sticky){
if(CSS.supports&&CSS.supports('position','sticky')){
应用粘性类($sticky)
}
})
}
函数apply_sticky_类($sticky){
var currentOffset=$sticky.getBoundingClientRect().top
var stickyOffset=parseInt(getComputedStyle($sticky).top.replace('px','')
var isStuck=currentOffset with(使用技巧):

//获取粘性元素
const stickyElm=document.querySelector('header')
const observer=新的IntersectionObserver(
([e])=>e.target.classList.toggle('isSticky',e.intersectionRatio<1),
{阈值:[1]}
);
观察者观察(粘滞)
正文{高度:200vh;字体:20px Arial;}
部分{
背景:浅蓝色;
填料:2米1米;
}
标题{
位置:粘性;
顶部:-1px;/*➜ 诀窍*/
填充:1em;
填料顶部:计算(1em+1px);/*➜ 补偿*/
背景:鲑鱼;
转换:.1s;
}
/*标题处于粘滞模式时的样式*/
标题:isSticky{
字体大小:.8em;
不透明度:.5;
}
空间

粘性标题
只需使用vanilla JS即可。您可以使用lodash的节流功能来防止某些性能问题

const-element=document.getElementById(“元素id”);
document.addEventListener(
“卷轴”,
_.油门(e=>{
element.classList.toggle(
“是粘的”,

element.offsetTop我发现了一个与@vsync的答案有点类似的解决方案,但它不需要添加到样式表中的“hack”。您只需更改IntersectionObserver的边界,即可避免将元素本身移到视口之外:

const observer = new IntersectionObserver(callback, {
  rootMargin: '-1px 0px 0px 0px',
  threshold: [1],
});

observer.observe(element);

@vsync的优秀答案几乎就是我所需要的,除了我通过Grunt“丑化”我的代码,Grunt需要一些旧的JavaScript代码样式

var stickyElm = document.getElementById('header');
var observer = new IntersectionObserver(function (_ref) {
    var e = _ref[0];
    return e.target.classList.toggle('isSticky', e.intersectionRatio < 1);
}, {
    threshold: [1]
});
observer.observe( stickyElm );

var stickyElm=document.getElementById('header');
var observer=新的IntersectionObserver(函数(_ref){
变量e=_ref[0];
返回e.target.classList.toggle('isSticky',e.intersectionRatio<1);
}, {
阈值:[1]
});
观察者,观察者(stickyElm);

该答案中的CSS保持不变

类似的内容也适用于固定的滚动高度:

//选择标题
const header=document.querySelector('header');
//添加用于滚动的事件侦听器
window.addEventListener('scroll',()=>{
//添加“卡住”类
如果(window.scrollY>=80)navbar.classList.add('stacked');
//移除“卡住”类
else navbar.classList.remove('stacked');
});

这很有趣,因为那篇文章的最高评价正好解决了你的问题。那家伙说得对,这应该是媒体查询,而不是属性。这样你可以在元素卡住时改变样式(我们经常这样做)哦,好吧,男人可以做梦。是的,我注意到了那个评论,他的建议似乎好得多。不过,
位置:sticky
是Chrome实现的,所以我正在寻找一种方法