admin管理员组

文章数量:1293660

var block = document.getElementById('block')

function myFunct() {
    block.style.transform = 'translateX(-400px)'
}
    .container {
        position:relative;
        width:400px;
        height:150px;
        margin:auto;
        background-color: blue;
        overflow:scroll;
        
    }
    

    
    #block {
        position:absolute;
        height:25px;
        width:100%;
        left:50%;
        bottom:50%;
        overflow: scroll;
        background-color: yellow;
        border:1px solid black;
        align-self: flex-end;
    }
    <div class="container">
        <div id="block"></div>
        <button onclick='myFunct()'>CLICK</button>
    </div>

var block = document.getElementById('block')

function myFunct() {
    block.style.transform = 'translateX(-400px)'
}
    .container {
        position:relative;
        width:400px;
        height:150px;
        margin:auto;
        background-color: blue;
        overflow:scroll;
        
    }
    

    
    #block {
        position:absolute;
        height:25px;
        width:100%;
        left:50%;
        bottom:50%;
        overflow: scroll;
        background-color: yellow;
        border:1px solid black;
        align-self: flex-end;
    }
    <div class="container">
        <div id="block"></div>
        <button onclick='myFunct()'>CLICK</button>
    </div>

In my example the block overflows the right side of the container and overflow is set to scroll. So you can scroll the right side and see the rest of the block. Then when I run the function, the block moves so it's overflowing the left side of the container. However it does not adjust to allow for scrolling left to see the rest of the block. What is the solution to allow for scrolling of other sides after functions are ran and blocks are moved to overflow those different sides.

Share asked Jul 31, 2019 at 18:26 Harper CreekHarper Creek 4376 silver badges20 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 3

Based on this, a the solution can be sort of 'hack' like this:

var block = document.getElementById('block')
function myFunct() {
    document.getElementsByClassName('container')[0].dir = 'rtl';
    block.style.transform = 'translateX(-400px)'
}
.container {
        position:relative;
        width:400px;
        height:150px;
        margin:auto;
        background-color: blue;
        overflow:scroll;
        
    }
    

    
    #block {
        position:absolute;
        height:25px;
        width:100%;
        left:50%;
        bottom:50%;
        overflow: scroll;
        background-color: yellow;
        border:1px solid black;
        align-self: flex-end;
    }
    
<div class="container">
  <div id="block"></div>
  <button onclick='myFunct()'>CLICK</button>
</div>

Thanks to @TemaniAfif that point me.

The real problem at hand is that the css property transform will only trigger a repaint on the Composite Layer, this was an optimization decision made to facilitate animations without triggering repaints on the Layout Layer . To trigger an entire layout repaint you should use a layout property like left or right:

Example:

function myFunct() {
    block.style.left = '0px'
}

Also the reason you are getting the scrollbar on initial load is because you have:

#block {
...
  left: 50%
...
}

More here on Compositor-Only Properties

Edit:

Although the above is true, switching to 'style.left' will still not cut it because block level elements have a default content flow direction of left to right or in css direction: ltr so this means you'll need to modify the content direction as well which should cancel out the need to use style.left. See below:

var block = document.getElementById('block')
var container = document.querySelector('.container')

function myFunct() {
    block.style.transform = 'translateX(-400px)'
    container.style.direction = 'rtl'
}
 .container {
        position:relative;
        width:400px;
        height:150px;
        margin:auto;
        background-color: blue;
        overflow:scroll;
    }
    

    
    #block {
        position:absolute;
        height:25px;
        width:100%;
        left:50%;
        bottom:50%;
        overflow: scroll;
        background-color: yellow;
        border:1px solid black;
     
    }
    <div class="container">
        <div id="block"></div>
        <button onclick='myFunct()'>CLICK</button>
    </div>

Is it important where the yellow block shifts and gets positioned? if you just set the #block width to allow for the extra 400px with width: calc(100% + 400px) then you can see it with overflow after calling the function.

var block = document.getElementById('block')

function myFunct() {
  block.style.transform = 'translateX(-400px)'
}
.container {
  position: relative;
  width: 400px;
  height: 150px;
  margin: auto;
  background-color: blue;
  overflow: scroll;

}



#block {
  position: absolute;
  height: 25px;
  width: calc(100% + 400px);
  left: 50%;
  bottom: 50%;
  overflow: scroll;
  background-color: yellow;
  border: 1px solid black;
  align-self: flex-end;
}
    <div class="container">
      <div id="block"></div>
      <button onclick='myFunct()'>CLICK</button>
    </div>

This is what I came up with. My solution applies to my use which is to have a have a line of text run across the page right to left and being able to scroll left to see the parts of the sentence that eventually overflow. The #fill div lets the entire wrapper be scrollable rather than just the span. There's a way to do it with two divs using "line-height = (size of container)" but I figured that would lead to future problems so I avoided. The key to my way was the "outer.scrollLeft += outer.scrollWidth" within the function. There's a more fluid way of doing this as my way is choppy by moving the entire span element left which is what my original question was pointed towards but ultimately not how I did it. Meshu's solution also worked in application to the question I asked. "Direction:rtl" also allows for a solution.

var inset = document.getElementById('inset')
var fill = document.getElementById('fill')
var text = 'There was a lamb who had a cow and a farmer was involved and then you make a moo sound and yell BINGO and that is how the song goes.'; /*Obviously you can change this jibberish */
var words = text.split(" ") /* breaking the text into an array of each word */

var i = 0
var timer = 5; /*How long the text will take to run through in seconds*/
var wordTime = (timer / words.length) * 1000; /* Time before the next word takes to the screen. As of this code, all words have equal time */


var myVar = setInterval(myFunct, wordTime);

function myFunct() {
  if (i == words.length) {
    clearInterval(myVar); /* Stops running when all words are passed through */
  } else {
    inset.innerHTML += " " + words[i];
  }
  i++
  let outer = fill
  outer.scrollLeft += outer.scrollWidth; /*important */
}
#wrapper {
  position: absolute;
  display: flex;
  height: 100px;
  width: 100%;
  min-width: 100%;
  max-width: 100%;
  left: 0;
  right: 0;
  bottom: 0;
  align-items: center;
  text-align: right;
  color: whitesmoke;
  font-family: sans-serif;
  font-size: 200%;
  background-color: rgba(0, 0, 0, 0.7);
}

#fill {
  display: flex;
  width: 100%; /*You can change this to change how much of container the text overtakes */
  height: 100%;
  max-width: 100%;
  align-items: center;
  overflow: auto;
}

#inset {
  padding-left:5px;
  white-space: nowrap;
  margin-left:auto;
}
<div id='wrapper'>
  <div id='fill'>
    <span id='inset'></span>
  </div>
</div>

.

本文标签: javascriptOverflow scrolling on dynamically moving elementsStack Overflow