javascript - 在 jquery 中滑动元素时出现问题?

标签 javascript jquery html css

我正在尝试开发以下轮播。

http://jsfiddle.net/2kLanjwn/2/

它应该以这种方式工作。

  • 点击向下按钮,轮播滚动和调整大小总是在中心的 div。

我无法在反向应用相同的逻辑,所以当我点击按钮 UP 时,我需要收缩中央 div,然后向上滑动。

请问我做错了什么,如果你能在 jsfiddle 上修复它。 另外我想知道是否有更好的方法来实现相同的效果或可以重复使用的组件。


<!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Scroll text box example</title>
        <style>
            #btn-up, #btn-down {
                position: absolute;
                top: 600px;
            }

            #btn-up {
                left: 0px;
            }

            #btn-down {
                left: 50px;
            }

            #btn-up, #btn-down {
                width: 50px;
                height: 50px;
                background-color: yellow;
                outline: 1px solid black;
            }

            #content-scroll-container {
                position: absolute;
                top: 0;
                left: 0px;
                width: 500px;
                height: 250px; /* MASK HEIGHT real mask would be 200*/
                overflow: hidden;
            }

            #content-scroll-inner {
                position: absolute;
            }

            .cnt {
                height: 100px;
                width: 500px;
                background-color: red;
            }

                .cnt:nth-child(even) {
                    height: 100px;
                    background-color: pink;
                }
        </style>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
        <script>
            var scroller = {
                config: {
                    curPos: 0,              // position
                    canExpand: false,
                    el: 'content-scroll-container',     // visible area (container)
                    elInner: 'content-scroll-inner',    // inner content
                    cntPosY: null,          // content top-left corner (0 position)
                    cntHeight: null,        // content lenght
                    maskHeight: null,       // visible area (rest is masked out)
                    canMoveUp: null,        // true jquery can slide up content
                    canMoveDown: null,      // true jquery can slide down content
                    increment: 100,         // slide of x pixel when user perfom an action
                    incrementOf: 0,         // how much we have slided the contnt
                    animationSpeed: 500,    // jquery animation speed, use 0 for no animation
                    isAnimationOn: false,   // true when jquery is performing animation
                },
                data: '<div id="cnt-0" class="cnt">0</div><div id="cnt-1" class="cnt">1</div><div id="cnt-2" class="cnt">2</div><div id="cnt-3" class="cnt">3</div><div id="cnt-4" class="cnt">4</div><div id="cnt-5" class="cnt">5 empty</div>',
                getCntPosition: function () {
                    // get y position of content
                    var elm = document.getElementById(this.config.elInner);
                    this.config.cntPosY = elm.offsetTop;
                },
                getCntSize: function () {
                    // get height for content
                    var elm = document.getElementById(this.config.elInner);
                    this.config.cntHeight = elm.clientHeight;
                },
                getMaskSize: function () {
                    // get height visible area
                    var elm = document.getElementById(this.config.el);
                    this.config.maskHeight = elm.clientHeight;
                },
                updateData: function () {
                    // refresh state
                    this.getMaskSize();
                    this.getCntPosition();
                    this.getCntSize();
                    this.canMoveUpCheck();
                    this.canMoveDownCheck();
                    //console.clear();
                    console.log(this.config);
                },
                canMoveUpCheck: function () {
                    // set flags allowing sliding up (in case we have enought content to show)
                    var lastScreenY = (this.config.cntHeight - this.config.maskHeight); // last screen visible
                    if ((this.config.incrementOf * -1) < lastScreenY)
                        this.config.canMoveUp = true;
                    else
                        this.config.canMoveUp = false;
                },
                canMoveDownCheck: function () {
                    // set flags allowing sliding down (in case we have enought content to show)
                    if (this.config.cntPosY >= 0)
                        this.config.canMoveDown = false; // cannot move more up if content is on start position (0 position)
                    else
                        this.config.canMoveDown = true;
                },
                goUp: function () {
                    // user want to read previose content
                    //this.updateData();
                    if (this.config.canMoveDown == true && this.config.isAnimationOn == false) {
                        this.moveCnt('down'); // content go down
                    }
                },
                goDown: function () { //**************************
                    // user want to read next content
                    //this.updateData();
                    if (this.config.canMoveUp == true && this.config.isAnimationOn == false) {
                        // check newPos
                        var newPos = this.config.curPos + 1;
                        if (newPos > 0) { // special case
                            if (this.config.canExpand == true)
                                this.config.increment = 150;
                            this.config.canExpand = true;
                            this.moveCnt('up');
                        }



                    }
                },
                moveCnt: function (direction) {
                    // do the actual animation
                    var moveOf;
                    this.isAnimationOn = true;
                    if (direction == 'up') {
                        this.config.curPos++;
                        if (this.config.cntPosY == 0) { // special case for first item
                            moveOf = '-=' + (this.config.increment / 2);
                        }
                        else {
                            moveOf = '-=' + this.config.increment;
                        }
                        var target = '#' + this.config.elInner + ':not(:animated)';
                        $(target).animate({ 'top': moveOf }, this.animationSpeed, this.cbEndAnimation.bind(this, direction));
                    } else if (direction == 'down') {
                        this.config.curPos++;
                        var distanceToFp = (this.config.increment / 2); // height to reach first page (special page)
                        var distanceToFp = 50;
                        if (this.config.cntPosY == (distanceToFp * -1)) {
                            moveOf = '+=' + distanceToFp;
                            // i need to contract only the firs tone
                            $('cnt-1').css({ height: '100px' }, 500, this.cbEndAnimationExpand.bind(this));
                        } else {
                            moveOf = '+=' + this.config.increment;
                        }
                        var target = '#' + this.config.elInner + ':not(:animated)';
                        $(target).animate({ 'top': moveOf }, this.animationSpeed, this.cbEndAnimation.bind(this));

                    }
                    //var target = '#' + this.config.elInner + ':not(:animated)';
                    //$(target).animate({ 'top': moveOf }, this.animationSpeed, this.cbEndAnimation.bind(this, direction));
                },
                cbEndAnimation: function (direction) {
                    // runs when animation end
                    this.config.isAnimationOn = false;
                    if (direction == 'up') {
                        this.config.incrementOf -= this.config.increment;
                        if (this.config.canExpand == true) {    // expand
                            this.logicExpand();
                        } else {
                            // do nothing
                        }
                    }
                    else if (direction == 'down') {
                        this.config.incrementOf += this.config.increment;

                    }
                    this.updateData(); // refresh state has element has just moved
                    this.logicShowHideArrows();
                },
                logicExpand: function () {
                    // take contenf and expand it
                    var elm = document.getElementById('cnt-' + this.config.curPos);
                    $(elm).animate({ height: '150px' }, 500, this.cbEndAnimationExpand.bind(this));
                },
                cbEndAnimationExpand: function () {
                    console.log('end anim expand');
                },
                logicContract: function () {
                    var elm = document.getElementById('cnt-' + this.config.curPos);
                    $(elm).animate({ height: '-=50px' }, 500, this.cbEndAnimationContract.bind(this));
                },
                logicShowHideArrows: function () {
                    // reset first
                    this.hideArrow('btn-up');
                    this.hideArrow('btn-down');
                    if (this.config.canMoveUp == true)
                        this.showArrow('btn-down');
                    if (this.config.canMoveDown == true)
                        this.showArrow('btn-up');
                },
                cbEndAnimationContract: function () {
                    this.config.isAnimationOn = false;
                    this.moveCnt('down'); // content go down
                },
                showArrow: function (elmName) {
                    var elm = document.getElementById(elmName);
                    elm.style.display = '';
                },
                hideArrow: function (elmName) {
                    var elm = document.getElementById(elmName);
                    elm.style.display = 'none';
                },
                setEventHandler: function () {
                    // envet handlers for arrows
                    var btnUp = document.getElementById('btn-up');
                    btnUp.addEventListener('click', this.goUp.bind(this), false);
                    var btnDown = document.getElementById('btn-down');
                    btnDown.addEventListener('click', this.goDown.bind(this), false);
                },
                renderData: function () {
                    // render data content to slide
                    var elm = document.getElementById(this.config.elInner);
                    elm.innerHTML = this.data;
                },
                start: function () {
                    this.renderData();
                    this.updateData();
                    this.setEventHandler();
                    this.logicShowHideArrows(); // at start set arrows visibility
                }
            };
        </script>
    </head>
    <body onload="scroller.start();">
        <div id="content-scroll-container">
            <div id="content-scroll-inner">
            </div>
        </div>
        <div id="btn-up">UP</div>
        <div id="btn-down">DOWN</div>
    </body>
    </html>

