【问题标题】:Left/Top overflow with scrollbars带有滚动条的左/上溢出
【发布时间】:2020-05-20 06:52:26
【问题描述】:

我正在使用transform: tranxlate(x, y) css 属性将我的元素定位在容器内。

当我将元素移动到右侧或底部时 - 出现滚动条是因为容器有 overflow: auto;。但是,如果我将元素移动到左侧或顶部 - 显然滚动条不会出现,因为溢出不起作用。

现在我正在寻找一些带有纯 html/js/css 的简约方法,以便能够滚动容器,记住内部内容可能会随机移动到任何一侧。

简而言之,如果黄色块超出左边缘,我希望滚动条出现,就像它在右边缘出现时一样?

这是一个Codepen example,它显示了问题。

var btns = document.querySelectorAll('button');
var inner = document.querySelector('.inner');
var offset = 0;

btns[0].addEventListener('click', function() {
  offset -= 25;
  inner.style.transform = `translate(${offset}px, 0px)`;
});

btns[1].addEventListener('click', function() {
  offset += 25;
  inner.style.transform = `translate(${offset}px, 0px)`;
});
button {
  margin: 0 auto;
  display: block;
}

.outer {
  outline: 1px dashed black;
  margin: 0 auto;
  width: 200px;
  height: 200px;
  overflow: auto;
}

.inner {
  width: 100px;
  height: 100px;
  background: yellow;
}
<button>Move Left</button>
<button>Move Right</button>

<div class="outer">
  <div class="inner"></div>
</div>

【问题讨论】:

  • 我不明白,你想总是显示滚动条还是从不显示滚动条?这里的问题到底是什么?另外,您能否在问题中而不是在 StackOverflow 之外的站点中提供可运行的 sn-p?
  • 您的询问不清楚,但如果右侧交叉元素,您可以实现一个条件,避免进入右侧站点或最大右侧站点相等值
  • 对不起,我正在做一些更大的事情,所以这只是一个非常简单的例子——这就是为什么它可能不容易理解的原因。但是想象一下在画布内移动的对象,如果有任何边界越界,我需要显示滚动条。
  • 那么,简而言之,您的问题是什么?你不需要解释你的整个项目,只需要解释你面临的问题。如果我理解正确,您希望滚动条在黄色块超出左边缘时出现,就像它在右边缘时出现的方式一样?
  • 是的@CalvinNunes 完全正确

标签: javascript html css scrollbar overflow


【解决方案1】:

也许这有帮助...考虑到偏移滚动不能为负数;你只能从 0 到无穷大(我想哈哈);然后,您可以通过 left 和 top 负值移动元素,但它不允许您滚动到。因此,您可以根据用户要求增加宽度和高度,并将相同的值滚动到用户移动的反方向,这将显示滚动能够进入这些现在不可用的位置(负滚动)的效果。当您返回时,您必须反转增强,当增强为空时,您可以根据需要移动元素。

我希望我的解释是成功的;请原谅我的英语...

"use strcit";

var blank, container, yblock;

function bLeft() {
  if (yblock.offsetLeft <= 0) {
    blank.style.width = blank.offsetWidth + 16 + 'px';
    container.scrollTo(container.scrollLeft + 16, container.scrollTop);
  } else {
    yblock.style.left = `${yblock.offsetLeft - 16}px`;
  }
}

function bRight() {
  if (blank.offsetWidth > container.offsetWidth) {
    blank.style.width = blank.offsetWidth - 16 + 'px';
  } else {
    yblock.style.left = `${yblock.offsetLeft + 16}px`;
  }
}

function bUp() {
  if (yblock.offsetTop <= 0) {
    blank.style.height = blank.offsetHeight + 16 + 'px';
    container.scrollTo(container.scrollLeft, container.scrollTop + 16);
  } else {
    yblock.style.top = `${yblock.offsetTop - 16}px`;
  }
}

function bDown() {
  if (blank.offsetHeight > container.offsetHeight) {
    blank.style.height = blank.offsetHeight - 16 + 'px';
  } else {
    yblock.style.top = `${yblock.offsetTop + 16}px`;
  }
}

