PHP和AJAX消息框在用户滚动上滚动


PHP and AJAX message box scroll on user scroll?

我有一个PHP消息系统,它每200ms自动滚动到div的底部以显示新消息。我的问题是,如果用户尝试向上滚动,他们会被迫每200毫秒滚动一次。我可以用什么方法来防止这种情况发生?

HTML和JavaScript:

        <div id="tab3">
          <h2>Chat Room</h>
                <div id="c-input_wrap">
                    <div id="chatlog">
                        Loading chat please wait...
                    </div>
                <div id="chatwrap">
                    <div id="chatinput">
                    <form name="chatbox" class="userchat">
                        <input class="userchat" name="message" type="text" autocomplete="off" onkeydown="if (event.keyCode == 13) document.getElementById('chatbutton').click()" autofocus/><br>
                        <input class="userchat" id="chatbutton" name="submitmsg" type="button" onclick="submitChat()" value="Send" />
                    </form>
                    </div>
                </div>
            </div>
        </div>
<script>    
    var form = document.querySelector('form[name="chatbox"]');
    form.addEventListener("submit", function (event) {
        event.preventDefault();
    });
    function submitChat() {
        if(chatbox.message.value == '') {
            alert('Error: Missing Fields.');
            return;
        }
        var message = chatbox.message.value;
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
            if(xmlhttp.readyState==4&&xmlhttp.status==100) {
                document.getElementById('chatlog').innerHTML = xmlhttp.responseText;
            }
        }
        xmlhttp.open('GET','chat.php?message='+message, true);
        xmlhttp.send();
        chatbox.reset();
    }
    $(document).ready(function(e) {
        $.ajax('logs.php', {
            ifModified: true,
            complete: function(jqxhrResponse) {
                $('#chatlog').html(jqxhrResponse.responseText);
                // scroll to the bottom here
                scrollToNewMessage();
            }
        })
    });
    var allowScroll = true;
    $('#chatlog').scroll(function() {
        allowScroll = isNearBottom();
    });
    function isNearBottom() {
        var leeway = 10;
        $(window).scroll(function() {
            return $(window).scrollTop() + $(window).height() > $(document).height() - leeway;
    });
}
function scrollToNewMessage() {
  if (allowScroll) {
    $("#chatlog").animate({ scrollTop: $('#chatlog').prop("scrollHeight")}, 1000);
  }
}
</script>

chat.hp:

<?php
    error_reporting(E_ALL & ~E_NOTICE);
    session_start();
    if  (isset($_SESSION['id'])) {
        $userId = $_SESSION['id'];
        $username = $_SESSION['username'];
        $userLabel = $_SESSION['nickname'];
    }
    $connect = mysqli_connect("", "", "", "");
    mysqli_select_db($connect, "root");
    $message = $_REQUEST['message'];
    $date = date('m/d/y');
    $time = date('H:i:s');
    mysqli_query($connect, 
    "INSERT INTO chat (name, message, time, date) VALUES ('$userLabel', '$message', '$time', '$date')"
    );
    $result1 = mysqli_query($connect, "SELECT * FROM chat ORDER by id");
    while ($extract = mysqli_fetch_assoc($result1)) {
        echo $extract['name'] . ": " . $extract['message'];
    }
?>

logs.hp:

<?php
    error_reporting(E_ALL & ~E_NOTICE);
    session_start();
    if  (isset($_SESSION['id'])) {
        $userId = $_SESSION['id'];
        $username = $_SESSION['username'];
        $userLabel = $_SESSION['nickname'];
    }
    $connect = mysqli_connect("", "", "", "root");
    mysqli_select_db($connect, "root");
    $day = date('m/d/y');
    $result1 = mysqli_query($connect, "SELECT * 
                                       FROM (SELECT * 
                                             FROM chat 
                                             WHERE date = '$day' 
                                             ORDER BY id DESC 
                                             LIMIT 100) x                                      
                                       ORDER BY id ASC
                                       ");
    while ($extract = mysqli_fetch_assoc($result1)) {
            echo "
            <div class='usermessage'>
                <div class='mheader'>
                    <h1 style='color:".$color."'>" . $extract['time'] . "</h1>
                    <h2 style='color:".$color."'>" . $extract['date'] . "</h2>
                    <h3 style='color:".$color."'>" . $extract['name'] . "</h3>
                </div>
                <p>" . $extract['message'] . "</p>
            </div>";
        }
?>

1。何时滚动

你不需要每200毫秒滚动一次,你只需要在有新信息时滚动。使用load做这件事有点困难,但jQuery的ajax函数可以帮助您:

$.ajax('logs.php', {
  ifModified: true,
  complete: function(jqxhrResponse) {
    $('#chatlog').html(jqxhrResponse.responseText);
    // scroll to the bottom here
    scrollToNewMessage();
  }
})

1.5:如果ifModified不适用,请在某个地方声明一个变量(在$(document).ready中应该可以)。

var currentMessageText = "";

现在自己检查是否有任何修改,如果有,请相应更新:

complete: function(jqxhrResponse) {
  if (currentMessageText != jqxhrResponse.responseText)
  {
    currentMessageText = jqxhrResponse.responseText;
    $('#chatlog').html(currentMessageText);
  }
}

2.何时不滚动

现在你需要弄清楚什么时候不滚动。如果用户向上滚动,那么我们不希望滚动。如果用户向下滚动,我们会这样做。我们可以使用jQuery的scroll事件来确定用户何时滚动,并测试他离底部有多近。

var allowScroll = true;
$('#chatlog').scroll(function() {
  allowScroll = isNearBottom();
});
/* modified from http://stackoverflow.com/a/3898152/123415 */
function isNearBottom() {
  var leeway = 10;
  $(window).scroll(function() {
    return $(window).scrollTop() + $(window).height() > $(document).height() - leeway);
  });
}

我给了用户一点余地,让他们不要处于最底层,但也许你想调整一下。

3.滚动至新消息

现在我们只需要在适当的时候滚动:

function scrollToNewMessage() {
  if (allowScroll) {
    $("#chatlog").animate({ scrollTop: $('#chatlog').prop("scrollHeight")}, 1000);
  }
}

免责声明:我还没有测试过上面的代码,如果有问题,只需留下评论,我就会更正。