web-dev-qa-db-ja.com

その下のdivにぶつかったときにdivが上にスクロールしないようにしますか?

私は 同様の質問 を昨日尋ねましたが、説明が不十分であり、純粋なCSSソリューションに対する私の希望を明記していなかったので、可能であると思われるので、もう一度やり直します。

基本的に、スクロール可能なメッセージのdivとその下に入力フィールドがあるという問題があります。ボタンをクリックしたときに、メッセージのdivもスクロールせずに、入力フィールドを100ピクセル増やしたいと思います。

ここに問題全体を示すフィドルがあります

ご覧のとおり、「マージンを追加」ボタンをクリックすると、メッセージのdivも上にスクロールします。そのままにしてもらいたいです。同様に、少し上にスクロールして最後から2番目のメッセージしか表示できない場合、ボタンをクリックしても、クリックしたときにその位置が保持されます。

興味深いのは、この動作が「ときどき」維持されることです。たとえば、状況によっては(かなり推測することはできません)、スクロール位置が保持されます。私はそれが一貫してそのように振る舞うことを望みます。

window.onload = function(e) {
  document.querySelector(".messages").scrollTop = 10000;
};

function test() {
  document.querySelector(".send-message").classList.toggle("some-margin");
}
.container {
     width: 400px;
     height: 300px;
     border: 1px solid #333;
     display: flex;
     flex-direction: column;
}
 .messages {
     overflow-y: auto;
     height: 100%;
}
 .send-message {
     width: 100%;
     display: flex;
     flex-direction: column;
}
 .some-margin {
     margin-bottom: 100px;
}
<div class="container">
   <div class="messages">
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
   </div>
   <div class="send-message">
      <input />
   </div>
</div>
<button onclick="test()">add margin</button>

enter image description here

10
Ryan Peschel

つまり、あなたの例を正確に解決するCSSのみのソリューションは次のとおりです。

.some-margin{margin-bottom:100px;}

.messages{margin-top:-100px;}

しかし、それが仮想キーボードの元の問題を解決することはないと思います。しかし、おそらくこれは他の誰かを解決策に刺激することができます。

主な問題は、スクロールバーがすでにあなたが望むことを正確に実行していることです:

最後に読み取ったコンテンツが表示されるように位置を維持します。

スクロールバーは、現在表示されているコンテンツの下部ではなく、上部を表示することを決定します。 (数字を使用する方が簡単です: https://jsfiddle.net/1co3x48n/

JavaScriptを使用したい場合は、あらゆる種類の回答があります。 https://www.google.com/search?q=scrollbar+always+on+bottom+css+site:stackoverflow.com =

正直なところ、このページを3〜3ページ以上読み、Javascriptの回答のみを見つけることができるという事実は、CSSのみの回答を見つけることはできないことを教えてくれます。

0
Eliezer Berlin

残念ながら、提供されているソリューションはどれも実際には機能していないようです。テキストボックスにonFocusを使用する場合の問題は、テキストボックスにすでにフォーカスがある場合は適用されないことです。私はこれを何時間もいじっていましたが、これまでに思いついた最も近い解決策はこれです:

componentDidMount() {
  this.screenHeight = window.innerHeight;

  let chatElem = document.querySelector(".conversations-chat");

  window.addEventListener('resize', () => {
    let diff = this.screenHeight - window.innerHeight;

    chatElem.scrollTop += diff;

    this.screenHeight = window.innerHeight;      
  });
}

ただし、これは時々しか機能しないようです。テキストボックスをクリックすると100%動作しますが、何らかの理由で仮想キーボードを閉じると、十分にスクロールされた場合にのみ動作します。それ以外の場合は、毎回同じ位置にリセットされます(下部近くですが、下部ではありません)。

原因は不明です。明日はもっと調べないといけないと思います。これはこれまでのところ最も近いものです。

0
Ryan Peschel

マージンを追加する場合はtest関数にdocument.querySelector(".messages").scrollTop = 10000;を追加し、次にscrollTopに設定した負荷で終了してscrolltopを設定し、マージンを追加またはマージンを削除する場合はscrolltopは、スクリプトを次のように変更するように設定し直していません

<script>
    window.onload = function(e){ 
    document.querySelector(".messages").scrollTop = 10000;
}

function test() {
    document.querySelector(".send-message").classList.toggle("some-margin")
            document.querySelector(".messages").scrollTop = 10000;
}
    </script>
0
MBadrian

上記の例のようにコンテナを作成しますが、入力を開始したらCSSを変更するだけです。

スクロールバーの位置は設定せず、メッセージコンテナ全体を上に移動します。したがって、スクロール位置が何であれ、同じままになります。もちろん、少なくとも下向きにすると、上部の線が見えなくなります。

あなたはあなたのニーズにCSSを微調整できるはずです。 :focusまたはわずかに異なるCSS設定を使用している場合は、JSなしでクリエイティブなこともできます。

function activate(){
    document.querySelector("#container").classList.toggle("active");
  }
#container{
    position:relative;
    width:300px;
    height:100vh;
    max-height:230px;
    overflow:hidden;
  }
  #messages{
    position:absolute;
    bottom:30px;
    overflow:auto;
    height:200px;
    width:100%;
    background:#eee;
  }
  #container.active #messages {
    bottom:100px;
  }
  #send-message{
    position:absolute;
    border:1px solid #ccc;
    bottom:0;
    height:28px;
  }
  #container.active #send-message{
    height:100px;
  }
<div id="container">
  <div id="messages">
  <div class="message">hello</div>
  <div class="message">hello</div>
  <div class="message">hello</div>
  <div class="message">hello</div>
  <div class="message">hello</div>
  <div class="message">hello</div>
  <div class="message">hello</div>
  <div class="message">hello</div>
  <div class="message">hello</div>
  <div class="message">hello</div>
  <div class="message">hello</div>
  <div class="message">hello</div>
  <div class="message">hello</div>
  <div class="message">hello</div>
  <div class="message">hello</div>
  <div class="message">hello</div>
  <div class="message">hello</div>
  <div class="message">hello</div>
  <div class="message">hello</div>
  <div class="message">hello</div>
  </div>
  <div id="send-message">
    <input id="newmessage" onclick="activate()" type="text" />
  </div>
</div>
0
Rmaxx

Jsトグル機能に問題があるようです。シンプルな非表示に変更しました。また、入力タグに幅を追加しました。また、位置を追加する必要があります:メッセージ送信divの絶対値と下部:0が下部に留まるようにします。次に、position:relativeをコンテナーに配置して、送信メッセージdivがコンテナー内に留まるようにします。つまり、メッセージコンテナはメッセージ自体に影響を与えず、プッシュアップしません。

window.onload = function(e) {
  document.querySelector(".messages").scrollTop = 10000;
};

function test() {
  var x = document.querySelector(".send-message");

  if (x.style.display === "none") {
    x.style.display = "block";
  } else {
    x.style.display = "none";
  }
}
.container {
     width: 400px;
     height: 300px;
     border: 1px solid #333;
     display: flex;
     flex-direction: column;
     position: relative;
}
 .messages {
     overflow-y: auto;
     height: 100%;
}
 .send-message {
     width: 100%;
     display: flex;
     flex-direction: column;
     position: absolute;
     bottom: 0;
}
 .send-message input {
     width:100%;
}
 .some-margin {
     margin-bottom: 100px;
}

 
 
<div class="container">
   <div class="messages">
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">test</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
      <div class="message">hello</div>
   </div>
   <div class="send-message">
      <input />
   </div>
</div>
<button onclick="test()">add margin</button>
0
Shannaki