【问题标题】:Keep the scroll at the bottom unless user changes the position of the scroll除非用户更改滚动的位置,否则将滚动保持在底部
【发布时间】:2016-11-04 19:48:17
【问题描述】:

几天前我asked如何在新数据进入时将滚动条保持在底部。我得到了this answer,这对我来说非常好用。但是现在我有了一个新的要求。我希望滚动条留在我拿它的地方。例如,当页面加载时,如果我没有触摸滚动条,那么滚动条应该保持在底部。但是如果我触摸它并把它拿起来,那么它应该呆在那里而不是自动下来。

这是我的代码:

<style>
#conversationDiv {
height: 900px;
overflow: auto;     
} 
</style>

<script>
$(function () {
  setInterval(function() {
    var element = document.getElementById("conversationDiv");
    element.scrollTop = element.scrollHeight;
  }, 0);
});
</script>


<div id="conversationDiv">

编辑:我在下面发布了完整的代码,它显示了消息的来源以及它们被附加到哪个 div 的位置。

<!DOCTYPE html>
<html>
<head>
<title>Hello WebSocket</title>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.1.0/sockjs.js">   </script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.js"></script>
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<style>
#conversationDiv {
height: 900px;
}
</style>
<script>
 $(function () {     
  setInterval(function() {       
   var element = document.getElementById("conversationDiv");
    element.scrollTop = element.scrollHeight;
   }, 0);
});  
</script>
<script type="text/javascript">
    var stompClient = null;
    function setConnected(connected) {
        document.getElementById('connect').disabled = connected;
        document.getElementById('disconnect').disabled = !connected;
        document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden';
        document.getElementById('response').innerHTML = '';
    }

    function connect() {
        var socket = new SockJS("http://twitchbot-farazdurrani.rhcloud.com:8000/hello/");
        stompClient = Stomp.over(socket);
        stompClient.connect({}, function(frame) {
            setConnected(true);
            console.log('Connected: ' + frame);
            stompClient.subscribe("/topic/greetings", function(greeting){
                showGreeting(greeting.body);
            });
        });
    }

    function disconnect() {
        if (stompClient != null) {
            stompClient.disconnect();
        }
        setConnected(false);
        console.log("Disconnected");
    }

    function sendName() { //I am not sending anything so remove this..
        var name = document.getElementById('name').value;
        stompClient.send("/app/hello", {}, JSON.stringify({ 'name': name     }));
    } 

    function showGreeting(message) {
        var response = document.getElementById('response');
        var p = document.createElement('p');
        p.style.wordWrap = 'break-word';
        p.appendChild(document.createTextNode(message));
        response.appendChild(p);
    }        
</script>
</head>
<body onload="connect()">
<div>
    <div>
        <button id="connect" onclick="connect();">Connect</button>
        <button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button>
    </div>
    <div id="conversationDiv" style="overflow:auto">            
        <p id="response"></p>
    </div>
</div>

关于正在发生的事情的一些信息:这是一个单向聊天系统(使用 WebSockets),其中只有一方发送消息。那是服务器端。所有的魔法都发生在 function showGreeting(message) {..} 中,它在其中创建元素和附加子元素等。我希望这可能没什么帮助。 谢谢

【问题讨论】:

  • 是的...正在努力。
  • 你不能把初始的 scrollHeight 和当前的比较来确定你是否应该 scrollTop 吗?
  • @Alexandre 这就是我所做的。但由于某种原因,它不起作用。你能调试我的代码吗?

标签: javascript html css


【解决方案1】:

为此,您可能需要一个标志。所以我正在做的是:

  1. 当触发滚动事件时(即使在追加时也会触发),我们需要检查滚动部分是否在末尾。
  2. 如果不是结束,我们需要清除间隔。
  3. 如果是结束,重新初始化间隔。

不知道为什么它不起作用。我有我在这里工作的脚本。

$(function () {
  var count = 1;
  setInterval(function () {
    $("#conversationDiv").append('<p>Message #' + count++ + ': Lorem ipsum dolor sit amet, consectetur adipisicing elit. Praesentium repudiandae doloribus unde, repellat maiores minus fuga earum esse, ab, aperiam voluptatibus est dolorem placeat perferendis omnis libero dolore alias quasi!</p>');
  }, 1000);
  var scr = setInterval(function() {
    var element = document.getElementById("conversationDiv");
    element.scrollTop = element.scrollHeight;
  }, 500);
  $("#conversationDiv").scroll(function () {
    var element = document.getElementById("conversationDiv");
    if ((Number(element.scrollTop) + Number($(element).height())) != (Number(element.scrollHeight)))
      clearInterval(scr);
    else
      if (element.scrollTop < element.scrollHeight)
      scr = setInterval(function() {
        var element = document.getElementById("conversationDiv");
        element.scrollTop = element.scrollHeight;
      }, 500);
  });
});
* {font-family: 'Segoe UI'; margin: 0; padding: 0; list-style: none;}

#conversationDiv {height: 350px; overflow: auto; border: 1px solid #ccc;}
#conversationDiv p {margin: 5px 5px 10px; padding: 5px; border: 1px solid #ccc; background-color: #f5f5f5;}
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<div id="conversationDiv">
  
</div>

好像少了点什么。我快到了。 Number(element.scrollTop)Number($(element).height())Number(element.scrollHeight) 区域内是否应该有什么东西。

【讨论】:

【解决方案2】:

你可以这样判断是否被滚动到底部

var isScrolled = (element.scrollHeight - element.scrollTop === element.clientHeight);

然后:

if (isScrolled) { 
   //code here to move scrollbar down
}

https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight

【讨论】:

  • 哇。谢谢。让我检查一下。
  • 我已经尝试了 isScrolled!isScrolled 来满足我的答案,但没有帮助!
  • 在浏览器中打开 fireBug 或其他调试器,console.log element.scrollHeight - element.scrollTop === element.clientHeight 它应该返回 true 或 false
猜你喜欢
  • 2013-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多