我正在使用我编写的jQuery插件遇到一些奇怪的行为。基本上,当滚动浏览侧栏所属的博客帖子时,插件会使侧边栏元素粘贴到浏览器窗口的顶部。这应该仅在窗口达到特定大小(768px)或更高时发生(插件通过检查侧边栏的浮动样式来检测到这种情况)。
一切都按预期工作......直到您从大型侧边栏调整浏览器的大小是粘性的 - 小侧边栏不应该是粘性的。我的onResize函数应该会删除滚动事件处理程序,并且只有在startQuery为true时才将其添加回来(因此,如果侧边栏浮点值不是none)。我通过控制台进行了双重和三重检查:就我所知,一切正常。我甚至将console.log('scroll')
添加到onScroll函数中,并且当应该删除事件处理程序时它不显示,但当我滚动浏览博客帖子时,我的侧边栏仍然变粘。
您可以在行动here中看到问题。要重新创建步骤:
这几乎就像删除了事件处理程序,但元素没有更新或其他东西。我确信我遗漏了一些基本的东西,但我已经研究并尝试了$(window).scroll
事件问题的各种修复,但没有一个在这里工作。
我对插件的调用:
$('.share-bar').stickySides({
'wrapper': '.post-wrapper',
'content': '.entry-content' });
插件代码:
;( function ( $, window, document, undefined ) {
var settings;
var throttled;
$.fn.stickySides = function( options ) {
settings = $.extend( {}, $.fn.stickySides.defaults, options );
// Store sidebars
settings.selector = this.selector;
settings.startQuery = '$("' + settings.selector + '").css(\'float\') != \'none\'';
// Create debounced resize function
var debounced = _.debounce( $.fn.stickySides.onResize, settings.wait );
$(window).resize( debounced );
// Create throttled scroll function
throttled = _.throttle( $.fn.stickySides.onScroll, settings.wait );
// Only continue if the start query is true
if ( eval(settings.startQuery) == true ) {
$(window).on( 'scroll.stickySides', throttled );
}
return this;
};
// Define default settings
$.fn.stickySides.defaults = {
wrapper: 'body',
content: '.content',
wait: 100,
startQuery: ''
};
$.fn.stickySides.onResize = function ( ) {
$(window).off( 'scroll.stickySides' );
// Only continue if the start query is true
if ( eval(settings.startQuery) == true ) {
$(window).on( 'scroll.stickySides', throttled );
} else {
var sides = $(settings.selector);
sides.each ( function () {
var elem = $(this);
var content = elem.siblings( settings.content );
if ( elem.css('position') == 'fixed' || elem.css('position') == 'absolute' ) {
elem.css( 'position', 'static' );
}
if ( content.css('margin-left') != '0px' ) {
content.css( 'margin-left', 0 );
}
});
}
};
$.fn.stickySides.onScroll = function ( ) {
console.log('scroll');
var sides = $(settings.selector);
// Check each sidebar
sides.each ( function () {
var elem = $(this);
var content = elem.siblings( settings.content );
var wrapper = elem.closest( settings.wrapper );
var elemHeight = elem.height();
var wrapperHeight = wrapper.height();
// Only continue if the wrapper is taller than the sidebar
if ( elemHeight >= wrapperHeight ) {
return;
} else {
var wrapperFracs = wrapper.fracs(function (fracs) {
// Only continue if the wrapper is in view
if ( fracs.visible == 0 ) {
return;
} else {
// Check if the wrapper extends beyond the top of
// the viewport
var wrapperSpaceTop = fracs.rects.element.top;
// If it does, change sidebar position as appropriate
if ( wrapperSpaceTop > 0 ) {
var visibleWrapper = fracs.rects.document.height;
// If the visible portion of the wrapper is smaller
// than the height of the sidebar...
if ( visibleWrapper <= elemHeight ) {
// ...position the sidebar at the bottom
// of the wrapper
if ( wrapperSpaceTop != 0 ) {
elem.css('position', 'absolute').css( 'top', (wrapperHeight - elemHeight) + content.position().top + 'px' );
}
// Otherwise, move sidebar to appropriate position
} else {
elem.css('position', 'fixed').css('top', 0);
}
content.css('margin-left', elem.outerWidth());
} else {
elem.css('position', 'static');
content.css('margin-left', 0);
}
}
});
}
});
};
} )( jQuery, window, document );
PS:我会使用现有的插件,但我没有看到一个与我需要的功能非常接近的插件;如果你知道一个,请随时指出一个。我还没有在Mac之外测试过。是的,我知道有些页面元素在移动设备上不能很好地流动 - 例如:网站标题&amp;导航 - 还有一些与此问题无关的其他缺失项目。在我解决之前,我正在等待客户的一些反馈。
答案 0 :(得分:1)
每次都会发生。在我寻求帮助后不久,我就自己弄明白了。 ;)
问题出在onScroll函数内的fracs函数中。我没有意识到它称为自己的调整大小/滚动处理程序,所以那些在我删除我的滚动处理程序时没有被绑定。我只是重新设计插件以利用fracs库的处理程序而不是调用我自己的滚动处理程序:
;( function ( $, window, document, undefined ) {
var settings;
var throttled;
$.fn.stickySides = function( options ) {
settings = $.extend( {}, $.fn.stickySides.defaults, options );
// Store sidebars
settings.selector = this.selector;
settings.startQuery = '$("' + settings.selector + '").css(\'float\') != \'none\'';
if ( eval( settings.startQuery ) == true ) {
$.fn.stickySides.doFracs();
}
// Create debounced resize function
var debounced = _.debounce( $.fn.stickySides.onResize, settings.wait );
$(window).resize( debounced );
return this;
};
// Define default settings
$.fn.stickySides.defaults = {
wrapper: 'body',
content: '.content',
wait: 100,
startQuery: ''
};
$.fn.stickySides.doFracs = function ( ) {
var sides = $(settings.selector);
// Check each sidebar
sides.each ( function () {
var elem = $(this);
var content = elem.siblings( settings.content );
var wrapper = elem.closest( settings.wrapper );
var elemHeight = elem.height();
var wrapperHeight = wrapper.height();
// Only continue if the wrapper is taller than the sidebar
if ( elemHeight >= wrapperHeight ) {
return;
} else {
var wrapperFracs = wrapper.fracs( $.fn.stickySides.fracsCallback );
}
});
}
$.fn.stickySides.unbindFracs = function ( ) {
var sides = $(settings.selector);
// Check each sidebar
sides.each ( function () {
var elem = $(this);
var content = elem.siblings( settings.content );
var wrapper = elem.closest( settings.wrapper );
if ( elem.css('position') == 'fixed' || elem.css('position') == 'absolute' ) {
elem.css( 'position', 'static' );
}
if ( content.css('margin-left') != '0px' ) {
content.css( 'margin-left', 0 );
}
wrapper.fracs('unbind');
});
}
$.fn.stickySides.fracsCallback = function ( fracs ) {
// Only continue if the wrapper is in view
if ( fracs.visible == 0 ) {
return;
} else {
var wrapper = $(this);
var elem = wrapper.find(settings.selector);
var content = elem.siblings( settings.content );
var elemHeight = elem.height();
var wrapperHeight = wrapper.height();
// Check if the wrapper extends beyond the top of
// the viewport
var wrapperSpaceTop = fracs.rects.element.top;
// If it does, change sidebar position as appropriate
if ( wrapperSpaceTop > 0 ) {
var visibleWrapper = fracs.rects.document.height;
// If the visible portion of the wrapper is smaller
// than the height of the sidebar...
if ( visibleWrapper <= elemHeight ) {
// ...position the sidebar at the bottom
// of the wrapper
if ( wrapperSpaceTop != 0 ) {
elem.css('position', 'absolute').css( 'top', (wrapperHeight - elemHeight) + content.position().top + 'px' );
}
// Otherwise, move sidebar to appropriate position
} else {
elem.css('position', 'fixed').css('top', 0);
}
content.css('margin-left', elem.outerWidth());
} else {
elem.css('position', 'static');
content.css('margin-left', 0);
}
}
}
$.fn.stickySides.onResize = function ( ) {
// Only continue if the start query is true
if ( eval(settings.startQuery) == true ) {
$.fn.stickySides.doFracs();
} else {
$.fn.stickySides.unbindFracs();
}
};
} )( jQuery, window, document );
瞧!问题解决了。