由于重复ajax调用,无法正确复制文本

r9f1avp5  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(407)

我有一个简单的聊天网络应用程序,一切正常。但是,有两个问题:1)当我尝试复制文本时,重复的ajax调用会导致选中所有文本,如果gif长于间隔,则会在循环中运行。2) 新消息的通知是有效的,但是为了看到新消息,您必须单击发件人,即使您当前正在与他们交谈。

当我试图复制一条消息时会发生这种情况:

我不知道如何在不点击用户链接的情况下显示新消息。
以下是主页chat.php:

  1. <?php
  2. //error_reporting(E_ERROR);
  3. //ini_set('display_errors', 1);
  4. include 'includes/header.php';
  5. include 'includes/DB.php';
  6. try {
  7. $db = new DB();
  8. } catch (Exception $e) {
  9. }
  10. $username = $_SESSION['logged_in'];
  11. $short_name = substr($username, 0, strpos($username, '.'));
  12. ?>
  13. <div id="page-wrap">
  14. <h2 id="chat_title_h2">IT Chat</h2>
  15. <p id="name-area">Hello, <?= $short_name ?></p>
  16. <div id="chat-wrap">
  17. <div id="user-list">
  18. <p style="color:white;font: bold 12px 'Lucida Grande', Sans-Serif;margin-top:10px; margin-left:10px;">
  19. Conversations</p>
  20. <?php
  21. //Populate the user list
  22. foreach ($users_result = $db->getRows('SELECT * FROM users ORDER BY username', ['']) as $user) {
  23. $username = $user['username'];
  24. $short_list_name = substr($username, 0, strpos($username, '.'));
  25. echo '<p style="margin-left:10px;color:white;"><a class="link" style="color:white!important;" href=' . $username . '>' . $short_list_name . '</a><span class="dot" data-name="' . $username . '"</p>';
  26. }
  27. ?>
  28. </div>
  29. <div id="chat-area"></div>
  30. </div>
  31. </div>
  32. <div id="wrapper">
  33. <form name="message-form" id="message-form" method="post" enctype="multipart/form-data">
  34. <div class="input-group">
  35. <span class="input-group-addon" style="background-color:darkorange;color:white;font-size:18px;border:none;border-radius:0;">
  36. <label for="upload" style="margin-top:5px;font-size:20px;">
  37. <span class="fa fa-paperclip"></span>
  38. <input type="file" id="upload" name="upload" style="display:none;">
  39. </label>
  40. </span>
  41. <textarea id="message" class="form-control" rows="3" maxlength="50000" style="resize:none;margin:0;height:50px;"></textarea>
  42. <span class="input-group-addon btn btn-primary" id="send-button" style="background-color:darkorange!important;box-shadow:none!important;">Send</span>
  43. </div>
  44. </form>
  45. </div>
  46. <p class="input--error" style="visibility:hidden;">Error Uploading File</p>
  47. <script>
  48. //var links = '<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">' + '<link rel="stylesheet" href="css/chat.css">';
  49. //$('head').append(links);
  50. //Disable send and upload buttons until user is clicked
  51. $('#message').prop('disabled', true);
  52. $('#upload').prop('disabled', true);
  53. $('#send-button').css('pointer-events', 'none');
  54. var userLink = '';
  55. document.title = 'Chat';
  56. //Check messges and notifications every 1000 ms
  57. setInterval(function () {
  58. getMessages();
  59. }, 1000); //<----- THE PROBLEM
  60. setInterval(function () {
  61. checkNotifications();
  62. }, 1000);
  63. $(function() {
  64. //Function that defines what happens when a file is chosen from file chooser
  65. $('input:file').change(function () {
  66. var file_data = $('#upload').prop('files')[0];
  67. var form_data = new FormData();
  68. form_data.append('upload', file_data);
  69. $.ajax({
  70. url: 'includes/chat/upload.php?userLink='+userLink,
  71. type: 'post',
  72. data: form_data,
  73. contentType: false,
  74. cache: false,
  75. processData: false,
  76. success:function(data) {
  77. if(data === 'Error') {
  78. $('.input--error').css('visibility','visible');
  79. $('.input--error').delay(3000).hide(0);
  80. } else {
  81. $('#chat-area').append(data);
  82. var chatarea = $('#chat-area');
  83. var height = chatarea[0].scrollHeight;
  84. chatarea.scrollTop(height);
  85. }
  86. },
  87. error:function(data) {
  88. console.log(data);
  89. }
  90. })
  91. });
  92. });
  93. //Get messages to refresh chat window
  94. function getMessages() {
  95. if (userLink.length > 0) {
  96. $.ajax({
  97. url: 'includes/chat/get_messages.php?userLink=' + userLink,
  98. type: 'post',
  99. dataType: 'html',
  100. success: function (data) {
  101. $('#chat-area').html(data);
  102. }
  103. })
  104. }
  105. }
  106. //If user's link is clicked, notification goes away and font changes to show which conversation you're on
  107. $(document).on('click', '.link', function (event) {
  108. event.preventDefault();
  109. //Scroll to the bottom when a user's link is clicked to read messages
  110. setTimeout(function() {
  111. var chatarea = $('#chat-area');
  112. var height = chatarea[0].scrollHeight;
  113. chatarea.scrollTop(height);
  114. }, 500);
  115. $('#message').prop('disabled', false);
  116. $('#upload').prop('disabled', false);
  117. $('#send-button').css('pointer-events', 'auto');
  118. userLink = $(this).attr('href');
  119. var name = userLink.substring(0, userLink.indexOf('.'));
  120. $('#message').attr('placeholder', 'Send message to ' + name);
  121. $('#message').addClass('message-placeholder');
  122. $('.message-placeholder').css('fontSize', 16);
  123. $('#chat_title_h2').text(name);
  124. $(this).parent().find('span').css('visibility', 'hidden');
  125. $(this).css({
  126. 'font-weight': 'bold',
  127. fontSize: 18
  128. });
  129. $('.link').each(function () {
  130. if ($(this).attr('href') !== userLink) {
  131. $(this).css({
  132. 'font-weight': 'normal',
  133. fontSize: 14
  134. })
  135. }
  136. });
  137. //Ajax call to get messages. Populate chat window with returned data
  138. $.ajax({
  139. type: 'post',
  140. url: 'includes/chat/show_conversation.php',
  141. data: {
  142. link: $(this).attr('href'),
  143. },
  144. dataType: 'html',
  145. success: function (data) {
  146. $('#chat-area').html(data);
  147. }
  148. })
  149. });
  150. //Button is not a 'button', but a span. Can't have a .submit() function here.
  151. $('#send-button').on('click', function () {
  152. var text = $('#message').val(); //Get what is in the textarea
  153. var maxLength = $('#message').attr('maxlength');
  154. console.log(text);
  155. var length = text.length;
  156. if (length <= maxLength + 1) { //Make sure it's not over the max length
  157. sendChat();
  158. $('#message').val('');
  159. } else {
  160. $('#message').val(text.substring(0, maxLength));
  161. }
  162. });
  163. //Ajax call to send the textarea data to the server. If overflow-y is present, auto-scroll to bottom
  164. function sendChat() {
  165. var text = $('#message').val();
  166. //Check to see if someone sent a link and format accordingly
  167. if (validURL(text)) {
  168. text = '<a target="_blank" href=' + text + '>' + text + '</a>';
  169. }
  170. $.ajax({
  171. url: 'includes/chat/send_message.php',
  172. type: 'post',
  173. data: {message: text, link: userLink},
  174. dataType: 'html',
  175. success: function (data) {
  176. getMessages();
  177. $('#chat-area').append(data);
  178. var chatarea = $('#chat-area');
  179. var height = chatarea[0].scrollHeight;
  180. chatarea.scrollTop(height);
  181. }
  182. });
  183. }
  184. //Check for new messages. Changes CSS of notification span to visible if new message is present.
  185. function checkNotifications() {
  186. $.ajax({
  187. url: 'includes/chat/check_notifications.php',
  188. type: 'post',
  189. dataType: 'json',
  190. success: function (data) {
  191. $.each(data, function (i, item) {
  192. console.log(item);
  193. $('.link').each(function () {
  194. if ($(this).parent().find('span').data('name') === item) {
  195. $(this).parent().find('span').css('visibility', 'visible');
  196. }
  197. })
  198. })
  199. }
  200. })
  201. }
  202. //Check if the message is a url so <a> tags can be added to the text
  203. function validURL(str) {
  204. var pattern = new RegExp('^((news|(ht|f)tp(s?)):\\/\\/)' + // protocol
  205. '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name
  206. '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address
  207. '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path
  208. '(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
  209. '(\\#[-a-z\\d_]*)?$', 'i'); // fragment locater
  210. if (!pattern.test(str)) {
  211. console.log('Not a valid URL');
  212. return false;
  213. } else {
  214. console.log('Valid URL');
  215. return true;
  216. }
  217. }
  218. </script>
  219. </body>
  220. </html>

