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

时间:2014-08-09 19:39:04

标签: javascript jquery html css

我正在尝试开发以下旋转木马。

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

它应该以这种方式工作。

  • 点击按钮DOWN,轮播滚动并调整中心的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>

1 个答案:

答案 0 :(得分:1)

我无法找到代码中的错误,但我对其进行了一些更改,并且有效。这是代码

<!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>