window.addEventListener("load", function() {
  blank = document.getElementById("blank");
  container = document.getElementById("container");
  yblock = document.getElementById("y-block");
  document.getElementById("left").addEventListener("click", bLeft);
  document.getElementById("right").addEventListener("click", bRight);
  document.getElementById("up").addEventListener("click", bUp);
  document.getElementById("down").addEventListener("click", bDown);
});
.container {
  position: relative;
  width: 20em;
  height: 20em;
  border: dashed 0.2em black;
  overflow: auto;
}

.blank {
  position: absolute;
  width: 100%;
  height: 100%;
}

.y-block {
  position: absolute;
  background-color: yellow;
  width: 3em;
  height: 3em;
}
<div class="container" id="container">
  <div class="blank" id="blank">
    <div class="y-block" id="y-block"></div>
  </div>
</div>
<div>
  <input type="button" value="left" id="left">
  <input type="button" value="right" id="right">
  <input type="button" value="down" id="down">
  <input type="button" value="up" id="up">
</div>

【讨论】:

  • 虽然此代码可能会解决问题,但 including an explanation 关于如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提出问题的人。请edit您的答案添加解释并说明适用的限制和假设。
【解决方案2】:

这是一个快速示例,说明如何在移动黄色框的同时实现容器水平滚动。

 var btns = document.querySelectorAll('button');
        var inner = document.querySelector('.inner');
        var outer = document.querySelector('.outer');
        var offset = 0;
        
        btns[0].addEventListener('click', function() {
            offset -= 25;
            inner.style.transform = `translate(${offset}px, 0px)`;
            outer.scroll({
                left: outer.scrollLeft -= 25
            });
        });
        
        btns[1].addEventListener('click', function() {
            offset += 25;
            inner.style.transform = `translate(${offset}px, 0px)`;
            outer.scroll({
                left: outer.scrollLeft += 25
            });
        });
button {
    margin: 0 auto;
    display: block;
  }
  
  .outer {
    outline: 1px dashed black;
    margin: 0 auto;
    width: 200px;
    height: 200px;
    overflow: auto;
  }
  
  .inner {
    width: 100px;
    height: 100px;
    background: yellow;
  }
    <button>Move Left</button>
    <button>Move Right</button>
    
    <div class="outer">
        <div class="inner"></div>
    </div>

【讨论】:

  • 谢谢!我注意到如果向左移动,滚动条不会出现
  • 当然不行,溢出只按照定义的方向起作用,默认是ltr(left to right)。
  • 这正是 OP 的问题...... OP 询问移动到左边缘时显示的滚动条
【解决方案3】:

不要向左或向上移动对象,而是在这些属性低于 0 时增加父容器的高度/宽度,并将窗口滚动偏移量。

这将使对象看起来从画布上移开,同时为您提供滚动条,但该对象实际上从未超出 (0,0)

【讨论】:

  • 你无法确定。如果是连续投票,则系统应在 48 小时内将其撤消。如果不是,您可以标记以引起版主注意,解释滥用情况。我不建议在 cmets 中处理这个。
  • 不是 100%,但他的回答被否决(不是我作为我的代表
  • @DAustin 顺便说一句,这种方法很有趣,我正在努力让它立即工作
  • 不幸的是,代表和我一样低,我只能在我自己的帖子的 cmets 中叫他出来
  • @Vytalyi - 是的,我正在为你制作小提琴,但我的日常工作妨碍了我。您可能需要一个用于内部元素的包装 DIV,而我找不到用于将 DIV 滚动到正确位置的有效 JS 函数。如果有机会,今天下午将再次尝试并用一个工作示例更新我的答案
猜你喜欢
  • 1970-01-01
  • 2013-02-25
  • 2020-02-02
  • 1970-01-01
  • 2011-04-20
  • 2014-08-08
  • 1970-01-01
  • 2020-05-07
  • 1970-01-01
相关资源
最近更新 更多