检查\u notifications.php

  1. <?php
  2. include '../DB.php';
  3. try { $db = new DB(); } catch (Exception $e) { $e->getMessage(); }
  4. session_start();
  5. //This script checks for unread messages and shows notifications accordingly.
  6. if(isset($_SESSION['logged_in'])) {
  7. $username = $_SESSION['logged_in'];
  8. $data = array();
  9. foreach($results = $db->getRows('SELECT user1, user2read FROM pm WHERE user2=?',[$username]) as $result) {
  10. $user2read = $result['user2read'];
  11. $user1 = $result['user1'];
  12. if($user2read === 'yes') {
  13. continue;
  14. }
  15. $data[] = $result['user1'];
  16. }
  17. echo json_encode($data);
  18. }

获取\u messages.php

  1. <?php
  2. include '../DB.php';
  3. try { $db = new DB(); } catch (Exception $e) { $e->getMessage(); }
  4. session_start();
  5. if(isset($_SESSION['logged_in'])) {
  6. $sender = $_SESSION['logged_in'];
  7. $recipient = $_GET['userLink'];
  8. foreach($results = $db->getRows('SELECT user1, user2, timestamp, message, user1read, user2read FROM pm WHERE (user1=? AND user2=?) OR (user1=? AND user2=?) ORDER BY id', [$sender, $recipient, $recipient, $sender]) as $result) {
  9. $user1 = $result['user1'];
  10. $user2 = $result['user2'];
  11. $short_name_1 = substr($user1, 0, strpos($user1, '.'));
  12. $message = $result['message'];
  13. $time = $result['timestamp'];
  14. $user1read = $result['user1read'];
  15. $user2read = $result['user2read'];
  16. echo '<p><strong>' . $short_name_1 . '</strong></p><p style="white-space:pre-wrap;padding: 2px 0;">' . $message . '</p><p style="padding: 2px 0; border-bottom: 1px solid #ccc;">' . $time . '</p>';
  17. }
  18. }

