# 为元素实现智能浮动

- Link: https://yjyj.net/learn/1705.html
- Published: 2012-12-09T21:02:37+08:00
- Author: 小 虾

⚡ 生猛大蝦编辑部 · 30 秒核心看点

 * 长文章侧边栏想跟随滚动，核心就是监听 scroll 并切换定位方式。
 * 文中对比了 jQuery 与原生 JS 两类实现，兼顾效果、兼容性和写法复杂度。
 * 实操结论：固定定位最省事，但要注意旧浏览器兼容与元素初始位置计算。

最近想要改造一下[囧客圈](http://jokeoo.com)
 为长文章的侧边栏加入只能浮动的div. 
在网上找到了几种解决办法:

0.显示要加载一下jq库,随便选,国外有用户就用google的,国内有用户就用百度或者新浪的.

1.

    ```decode:true
        <script type="text/javascript">
           $(function() {
               var offset = $("#text-3").offset();
               var topPadding = 15;
               $(window).scroll(function() {
                   if ($(window).scrollTop() > offset.top) {
                       $("#text-3").stop().animate({
                           marginTop: $(window).scrollTop() - offset.top + topPadding
                       });
                   } else {
                       $("#text-3").stop().animate({
                           marginTop: 0
                       });
                   };
               });
           });
       </script>
    ```

2.

    ```decode:true
    $.fn.smartFloat = function() {
        var position = function(element) {
            var top = element.position().top, pos = element.css("position");
            $(window).scroll(function() {
                var scrolls = $(this).scrollTop();
                if (scrolls > top) {
                    if (window.XMLHttpRequest) {
                        element.css({
                            position: "fixed",
                            top: 0
                        });
                    } else {
                        element.css({
                            top: scrolls
                        });
                    }
                }else {
                    element.css({
                        position: "absolute",
                        top: top
                    });
                }
            });
        };
        return $(this).each(function() {
            position($(this));
        });
    };

        $("#float").smartFloat();
    ```

3.
 js:

    ```decode:true
        (function(){
        var oDiv=document.getElementById("float");
        var H=0,iE6;
        var Y=oDiv;
        while(Y){H+=Y.offsetTop;Y=Y.offsetParent};
        iE6=window.ActiveXObject&&!window.XMLHttpRequest;
        if(!iE6){
            window.onscroll=function()
            {
                var s=document.body.scrollTop||document.documentElement.scrollTop;
                if(s>H){oDiv.className="div1 div2";if(iE6){oDiv.style.top=(s-H)+"px";}}
                else{oDiv.className="div1";}    
            };
        }
    })();
    ```

html:

    ```decode:true
    <div id="box">
        <div id="float" class="div1">
            //随滚动移动的部分代码
        </div>
    </div>
    ```

css:

    ```decode:true
    #box{float:left;position:relative;width:295px;}
    .div1{}
    .div2{position:fixed;_position:absolute;top:3px;z-index:295;}
    ```

❓ 延伸问答与排错指南（FAQ）

侧边栏智能浮动最核心的实现思路是什么？

本质是监听页面滚动位置，判断元素是否越过初始阈值；超过后把元素切换为 fixed 或通过
脚本调整 top/marginTop，让它看起来一直跟着页面移动。关键是先算准初始 offset，再处理
回滚时的复位。

jQuery 和原生 JavaScript 方案有什么区别？

jQuery 写法更短，适合快速改造现有页面；原生 JavaScript 依赖更少，适合想减少库依赖
的场景。两者思路一致，都是监听滚动并修改样式，差别主要在代码量、兼容处理和维护成本。

旧浏览器下做浮动效果要注意什么？

要特别注意 fixed 定位兼容性。文章里的做法会判断浏览器能力，兼容不足时改用绝对定位
并动态计算 top，避免浮动模块错位或失效。实际使用时还要确认容器布局不会被浮动打乱。

📚 【[招数学习](https://yjyj.net/category/learn)】专栏延伸阅读与热门精选（[全站文章归档](https://yjyj.net/archive)）：

 * [win2k3+iis下wordpress的伪静态设置httpd.ini](https://yjyj.net/learn/wordpress-learn/1704.html)
 * [终于找到一个能用的WordPress不同分类下的文章使用不同样式的模板](https://yjyj.net/learn/wordpress-learn/1700.html)
 * [Vps时间同步](https://yjyj.net/learn/centos/1753.html)
 * [再次折腾Mysql主主同步配置,方案适合: Mysql5.1x-5.5x](https://yjyj.net/learn/centos/1756.html)
 * 热门必读[斐讯R1升级固件，音质终于得以提升了](https://yjyj.net/learn/5984.html)
 * 热门必读[Shopify Sessions 数据维度表](https://yjyj.net/learn/shopify/7764.html)

## Comments

### By: 我要发芽

- Link: https://yjyj.net/learn/1705.html/comment-page-1#comment-12060
- Published: 2012-12-14T17:36:32+08:00

不懂代码，唉。
