jq 特效疑问?为啥if else不断重复执行?

图片描述

如题,我想做一个当滚动到头部当前选择元素固定住,然后下来到原来的位置,当前显示

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.js"></script>
    <style>
        html,
        body {
            padding: 0;
        }

        #header {
            line-height: 70px;
            text-align: center;
            background-color: red;
        }

        #nav {
            height: 30px;
            margin-top: 20px;
            background-color: blue;
        }

        #wrap {
            height: 1200px;
            background-color: #ccc;
            padding: 10px;
            padding-right: 20px;
        }

        #wrap .aside {
            float: left;
            width: 100px;
            height: 400px;
            background-color: green;
            float: left;
        }

        #wrap .main {
            background-color: white;
            overflow: hidden;
            height: 100%;
        }

        #footer {
            height: 30px;
            background-color: black;
            color: green;
        }
    </style>
</head>

<body>
    <div id="header">header</div>
    <div id="nav">nav</div>
    <div id="wrap">
        <div class="aside">aside</div>
        <div class="main">main</div>
    </div>
    <div id="footer">footer</div>
    <script>
        var this1;
        $.fn.stick = function () {
            this1 = this;
            $(window).on('scroll', function () {
                var wintop = $(window).scrollTop();
                if(wintop>=objtop){
                    console.log(1);
                    if(!this1.attr('inx')){
                        this1.hide();
                        cloneself.css({
                            'display': 'block',
                             'opacity': '1',
                             'position':'fixed',
                             'top':0,
                             'margin':0
                        })
                    }
                    this1.attr('inx','true');
                    return;
                }else{
                    if(!this1.attr('inx')){
                        return;
                    }else{
                        console.log(2);
                        cloneself.hide();
                        this1.show();
                        this1.removeAttr('inx');
                        return;
                    }
                }
                       
            })
        }
        $('#nav').stick();
        var objtop = $(this1).offset().top;
        var objwidth = $(this1).width();
        var objheight = $(this1).height();
        var cloneself = $(this1).clone();
        cloneself.css({
            'display': 'none',
            'opacity': '0',
            'width': objwidth,
            'height': objheight
        })
        cloneself.insertBefore(this1);
    </script>
</body>

</html>

出现这个if else永远在同时执行的bug,不是if else只执行一次吗。为什么会出现这个bug?

如果我把代码修改成这样,就不会有这个问题。这是啥情况?

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.js"></script>
    <style>
        html,
        body {
            padding: 0;
        }

        #header {
            line-height: 70px;
            text-align: center;
            background-color: red;
        }

        #nav {
            height: 30px;
            margin-top: 20px;
            background-color: blue;
        }

        #wrap {
            height: 1200px;
            background-color: #ccc;
            padding: 10px;
            padding-right: 20px;
        }

        #wrap .aside {
            float: left;
            width: 100px;
            height: 400px;
            background-color: green;
            float: left;
        }

        #wrap .main {
            background-color: white;
            overflow: hidden;
            height: 100%;
        }

        #footer {
            height: 30px;
            background-color: black;
            color: green;
        }
    </style>
</head>

<body>
    <div id="header">header</div>
    <div id="nav">nav</div>
    <div id="wrap">
        <div class="aside">aside</div>
        <div class="main">main</div>
    </div>
    <div id="footer">footer</div>
    <script>
        var this1;
        $.fn.stick = function () {
            this1 = this;
            $(window).on('scroll', function () {
                var wintop = $(window).scrollTop();
                if(wintop>=objtop){
                    console.log(1);
                    
                   
                }else{
                    console.log(2);
                }
                       
            })
        }
        $('#nav').stick();
        var objtop = $(this1).offset().top;
        var objwidth = $(this1).width();
        var objheight = $(this1).height();
        var cloneself = $(this1).clone();
        cloneself.css({
            'display': 'none',
            'opacity': '0',
            'width': objwidth,
            'height': objheight
        })
        cloneself.insertBefore(this1);
    </script>
</body>

</html>

------------------------已经解决,当滚动距离小于当前元素的的top值得时候,我直接remove掉了这个style,然后在恢复初始值,这样就好了

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.js"></script>
    <style>
        html,
        body {
            padding: 0;
        }

        #header {
            line-height: 70px;
            text-align: center;
            background-color: red;
        }

        #nav {
            height: 30px;
            margin-top: 20px;
            background-color: blue;
        }

        #wrap {
            height: 1200px;
            background-color: #ccc;
            padding: 10px;
            padding-right: 20px;
        }

        #wrap .aside {
            float: left;
            width: 100px;
            height: 400px;
            background-color: green;
            float: left;
        }

        #wrap .main {
            background-color: white;
            overflow: hidden;
            height: 100%;
        }

        #footer {
            height: 30px;
            background-color: black;
            color: green;
        }
    </style>
</head>

<body>
    <div id="header">header</div>
    <div id="nav">nav</div>
    <div id="wrap">
        <div class="aside">aside</div>
        <div class="main">main</div>
    </div>
    <div id="footer">footer</div>
    <script>
        var this1;
        $.fn.stick = function () {
            this1 = this;
            $(window).on('scroll', function () {
                var wintop = $(window).scrollTop();

                if (wintop >= objtop) {
                    if (!this1.attr('inx')) {
                        this1.hide();
                        cloneself.css({
                            'display': 'block',
                            'opacity': '1',
                            'position': 'fixed',
                            'width': objwidth,
                            'height': objheight,
                            'top': 0,
                            'margin': 0
                        })
                    }
                    this1.attr('inx', 'true');
                    return;
                } else {
                    if (!this1.attr('inx')) {
                        return;
                    } else {
                        cloneself.removeAttr('style')
                        cloneself.css({
                            'display': 'none',
                            'opacity': '0',
                        })
                        this1.show();
                        this1.removeAttr('inx');
                        return;
                    }
                }

            })
        }
        $('#nav').stick();
        var objtop = $(this1).offset().top;
        var objleft = $(this1).offset().left;
        var objwidth = $(this1).width();
        var objheight = $(this1).height();
        var cloneself = $(this1).clone();
        cloneself.css({
            'display': 'none',
            'opacity': '0',
        })
        cloneself.insertBefore(this1);
    </script>
</body>

</html>
阅读 3.4k
6 个回答

你没有看到滚动条在一直动吗。你使用的页面布局方式,当该元素显示的时候会导致滚动条移动,所以滚动事件会不断触发。

两种解决办法,一种是调整页面布局,二是在js中判断,忽略由隐藏到显示这个状态改变带来的突发滚动。

$(window).on('scroll', function (){}

滚动条滚动事件 ,你一直在滚动呀

触发了滚动事件

  1. 绑定了 scroll事件,每次滚动都会触发,
  2. 触发滚动便会产生判断,打印 1

scroll是个高频事件,发生时会短时间内不断触发,jQ在这里只是帮你把兼容封装了一下(MDN的scroll事件介绍里有兼容性相关的东西),事件的防抖需要你自己去做。
另外下次如果碰到类似情况,事件里加debugger;语句打断点单步跟一遍流程,你加console.log('1');一般只能是(粗略)判断有没有执行到这个分支,具体逻辑是帮不上忙的。

楼上说的都是对的,你这个绑定了scroll 每次滚动都会触发

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题