verfaa
Профессор
- Регистрация
- 29 Янв 2007
- Сообщения
- 417
- Реакции
- 49
- Автор темы
- #1
Нужно прикрутить на сайт знакомств вебмессенджер, где пользователи могли бы общаться один на один. Покопавшись в нете, ничего подходящего толком не нашев, я решил взять за основу чат, который подробно описан в этих двух уроках:
Для просмотра ссылки Войдиили Зарегистрируйся
Для просмотра ссылки Войдиили Зарегистрируйся
Опыта в программировании у меня немного, а опыта работы с JS совсем мало, поэтому с доработкой скрипта до вебмессенджера возникли трудности. Скрипт с руселлера я немного переработал, убрал из него ненужные на мой взгляд куски кода, дописал свой код, в результате пользователи могут отправлять друг другу сообщения и получать их.
Но в руселлерском чате не сделана постраничная навигация сообщений, в результате чего все сообщения сразу подгружаются на страницу. А сообщений может быть много, 1000 например или больше и все они будут пытаться загрузиться на страницу, будет не очень хорошо, нужна постраничная навигация, как это сделано на mamba.ru или loveplanet.ru
Вот код, который я имею на данный момент:
HTML + JS
В скрипт айди пользователя, с которым общается юзер, я передаю в обычном GET-запросе, т.е. в анкете есть ссылка <a href='im.php?resp=29476'>написать сообщение</a> - юзер её кликает и попадает на страницу с чатом и начинает общение)
im_ajax.php
В результате в массив pages_arr попадают нужные элементы (вижу в файрбаге) - ссылки, но как их добавить на страницу ума не приложу. В JS в
Для просмотра ссылки Войди
Для просмотра ссылки Войди
Опыта в программировании у меня немного, а опыта работы с JS совсем мало, поэтому с доработкой скрипта до вебмессенджера возникли трудности. Скрипт с руселлера я немного переработал, убрал из него ненужные на мой взгляд куски кода, дописал свой код, в результате пользователи могут отправлять друг другу сообщения и получать их.
Но в руселлерском чате не сделана постраничная навигация сообщений, в результате чего все сообщения сразу подгружаются на страницу. А сообщений может быть много, 1000 например или больше и все они будут пытаться загрузиться на страницу, будет не очень хорошо, нужна постраничная навигация, как это сделано на mamba.ru или loveplanet.ru
Вот код, который я имею на данный момент:
HTML + JS
Код:
<div id="chatContainer">
<div id="chatTopBar" class="rounded"></div>
<div id="chatLineHolder"></div>
<div id="chatBottomBar" class="rounded">
<div class="tip"></div>
<form id="submitForm" method="post" action="">
<textarea id="chatText" name="chatText" class="rounded" maxlength="255"></textarea><br />
<input type="submit" class="blueButton" value="Send msg!" />
</form>
</div>
</div>
<div id="num_pages"></div>
<script src="{$site_root}{$template_root}/js/im_jquery.mousewheel.js"></script>
<script src="{$site_root}{$template_root}/js/im_jScrollPane.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
// Запускаем метод init, когда документ будет готов:
chat.init();
});
var chat = {
// data содержит перменные для использования в классах:
data : {
lastID : 0,
noActivity : 0
},
// Init привязывает обработчики событий и устанавливает таймеры:
init : function(){
// Конвертируем div #chatLineHolder в jScrollPane,
// сохраняем API плагина в chat.data:
chat.data.jspAPI = $('#chatLineHolder').jScrollPane({
verticalDragMinHeight: 12,
verticalDragMaxHeight: 12
}).data('jsp');
// Используем перменную working для предотвращения
// множественных отправок формы:
var working = false;
// Отправляем данные новой строки чата:
$('#submitForm').submit(function(){
var text = $('#chatText').val();
if(text.length == 0){
return false;
}
if(working) return false;
working = true;
// Генерируем временный ID для чата:
var tempID = 't'+Math.round(Math.random()*1000000),
params = {
id : tempID,
author : chat.data.name,
gravatar : chat.data.gravatar,
text : text.replace(/</g,'<').replace(/>/g,'>')
};
// Используем метод addChatLine, чтобы добавить чат на экран
// немедленно, не ожидая заверщения запроса AJAX:
chat.addChatLine($.extend({},params));
// Используем метод tzPOST, чтобы отправить чат
// черех запрос POST AJAX:
$.tzPOST('submitChat',$(this).serialize(),function(r){
working = false;
$('#chatText').val('');
$('div.chat-'+tempID).remove();
params['id'] = r.insertID;
chat.addChatLine($.extend({},params));
});
return false;
});
// Самовыполняющиеся функции таймаута
(function getChatsTimeoutFunction(){
chat.getChats(getChatsTimeoutFunction);
})();
},
// Метод render генерирует разметку HTML,
// которая нужна для других методов:
render : function(template,params){
var arr = [];
switch(template){
case 'chatLine':
arr = [
'<div class="chat chat-',params.id,' rounded"><span class="author">',params.author,
':</span><span class="text">',params.text,'</span><span class="time">',params.time,'</span></div>'];
break;
}
// Единственный метод join для массива выполняется
// бысстрее, чем множественные слияния строк
return arr.join('');
},
// Метод addChatLine добавляет строку чата на страницу
addChatLine : function(params){
// Все показания времени выводятся в формате временного пояса пользователя
var d = new Date();
if(params.time) {
// PHP возвращает время в формате UTC (GMT). Мы используем его для формирования объекта date
// и дальнейшего вывода в формате временного пояса пользователя.
// JavaScript конвертирует его для нас.
d.setUTCHours(params.time.hours,params.time.minutes);
}
params.time = (d.getHours() < 10 ? '0' : '' ) + d.getHours()+':'+
(d.getMinutes() < 10 ? '0':'') + d.getMinutes();
var markup = chat.render('chatLine',params),
exists = $('#chatLineHolder .chat-'+params.id);
if(exists.length){
exists.remove();
}
if(!chat.data.lastID){
// Если это первая запись в чате, удаляем
// параграф с сообщением о том, что еще ничего не написано:
$('#chatLineHolder p').remove();
}
// Если это не временная строка чата:
if(params.id.toString().charAt(0) != 't'){
var previous = $('#chatLineHolder .chat-'+(+params.id - 1));
if(previous.length){
previous.after(markup);
}
else chat.data.jspAPI.getContentPane().append(markup);
}
else chat.data.jspAPI.getContentPane().append(markup);
// Так как мы добавили новый контент, нужно
// снова инициализировать плагин jScrollPane:
chat.data.jspAPI.reinitialise();
chat.data.jspAPI.scrollToBottom(true);
},
// Данный метод запрашивает последнюю запись в чате
// (начиная с lastID), и добавляет ее на страницу.
getChats : function(callback){
$.tzGET('getChats',{lastID: chat.data.lastID},function(r){
for(var i=0;i<r.chats.length;i++){
chat.addChatLine(r.chats[i]);
}
if(r.chats.length){
chat.data.noActivity = 0;
chat.data.lastID = r.chats[i-1].id;
}
else{
// Если нет записей в чате, увеличиваем
// счетчик noActivity.
chat.data.noActivity++;
}
if(!chat.data.lastID){
chat.data.jspAPI.getContentPane().html('<p class="noChats">Ничего еще не написано</p>');
}
// Устанавливаем таймаут для следующего запроса
// в зависимости активности чата:
var nextRequest = 1000;
// 2 секунды
if(chat.data.noActivity > 3){
nextRequest = 2000;
}
if(chat.data.noActivity > 10){
nextRequest = 5000;
}
// 15 секунд
if(chat.data.noActivity > 20){
nextRequest = 15000;
}
setTimeout(callback,nextRequest);
});
},
// Данный метод выводит сообщение об ошибке наверху страницы:
displayError : function(msg){
var elem = $('<div>',{
id : 'chatErrorMessage',
html : msg
});
elem.click(function(){
$(this).fadeOut(function(){
$(this).remove();
});
});
setTimeout(function(){
elem.click();
},5000);
elem.hide().appendTo('body').slideDown();
}
};
// Формирование GET & POST:
$.tzPOST = function(action,data,callback){
$.post('im_ajax.php?action='+action+'&resp={$respondent}',data,callback,'json');
}
$.tzGET = function(action,data,callback){
$.get('im_ajax.php?action='+action+'&resp={$respondent}',data,callback,'json');
}
</script>
В скрипт айди пользователя, с которым общается юзер, я передаю в обычном GET-запросе, т.е. в анкете есть ссылка <a href='im.php?resp=29476'>написать сообщение</a> - юзер её кликает и попадает на страницу с чатом и начинает общение)
im_ajax.php
Код:
<?php
// Если к нам идёт Ajax запрос, то ловим его
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
// тут подключаем базу данных, стартуем сессию, включаем необходимые библиотеки...
$user = auth_index_user(); // Авторизуем юзера
$id_user = intval($user[0]); // Тут будет айди юзера
$response = array();
switch($_GET['action']){
//Добавляем сообщение в базу
case 'submitChat':
$strSQL = "INSERT INTO pro_im_lines (id_user, id_respondent, text)
VALUES (
'".$id_user."',
'".mysql_real_escape_string($_REQUEST['resp'])."',
'".mysql_real_escape_string($_POST['chatText'])."'
)";
$dbconn->Execute($strSQL);
$rs = $dbconn->Execute("SELECT LAST_INSERT_ID() FROM pro_im_lines");
$response = array(
'status' => 1,
'insertID' => $rs->fields[0]
);
break;
case 'getChats':
// Получаем сообщения из базы, которые мы отправляли
// собеседнику и которые собеседник отправлял нам, только 10 последних!
$strSQL = "(SELECT * FROM pro_im_lines WHERE
((id_user='".$id_user."' AND
id_respondent='".intval($_REQUEST['resp'])."') OR
(id_user='".intval($_REQUEST['resp'])."' AND
id_respondent='".$id_user."')) AND
id > '".intval($_GET['lastID'])."' ORDER BY id DESC LIMIT 10)
ORDER BY id ASC";
$rs = $dbconn->Execute($strSQL);
$i = 0;
$chats = array();
while(!$rs->EOF){
$row = $rs->GetRowAssoc(false);
$chats[$i]["id"] = $row["id"];
$chats[$i]["author"] = $row["id_respondent"];
$chats[$i]["text"] = $row["text"];
$chats[$i]["ts"] = $row["ts"];
$chats[$i]["time"] = array(
'hours' => gmdate('H',strtotime($chats[$i]["ts"])),
'minutes' => gmdate('i',strtotime($chats[$i]["ts"]))
);
$rs->MoveNext();
$i++;
}
// В результате в массиве $chats окажутся все сообщения, которые мы отправляли
// собеседнику и которые собеседник отправлял нам.
// Этот массив мы отправляем обратно в JS ниже - echo json_encode($response);
// А тут я пытался сделать постраничный вывод:
// Выбираем все сообщения, которые мы отправляли друг другу
$strSQL = "SELECT * FROM pro_im_lines WHERE
(id_user='".$id_user."' AND
id_respondent='".intval($_REQUEST['resp'])."') OR
(id_user='".intval($_REQUEST['resp'])."' AND
id_respondent='".$id_user."')";
$rs = $dbconn->Execute($strSQL);
$row_count = $rs->RowCount(); //считаем число строк в таблице с сообщениями
$pages = ceil($row_count/10);//определим количество страниц
$pages_arr = array();
if($pages>1){
for($i=1;$i<=$pages;$i++){
$pages_arr[] = "<a href=\"javascript:ajax_get_data('.$page-1.');\">'.$i.' </a>";
}
}
$response = array('chats' => $chats, 'pages_arr' => $pages_arr);
break;
}
echo json_encode($response);
}
...
?>
В результате в массив pages_arr попадают нужные элементы (вижу в файрбаге) - ссылки, но как их добавить на страницу ума не приложу. В JS в
возвратную функцию пытался добавить
for(var i=0;i<r. pages_arr.length;i++){
$("#num_pages").appendTo(r.pages_arr);
}
но ничего не добавляет, а в файрбаге в firefox только ошибку вываливает((
Подскажите плиз, как мне сделать постраничную навигацию в моем случае и чтобы когда пользователь кликает скажем на 5-ю страницу нужные сообщения через ajax подкружались в окно чата.
И в целом по коду, может его можно оптимизировать как-то, удалить ненужные части или добавить что-то? Понимаю что много написал, очень надеюсь на помощь и советы...