显示\u conversation.php

  1. <?php
  2. include '../DB.php';
  3. try { $db = new DB(); } catch (Exception $e) { $e->getMessage(); }
  4. //This script shows the conversation when a user's link is clicked
  5. session_start();
  6. if($_SERVER['REQUEST_METHOD'] === 'POST') {
  7. if(isset($_SESSION['logged_in'])) {
  8. $username = $_SESSION['logged_in'];
  9. $recipient = $_POST['link'];
  10. foreach($results = $db->getRows('SELECT user1, user2, timestamp, message FROM pm WHERE (user1=? AND user2=?) OR (user1=? AND user2=?) ORDER BY id', [$username, $recipient, $recipient, $username]) as $result) {
  11. $user1 = $result['user1'];
  12. $user2 = $result['user2'];
  13. $short_name_1 = substr($user1, 0, strpos($user1, '.'));
  14. $message = $result['message'];
  15. $time = $result['timestamp'];
  16. echo '<p><strong>'.$short_name_1.'</strong></p><p style="white-space:pre-wrap;padding: 2px 0;">'.$message .'</p><p style="padding: 2px 0; border-bottom: 1px solid #ccc;">'.$time.'</p>';
  17. }
  18. $read_status_result = $db->updateRow('UPDATE pm SET user2read=? WHERE user2=?',['yes',$username]);
  19. }
  20. }

发送消息.php

  1. <?php
  2. include '../DB.php';
  3. try { $db = new DB(); } catch (Exception $e) { $e->getMessage(); }
  4. session_start();
  5. if($_SERVER['REQUEST_METHOD'] === 'POST') {
  6. if (isset($_SESSION['logged_in'])) {
  7. $user = $_SESSION['logged_in'];
  8. $message = $_POST['message'];
  9. $recipient = $_POST['link'];
  10. $timestamp = date('Y-m-d H:i:s');
  11. $short_name_1 = substr($user, 0, strpos($user, '.'));
  12. $short_name_2 = substr($recipient, 0, strpos($recipient, '.'));
  13. $result = $db->insertRow('INSERT INTO pm (user1, user2, message, timestamp, user1read, user2read) VALUES (?,?,?,?,?,?)', [$user, $recipient, $message, $timestamp, 'yes', 'yes']);
  14. echo '<p><strong>'.$short_name_1.'</strong></p><p style="white-space:pre-wrap;padding: 2px 0;">'.$message .'</p><p style="padding: 2px 0; border-bottom: 1px solid #ccc;">'.$timestamp.'</p>';
  15. $set_read_status_result = $db->updateRow('UPDATE pm SET user1read=?, user2read=? WHERE user1=? AND user2=?',['yes', 'no', $user, $recipient]);
  16. }
  17. }