最佳答案

我找不到你的代码有什么问题,但我对它做了一些修改,它起作用了。这是代码

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Scroll text box example</title>
    <style>
        #btn-up, #btn-down {
            position: absolute;
            top: 400px;
        }

        #btn-up {
            left: 0px;
        }

        #btn-down {
            left: 50px;
        }

        #btn-up, #btn-down {
            width: 50px;
            height: 50px;
            background-color: yellow;
            outline: 1px solid black;
        }

        #content-scroll-container {
            position: absolute;
            top: 0;
            left: 0px;
            width: 500px;
            height: 250px; /* MASK HEIGHT real mask would be 200*/
            overflow: hidden;
        }

        #content-scroll-inner {
            position: absolute;
        }

        .cnt {
            height: 100px;
            width: 500px;
            background-color: red;
        }

            .cnt:nth-child(even) {
                height: 100px;
                background-color: pink;
            }
    </style>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script>
        var scroller = {
            config: {
                curPos: 0,              // position
                el: 'content-scroll-container',     // visible area (container)
                elInner: 'content-scroll-inner',    // inner content
                cntPosY: null,          // content top-left corner (0 position)
                cntHeight: null,        // content lenght
                maskHeight: null,       // visible area (rest is masked out)
                animationSpeed: 500,    // jquery animation speed, use 0 for no animation
                isAnimationOn: false,   // true when jquery is performing animation
            },
            data: '<div id="cnt-0" class="cnt">0</div><div id="cnt-1" class="cnt">1</div><div id="cnt-2" class="cnt">2</div><div id="cnt-3" class="cnt">3</div><div id="cnt-4" class="cnt">4</div><div id="cnt-5" class="cnt">5 empty</div>',
            getCntPosition: function () {
                // get y position of content
                var elm = document.getElementById(this.config.elInner);
                this.config.cntPosY = elm.offsetTop;
            },
            getCntSize: function () {
                // get height for content
                var elm = document.getElementById(this.config.elInner);
                this.config.cntHeight = elm.clientHeight;
            },
            getMaskSize: function () {
                // get height visible area
                var elm = document.getElementById(this.config.el);
                this.config.maskHeight = elm.clientHeight;
            },
            updateData: function () {
                // refresh state
                this.getMaskSize();
                this.getCntPosition();
                this.getCntSize();
                //console.clear();
                console.log(this.config);
            },
            logicShowHideArrows: function () {
                if(this.config.curPos<1) {
                    $('#btn-up').hide();
                } else {
                    $('#btn-up').show();
                }
                if(this.config.curPos>=4) {
                    $('#btn-down').hide();
                } else {
                    $('#btn-down').show();
                }
            },
            goUp: function () {

                if(this.config.curPos<4 && scroller.config.isAnimationOn ==false) {
                    scroller.config.isAnimationOn = true;
                    scroller.config.curPos++;
                    if(scroller.config.curPos==1) {
                        $('#content-scroll-inner').animate({'top':'-=50px'},500,function(){
                            $('#cnt-'+scroller.config.curPos).animate({'height':'+=50px'},500);
                            scroller.logicShowHideArrows();
                            scroller.config.isAnimationOn = false;
                        });
                        this.config.incrementOf-=50;
                        $('#btn-up').show();
                    }
                    else {
                         $('#content-scroll-inner').animate({'top':'-=150px'},500,function(){
                            $('#cnt-'+scroller.config.curPos).animate({'height':'+=50px'},500);
                            scroller.logicShowHideArrows();
                            scroller.config.isAnimationOn = false;
                        });
                            this.config.incrementOf-=150;
                    }
                    this.updateData();
                } 

            },
            goDown: function () { //**************************
                // user want to read next content
                //this.updateData();
                if(this.config.curPos>0 && scroller.config.isAnimationOn ==false) {
                    scroller.config.isAnimationOn = true;
                    if(this.config.curPos==1) {
                        $('#cnt-'+scroller.config.curPos).animate({'height':'-=50px'},500,function(){
                           $('#content-scroll-inner').animate({'top':'+=50px'},500);
                           scroller.logicShowHideArrows();
                           scroller.config.isAnimationOn = false;
                        });
                        scroller.config.curPos--;
                        this.config.incrementOf+=150;
                        this.updateData();
                    }
                    else {
                        $('#cnt-'+scroller.config.curPos).animate({'height':'-=50px'},500,function(){
                           $('#content-scroll-inner').animate({'top':'+=150px'},500);
                           scroller.logicShowHideArrows();
                           scroller.config.isAnimationOn = false;
                        });
                        scroller.config.curPos--;
                        this.config.incrementOf+=150;
                        this.updateData();
                    }
                }
            },

            setEventHandler: function () {
                $('#btn-up').click(function() {
                    scroller.goDown();
                });
                $('#btn-down').click(function() {
                    scroller.goUp();
                });
            },
            renderData: function () {
                // render data content to slide
                var elm = document.getElementById(this.config.elInner);
                elm.innerHTML = this.data;
            },
            start: function () {
                this.renderData();
                this.updateData();
                this.setEventHandler();
                this.logicShowHideArrows();
            }
        };
    </script>
</head>
<body onload="scroller.start();">
    <div id="content-scroll-container">
        <div id="content-scroll-inner">
        </div>
    </div>
    <div id="btn-up">UP</div>
    <div id="btn-down">DOWN</div>
</body>
</html>

关于javascript - 在 jquery 中滑动元素时出现问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25222335/

相关文章:

html - 我如何将这个 &lt;iframe&gt; 放在网页上

javascript - 将 const 值存储在变量和状态之间有区别吗?

javascript - JQuery 延迟数组,实现不工作

javascript - 延迟文本在背景颜色中的显示和淡化

jquery - 动态添加的输入字段的表单集合问题

html - IE 的菜单 CSS 问题

html - 如何去除 HTML 页面底部的多余空间?

Javascript Jquery 添加样式表 IE

由字符串索引的 Javascript 数组

javascript - 如何在前端应用程序和后端服务器之间共享cookie?