javascript - 如何将具有绝对位置的div定位在具有相对位置的div中?

标签 javascript jquery html css

在下面的脚本中,我需要能够在类 .cnt 的 div 容器中用绝对值定位类 .infobox 的坐标。

注意:如果可能的话,它应该可以在不为类 .cnt 设置顶部位置的情况下工作。 点击 UP/Down 可以看到 .infobox

http://jsfiddle.net/pg52hsnc/


<!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;
        }
        .infobox {
            position:relative;
            top: 80px;
            height: 50px;
            width: 500px;
            background-color: cyan;
            display: none;
       } 
    </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 class="infobox">info 1</div></div><div id="cnt-2" class="cnt">2<div class="infobox">info 2</div></div><div id="cnt-3" class="cnt">3<div class="infobox">info 3</div></div><div id="cnt-4" class="cnt">4<div class="infobox">info 4</div></div><div id="cnt-5" class="cnt">5<div class="infobox">info 5</div> 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();
                }
            },
            showInfoBox: function (id) {
                this.config.isAnimationOn = true;
                var target = '#cnt-' + id + ' .infobox';
                $(target).slideDown("slow", function () {
                    this.config.isAnimationOn = false;
                }.bind(this));
            },
            hideInfoBox: function (id) {
                this.config.isAnimationOn = true;
                var target = '#cnt-' + id + ' .infobox';
                $(target).slideUp("slow", function () {
                    scroller.config.isAnimationOn = false;
                });
            },
            goUp: function () {

                if (this.config.curPos < 4 && scroller.config.isAnimationOn == false) {
                    scroller.config.isAnimationOn = true;
                    scroller.config.curPos++;
                    if (scroller.config.curPos == 1) {

                        // special case for first row
                        $('#content-scroll-inner').animate({ 'top': '-=50px' }, 500, function () {
                            $('#cnt-' + scroller.config.curPos).animate({ 'height': '+=50px' }, 500);
                            scroller.logicShowHideArrows();
                            scroller.config.isAnimationOn = false;
                            scroller.showInfoBox(scroller.config.curPos);
                        });
                        this.config.incrementOf -= 50;
                        $('#btn-up').show();
                    }
                    else {
                        // normal case
                        $('#content-scroll-inner').animate({ 'top': '-=150px' }, 500, function () {
                            $('#cnt-' + scroller.config.curPos).animate({ 'height': '+=50px' }, 500);
                            scroller.logicShowHideArrows();
                            scroller.config.isAnimationOn = false;
                            scroller.showInfoBox(scroller.config.curPos);
                        });
                        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) {
                        scroller.hideInfoBox(this.config.curPos);
                        $('#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 {
                        scroller.hideInfoBox(this.config.curPos);
                        $('#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>

最佳答案

我能够使用以下代码解决我的问题。我明确地在 .cnt

上添加 position:relative
   .cnt {
        position: relative;
        height: 100px;
        width: 500px;
        background-color: red;
    }

    .infobox {
        position: absolute;
        top: 70px;
        height: 80px;
        width: 500px;
        background-color: cyan;
        display: none;
    }

关于javascript - 如何将具有绝对位置的div定位在具有相对位置的div中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25341419/

相关文章:

html - 如何使用 jekyll 从主页实现 "load more posts"?

javascript - 是否有 JavaScript/jQuery 文件创建事件?

javascript - 如何在 cURL 请求中传递 Javascript 操作

javascript - 单击滚动可滚动 div 内的元素不起作用

html - 在 SVG 路径上添加效果

php - 在 mPDF 上呈现 CSS 的问题 - PHP

javascript - 如何在 6 个数组 Vue 之间移动对象

javascript - Draftjs 中的 block 是什么?

Javascript 发布数组并在服务器端接收它

javascript - 如何区分手动滚动(通过鼠标滚轮/滚动条)与 Javascript/jQuery 滚动?