还有另一个文件upload.php,但它并不相关(以防您看到查询字符串中的链接并想知道它去了哪里)。
最后,以下是我的pm和users表的模式:
pm架构

  1. mysql> describe pm;
  2. +-----------+-------------+------+-----+-------------------+-----------------------------+
  3. | Field | Type | Null | Key | Default | Extra |
  4. +-----------+-------------+------+-----+-------------------+-----------------------------+
  5. | id | int(11) | NO | PRI | NULL | auto_increment |
  6. | user1 | varchar(30) | NO | | NULL | |
  7. | user2 | varchar(30) | NO | | NULL | |
  8. | message | text | YES | | NULL | |
  9. | timestamp | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
  10. | user1read | varchar(3) | YES | | NULL | |
  11. | user2read | varchar(3) | YES | | NULL | |
  12. +-----------+-------------+------+-----+-------------------+-----------------------------+
  13. 7 rows in set (0.01 sec)

用户

  1. mysql> describe users;
  2. +----------+--------------+------+-----+---------+----------------+
  3. | Field | Type | Null | Key | Default | Extra |
  4. +----------+--------------+------+-----+---------+----------------+
  5. | id | int(6) | NO | PRI | NULL | auto_increment |
  6. | username | varchar(255) | NO | | NULL | |
  7. | password | varchar(255) | NO | | NULL | |
  8. +----------+--------------+------+-----+---------+----------------+
  9. 3 rows in set (0.00 sec)

基本上,不必每秒钟检查一次消息,只要在发送消息时填充它就好了。这对这个项目没有坏处。这是一个更方便的因素,但我相信一些用户会想要这个功能。
如果有什么太模糊,或我没有评论的东西不够好,让我知道,我会编辑。

b5lpy0ml

b5lpy0ml1#

好吧,我不得不做一些代码杂耍,但我做到了我现在可以复制文本,如果需要的话,我只是禁用了选项上传一个gif,因为动画是可怕的设置间隔是每秒。在我找到一个更持久的解决方案之前,这是一个暂时的解决办法。
我为getmessages()setinterval分配了一个变量,并编写了mouseup和mousedown函数:

  1. //Check messges and notifications every 1000 ms
  2. var get_messages = setInterval(function () { //<-- Made this a variable
  3. getMessages();
  4. }, 1000);
  5. setInterval(function () {
  6. checkNotifications();
  7. }, 1000);
  8. $(function () {
  9. //Get the current mouse state to allow copying of text
  10. $('#chat-area').on('mousedown mouseup', function mouseState(e) {
  11. switch (e.type) {
  12. case 'mousedown':
  13. clearInterval(get_messages); //<-- Stop getting messages temporarily
  14. clearInterval(get_messages_again); //<-- Had to do it again with another variable
  15. console.log('Mouse down');
  16. break;
  17. case 'mouseup':
  18. console.log('Mouse up');
  19. setTimeout(function () { //<-- Give a few seconds to right click and Copy text, then go back to getting messages.
  20. get_messages_again = setInterval(function () {
  21. getMessages();
  22. }, 1000);
  23. },3000);
  24. break;
  25. }
  26. });

如果用户已经在与所选名称的对话中,那么通知也会消失。我只是在checknotifications()函数中附加了一个if/else,如下所示:

  1. //Check for new messages. Changes CSS of notification span to visible if new message is present.
  2. function checkNotifications() {
  3. $.ajax({
  4. url: 'includes/chat/check_notifications.php',
  5. type: 'post',
  6. dataType: 'json',
  7. success: function (data) {
  8. $.each(data, function (i, item) {
  9. console.log(item);
  10. $('.link').each(function () {
  11. //Get the current font-weight.
  12. //If it's above the norm, that means the user
  13. //is currently viewing messages and a notification
  14. //isn't needed.
  15. if($(this).css('font-weight') > 400) {
  16. $(this).parent().find('span').css('visibility', 'hidden');
  17. } else {
  18. //This code was already here.
  19. //Just made it part of the else statement
  20. if ($(this).parent().find('span').data('name') === item) {
  21. $(this).parent().find('span').css('visibility', 'visible');
  22. }
  23. }
  24. })
  25. })
  26. }
  27. })
  28. }
展开查看全部
omhiaaxx

omhiaaxx2#

重新加载动画(selection/gif动画)的一个解决方案是只加载新的入口,而保留旧的入口。所以不会重写。只是附加。

相关问题