Sumário AJAX Web Chat (Part 1) PHP e MySQL... 2 HTML... 2 Database Schema... 5 PHP... 7 AJAX Web Chat (Part 2) CSS and jquery... 20 CSS... 20 jquery... 27 1 P á g i n a
AJAX Web Chat (Part 1) PHP e MySQL Ao discutir a comunicação em tempo real, não há muitas soluções que podem rivalizar com o poder de um web chat simples. O que é ainda melhor, é que você já tem todas as ferramentas que você precisa para criar um - seu navegador. Neste duas partes tutorial, estaremos criando um chat AJAX Web utilizando PHP, MySQL e jquery. Nesta primeira parte, iremos discutir o PHP e MySQL lado, e na próxima semana vamos continuar com o jquery e CSS front-end. HTML Como de costume, o primeiro passo é estabelecer a marcação HTML. Nosso documento está estruturado como HTML5 para maior comodidade, pois isso nos permite usar o novo, mais curto (e mais memorável) doctype, e ignorar o atributo do tipo nas tags de script. ajax-chat.html <!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title></title> <!-- Carregando o JScrollPane CSS, juntamente com o estilo do conversar em chat.css eo resto da página em page.css --> <link rel="stylesheet" type="text/css" href="js/jscrollpane/jscrollpane.css" /> <link rel="stylesheet" type="text/css" href="css/page.css" /> <link rel="stylesheet" type="text/css" href="css/chat.css" /> 2 P á g i n a
</head> <body> <div id="chatcontainer"> <div id="chattopbar" class="rounded"></div> <div id="chatlineholder"></div> <div id="chatusers" class="rounded"></div> <div id="chatbottombar" class="rounded"> <div class="tip"></div> <form id="loginform" method="post" action=""> <input id="name" name="name" class="rounded" maxlength="16" /> <input id="email" name="email" class="rounded" /> <input type="submit" class="bluebutton" value="entrar" /> </form> <form id="submitform" method="post" action=""> <input id="chattext" name="chattext" class="rounded" maxlength="255" /> <input type="submit" class="bluebutton" value="enviar" /> </form> </div> </div> 3 P á g i n a
<!-- Carregar jquery, o plugin mousewheel e JScrollPane, juntamente com a nosso script.js --> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js "></script> <script src="js/jscrollpane/jquery.mousewheel.js"></script> <script src="js/jscrollpane/jscrollpane.min.js"></script> <script src="js/script.js"></script> </body> </html> Para otimizar o tempo de carregamento, as folhas de estilo estão incluídas na seção de cabeça, e os arquivos JavaScript no rodapé, pouco antes da tag body fechamento. Nós estamos usando o plugin JScrollPane para criar a área de rolagem com as entradas de bate-papos. Este plugin vem com seu próprio estilo, que é a primeira coisa que nós incluímos na página. A marcação do bate-papo é composto por quatro divs principais - a barra superior, o recipiente bate-papo, o container de usuário ea barra inferior. Este último tem o login e enviar formulários. A forma de envio é oculta por padrão e só aparece se o usuário tiver feito logon com sucesso no sistema de chat. 4 P á g i n a
Uma conversa AJAX Web com PHP, MySQL e jquery Por fim, incluímos os arquivos JavaScript. Começando com a biblioteca jquery, nós adicionamos o plugin mousewheel (usado por JScrollPane), o plugin JScrollPane si e nosso arquivo script.js. Database Schema Antes de seguir em frente com a parte PHP, primeiro temos que dar uma olhada em como os dados de bate-papo está organizada na base de dados MySQL. Para os fins deste script usamos duas tabelas. Em webchat_users estamos armazenando os participantes de bate-papo. Esta tabela tem na id, nome, gravatar e um campo last_activity. O campo de nome é definido como único, de modo que os usuários não têm nomes nick duplicados na sala de chat. 5 P á g i n a
Estrutura da tabela Outra característica útil dos campos de índice exclusivo, é que as consultas inserção falhará ea propriedade inserted_rows do objeto MySQLi será definido como zero se tentarmos inserir uma linha duplicada. Esta encontra seu lugar na classe PHP chat você verá na próxima etapa. A coluna last_activity tem um timestamp, que é atualizado a cada 15 segundos para cada usuário. Também é definida como um índice, por isso é mais rápido para excluir usuários inativos (com uma coluna last_activity com um valor superior a 15, significa que o usuário não é mais vendo a janela de chat). Estrutura da tabela 6 P á g i n a
A tabela webchat_lines detém as entradas de chat individuais. Observe que estamos armazenando o nome do autor e gravatar aqui também. Esta duplicação é que vale a pena, pois liberta-nos de usar uma junção caro ao solicitar as últimas conversas - o recurso acessados com mais frequência da aplicação. As definições dessas tabelas estão disponíveis no tables.sql no arquivo de download. Você pode executar o código em phpmyadmin para criá-los. Além disso, ao configurar o bate-papo em seu próprio país anfitrião, lembre-se de modificar ajax.php com seus bancos de dados MySQL detalhes de login. PHP Agora que temos o banco de dados no lugar, vamos começar a discutir os scripts PHP que impulsionam o chat. O primeiro arquivo, vamos dar uma olhada mais de perto, é ajax.php. Ele lida com as requisições AJAX enviados a partir do front-end jquery e saídas JSON dados formatados. ajax.php require "classes/db.class.php"; require "classes/chat.class.php"; require "classes/chatbase.class.php"; require "classes/chatline.class.php"; require "classes/chatuser.class.php"; session_name('webchat'); session_start(); if(get_magic_quotes_gpc()){ // Se magic quotes está habilitado, retirar as barras extras array_walk_recursive($_get,create_function('&$v,$k','$v = stripslashes($v);')); array_walk_recursive($_post,create_function('&$v,$k','$v = stripslashes($v);')); 7 P á g i n a
try{ // Conectando-se ao banco de dados DB::init($dbOptions); $response = array(); // Entrar com as ações apoiadas: switch($_get['action']){ case 'login': break; $response = Chat::login($_POST['name'],$_POST['email']); case 'checklogged': break; $response = Chat::checkLogged(); case 'logout': break; $response = Chat::logout(); case 'submitchat': break; $response = Chat::submitChat($_POST['chatText']); case 'getusers': break; $response = Chat::getUsers(); case 'getchats': 8 P á g i n a
break; $response = Chat::getChats($_GET['lastID']); default: throw new Exception('Ação errada'); echo json_encode($response); catch(exception $e){ die(json_encode(array('error' => $e->getmessage()))); Por conveniência, eu usei um switch simples para definir as ações, apoiadas pelo script. Estes incluem a apresentação chat, login / logout de funcionalidade, e as ações para solicitar uma lista de chats e usuários on-line. Toda a saída está na forma de mensagens de JSON (convenientemente manipulados por jquery), e os erros são obtidas sob a forma de excepções. O interruptor rotas declaração todas as solicitações para o método estático apropriado da classe bate-papo, que discutiremos mais adiante nesta seção. DB.class.php class DB { private static $instance; private $MySQLi; private function construct(array $dboptions){ $this->mysqli = @ new mysqli( $dboptions['db_host'], $dboptions['db_user'], $dboptions['db_pass'], $dboptions['db_name'] ); if (mysqli_connect_errno()) { throw new Exception('Database erro.'); $this->mysqli->set_charset("utf8"); 9 P á g i n a
public static function init(array $dboptions){ if(self::$instance instanceof self){ return false; self::$instance = new self($dboptions); public static function getmysqliobject(){ return self::$instance->mysqli; public static function query($q){ return self::$instance->mysqli->query($q); public static function esc($str){ return self::$instance->mysqli- >real_escape_string(htmlspecialchars($str)); A classe DB é o nosso gerente de banco de dados. O construtor é privado, o que significa que nenhum objeto pode ser criado a partir do exterior, ea inicialização só é possível a partir do método estático init (). É preciso uma matriz com MySQL detalhes de login, e cria uma instância da classe, realizada no self :: $ instance variável estática. Dessa forma, podemos ter certeza de que apenas uma conexão com o banco de dados pode existir no mesmo tempo. O resto das classes de tirar vantagem do método para comunicar com a base de dados de consulta estática (). ChatBase.class.php /* Esta é a classe base, usado por ambos chatline e ChatUser */ class ChatBase{ // Esse construtor é usado por todas as classes de bate-papo: public function construct(array $options){ foreach($options as $k=>$v){ 10 P á g i n a
if(isset($this->$k)){ $this->$k = $v; Esta é uma classe base simples. Seu objetivo principal é definir o construtor, que recebe um array com os parâmetros e salva apenas os que estão definidos na classe. ChatLine.class.php /* A ChatLine é usado para as entradas de bate-papo */ class ChatLine extends ChatBase{ protected $text = '', $author = '', $gravatar = ''; public function save(){ DB::query(" INSERT INTO webchat_lines (author, gravatar, text) VALUES ( '".DB::esc($this->author)."', '".DB::esc($this->gravatar)."', '".DB::esc($this->text)."' )"); // Retorna o objeto MySQLi da classe DB return DB::getMySQLiObject(); 11 P á g i n a
Aqui é a classe chatline. Estende-se ChatBase, assim você pode facilmente criar um objeto dessa classe, proporcionando uma matriz com um texto, autor e elementos Gravatar. A propriedade gravatar contém um hash md5 de e-mail da pessoa. Isso é necessário para que possamos buscar gravatar do usuário a partir gravatar.com. Essa classe também define um método save, que o objeto de nosso banco de dados. Como ele retorna o objeto MySQLi, contido na classe DB, você pode verificar se a gravação foi bemsucedida verificando a propriedade affected_rows (voltaremos a este na classe chat). ChatUser.class.php class ChatUser extends ChatBase{ protected $name = '', $gravatar = ''; public function save(){ DB::query(" INSERT INTO webchat_users (name, gravatar) VALUES ( '".DB::esc($this->name)."', '".DB::esc($this->gravatar)."' )"); return DB::getMySQLiObject(); public function update(){ DB::query(" INSERT INTO webchat_users (name, gravatar) VALUES ( '".DB::esc($this->name)."', '".DB::esc($this->gravatar)."' 12 P á g i n a
) ON DUPLICATE KEY UPDATE last_activity = NOW()"); O mesmo também é válido aqui. Nós temos o nome e as propriedades gravatar (notar o modificador de acesso protected - isso significa que eles estarão acessíveis na classe ChatBase, para que possamos colocá-las no construtor). A diferença é que nós também temos um método update (), que atualiza o timestamp last_activity para o tempo atual. Isso mostra que essa pessoa mantém uma janela de batepapo aberto e é exibido como on-line na seção de usuários. Chat.class.php Part 1 /* A classe Chart exploses métodos estáticos públicos, utilizados por ajax.php */ class Chat{ public static function login($name,$email){ if(!$name!$email){ throw new Exception('Preencha todos os campos obrigatórios'); if(!filter_input(input_post,'email',filter_validate_email)){ throw new Exception('Seu e-mail não é válido.'); // Preparando o hash gravatar: $gravatar = md5(strtolower(trim($email))); $user = new ChatUser(array( 'name' => $name, 13 P á g i n a
'gravatar' => $gravatar )); // O método save retorna um objeto MySQLi if($user->save()->affected_rows!= 1){ throw new Exception('Este nick está em uso.'); $_SESSION['user'] 'name' 'gravatar' = array( => $name, => $gravatar ); return array( 'status' => 1, 'name' 'gravatar' => $name, => Chat::gravatarFromHash($gravatar) ); public static function checklogged(){ $response = array('logged' => false); if($_session['user']['name']){ $response['logged'] = true; $response['loggedas'] = array( 'name' => $_SESSION['user']['name'], 'gravatar' => Chat::gravatarFromHash($_SESSION['user']['gravatar']) 14 P á g i n a
); return $response; public static function logout(){ DB::query("DELETE FROM webchat_users WHERE name = '".DB::esc($_SESSION['user']['name'])."'"); $_SESSION = array(); unset($_session); return array('status' => 1); Este é o lugar onde todo o trabalho é feito. Lembre-se da instrução switch em ajax.php acima? Ele mapeia as acções apoiadas pelos métodos correspondentes da classe. Cada um destes métodos retorna uma matriz, tal como é posteriormente convertido para um objeto JSON com o json_encode interno () função (o que acontece na parte inferior do ajax.php). Quando o usuário faz login, o seu nome e gravatar ser salvo como elementos do array $ _SESSION, e ficam disponíveis sobre os pedidos consecutivos. Nós estaremos usando isso para validar se o usuário tem permissão para adicionar chats mais tarde. Você também pode ver como estamos preparando o hash gravatar. Isto é feito de acordo com o seu guia de melhores práticas e garante que, se a pessoa tenha configurado um Gravatar, será adequadamente exibidos. Chat.class.php Part 2 public static function submitchat($chattext){ if(!$_session['user']){ 15 P á g i n a
throw new Exception('Você não está logado'); if(!$chattext){ throw new Exception(' Você haven\'entrou em uma mensagem de bate-papo.'); $chat = new ChatLine(array( 'author' 'gravatar' 'text' => $_SESSION['user']['name'], => $_SESSION['user']['gravatar'], => $chattext )); // O método save retorna um objeto MySQLi $insertid = $chat->save()->insert_id; return array( 'status' => 1, 'insertid' => $insertid ); public static function getusers(){ if($_session['user']['name']){ $user = new ChatUser(array('name' => $_SESSION['user']['name'])); $user->update(); 16 P á g i n a
// Exclusão de chats com mais de 5 minutos e usuários inativos por 30 segundos DB::query("DELETE FROM webchat_lines WHERE ts < SUBTIME(NOW(),'0:5:0')"); DB::query("DELETE FROM webchat_users WHERE last_activity < SUBTIME(NOW(),'0:0:30')"); $result = DB::query('SELECT * FROM webchat_users ORDER BY name ASC LIMIT 18'); $users = array(); while($user = $result->fetch_object()){ $user->gravatar = Chat::gravatarFromHash($user- >gravatar,30); $users[] = $user; return array( 'users' => $users, 'total' => DB::query('SELECT COUNT(*) as cnt FROM webchat_users')->fetch_object()->cnt ); public static function getchats($lastid){ $lastid = (int)$lastid; $result = DB::query('SELECT * FROM webchat_lines WHERE id > '.$lastid.' ORDER BY id ASC'); 17 P á g i n a
$chats = array(); while($chat = $result->fetch_object()){ // Retornando a hora GMT (UTC), da criação de bate-papo: $chat->time = array( 'hours' 'minutes' => gmdate('h',strtotime($chat->ts)), => gmdate('i',strtotime($chat->ts)) ); $chat->gravatar = Chat::gravatarFromHash($chat- >gravatar); $chats[] = $chat; return array('chats' => $chats); public static function gravatarfromhash($hash, $size=23){ return 'http://www.gravatar.com/avatar/'.$hash.'?size='.$size.'&default='. urlencode('http://www.gravatar.com/avatar/ad516503a11cd5ca435acc9bb6 523536?size='.$size); Como você vai ver em a próxima parte da este tutorial, jquery envia uma getusers () o solicitem cada 15 segundos. Nós estamos usando esse para excluir chats mais velho do que 5 minutos e usuários inativos a partir da banco de dados. Nós poderíamos, potencialmente, excluir esses registros em getchats, mas que é solicitado uma vez a cada segundo e o tempo de processamento extra poderia impactar severamente o desempenho de o nosso app. 18 P á g i n a
Outra coisa pena notar, é que, no método getchats (), nós estamos usando a função de gmdate para a saída de um tempo GMT. In o frontend, nós usar os horas e minuto valores para alimentar o objeto de data JavaScript, e, como resultado de todas as vezes são exibidos em tempo local do usuário. 19 P á g i n a
Fazer um AJAX Web Chat (Part 2) CSS and jquery Na segunda parte deste tutorial em duas partes, estaremos criando o jquery e CSS final frente ao nosso Web chat AJAX. Na primeira parte, discutimos a PHP e MySQL lado. Agora vamos continuar de onde paramos da última vez. Os estilos de bate-papo são auto-suficientes e residem em chat.css. Estes estilos são independentes do restante da página, por isso é mais fácil de incorporar a janela de chat em um site existente. Você só precisa incluir a marcação HTML discutimos na semana passada, e incluem a folha de estilo e arquivos JavaScript. CSS chat.css - Parte 1: /* Principal recipiente bate-papo */ #chatcontainer{ width:510px; margin:100px auto; position:relative; /* Barra de Início (Top bar)*/ 20 P á g i n a
#chattopbar{ height:40px; background:url('../img/solid_gray.jpg') repeat-x #d0d0d0; border:1px solid #fff; margin-bottom:15px; position:relative; color:#777; text-shadow:1px 1px 0 #FFFFFF; #chattopbar.name{ position:absolute; top:10px; left:40px; #chattopbar img{ left:9px; position:absolute; top:8px; /* Bate-papo (Chats) */ #chatlineholder{ height:360px; width:350px; margin-bottom:20px; outline:none;.chat{ background:url('../img/chat_line_bg.jpg') repeat-x #d5d5d5; min-height:24px; padding:6px; border:1px solid #FFFFFF; padding:8px 6px 4px 37px; position:relative; margin:0 10px 10px 0;.chat:last-child{ margin-bottom:0; 21 P á g i n a
.chat.gravatar{ background:url('http://www.gravatar.com/avatar/ad516503a11cd5ca435acc9 bb6523536?size=23') no-repeat; left:7px; position:absolute; top:7px;.chat img{ display:block; visibility:hidden; Começamos por denominar o div # chatcontainer. Centrada na página horizontalmente, com a ajuda de uma margem de automática. Como você viu na parte anterior do tutorial, esta div é dividido em uma barra superior, área de chats, área do usuário, e na barra inferior. A barra superior mostra as informações de login do usuário. É atribuído um posicionamento relativo de modo a que o botão avatar, nome e sair podem ser posicionados em conformidade. Depois vem o div que contém todos os chats - # chatlineholder. Esta div tem uma largura fixa e altura, e como você vai ver na parte jquery deste tutorial, estamos usando o plugin JScrollPane para transformá-lo em uma área de rolagem de fantasia com barras laterais personalizados. 22 P á g i n a
chat.css Part 2 /* Área do Usuário */ #chatusers{ background-color:#202020; border:1px solid #111111; height:360px; position:absolute; right:0; top:56px; width:150px; #chatusers.user{ 23 P á g i n a
background:url('http://www.gravatar.com/avatar/ad516503a11cd5ca435ac c9bb6523536?size=30') no-repeat 1px 1px #444444; border:1px solid #111111; float:left; height:32px; margin:10px 0 0 10px; width:32px; #chatusers.user img{ border:1px solid #444444; display:block; visibility:hidden; /* Bottom Bar */ #chatbottombar{ background:url('../img/solid_gray.jpg') repeat-x #d0d0d0; position:relative; padding:10px; border:1px solid #fff; #chatbottombar.tip{ position:absolute; width:0; height:0; 24 P á g i n a
border:10px solid transparent; border-bottom-color:#eeeeee; top:-20px; left:20px; #submitform{ display:none; Na segunda parte, o estilo do recipiente e as divs do usuário #chatusers. Cada usuário de bate-papo ativo é representado por um ícone de 32 por 32 px (gravatar). O único efeito é definido como um fundo, e quando as imagens de fundo reais são carregadas, que são mostrados de cima delas. Isso impede que a cintilação irritante que geralmente ocorreria antes da imagem ser carregada. O resto do código trata da barra inferior e as formas de enviar. Você pode achar interessante a forma como o div. A Dica é transformar em um triângulo CSS puro utilizando uma altura zero e largura, junto com um valor grande na fronteira. Eu já usei esse truque em tutoriais anteriores. chat.css Part 3 /* Substituindo os estilos padrão de JScrollPanel*/.jspVerticalBar{ background:none; width:20px;.jsptrack{ background-color:#202020; border:1px solid #111111; 25 P á g i n a
width:3px; right:-10px;.jspdrag { background:url('../img/slider.png') no-repeat; width:20px; left:-9px; height:20px!important; margin-top:-5px;.jspdrag:hover{ background-position:left bottom; /* Estilos adicionais */ #chatcontainer.bluebutton{ background:url('../img/button_blue.png') no-repeat; border:none!important; color:#516d7f!important; display:inline-block; font-size:13px; height:29px; text-align:center; text-shadow:1px 1px 0 rgba(255, 255, 255, 0.4); width:75px; margin:0; 26 P á g i n a
cursor:pointer; #chatcontainer.bluebutton:hover{ background-position:left bottom; Na última parte do código, substituir o estilo padrão da div JScrollPane. Por padrão, ele é mostrado com barras de rolagem roxo, o que não é muito apropriado para o nosso projeto. Em vez de codificação nosso próprio estilo a partir do zero, nós apenas incluir o default e substituir algumas das regras. Finalmente, você pode ver os estilos do botão azul. Pode-se atribuir essa classe a qualquer âncora regular ou botão, e você terá um botão azul bonito. jquery Movendo-se para a última etapa deste tutorial - o código jquery. O chat funciona através de escuta para eventos de login e enviar formulários (eo botão de logout), e com o agendamento do pedido AJAX de volta para o servidor para verificação de novas conversas e usuários. Como você viu na primeira parte do tutorial, na semana passada, no lado do PHP as requisições AJAX são manipulados por ajax.php. questões jquery um número de requisições AJAX: Registrando um usuário: isso é feito por uma única solicitação POST; Registrando um usuário fora: também uma única solicitação POST; Verificação para usuários logados: isso é feito uma vez a cada 15 segundos; Verificação de novos chats: uma requisição GET é disparado a cada segundo. Isso poderia significar uma carga pesada em seu servidor, é por isso que o script é otimizado no back-end, e dependendo da atividade do bate-papo, os pedidos são reduzidos para um a cada 15 segundos. 27 P á g i n a
Como você vai ver no código abaixo, temos definido wrapper personalizado para jquery $.get e $.post. que vai nos ajudar em não ter que preencher todos os parâmetros longos para a emissão de um pedido. Além disso, todo o código de bate-papo está organizada em um único objeto chamado chat. Trata-se de uma série de métodos úteis, que você vai ver nos fragmentos abaixo. script.js Part 1 $(document).ready(function(){ chat.init(); ); var chat = { // dados contém variáveis para uso na classe: data : { lastid : 0, noactivity : 0, // Init liga ouvintes de evento e configura timers: init : function(){ // Usa o plugin jquery texto padrão, incluídos na parte inferior: $('#name').defaulttext('nickname'); $('#email').defaulttext('email (Gravatars are Enabled)'); // Convertendo o div #chatlineholder em um JScrollPane, // e salvar API do plugin em chat.data: chat.data.jspapi = $('#chatlineholder').jscrollpane({ 28 P á g i n a
verticaldragminheight: 12, verticaldragmaxheight: 12 ).data('jsp'); // Nós usamos a variável trabalhando para evitar // vários envios de formulários: var working = false; // Registrando uma pessoa no bate-papo: $('#loginform').submit(function(){ if(working) return false; working = true; // Usando a nossa função tzpost wrapper function // (definido em baixo): $.tzpost('login',$(this).serialize(),function(r){ working = false; if(r.error){ chat.displayerror(r.error); else chat.login(r.name,r.gravatar); ); ); return false; O objetivo do método init () é ligar todos os manipuladores de eventos para o bate-papo e começar as funções de tempo de espera que são usados para programar as verificações para novas conversas e usuários on-line. Você pode ver que nós usamos nossas próprias funções 29 P á g i n a
wrapper - $.tzget and $.tzpost. Estes levantar o fardo de ter que especificar uma longa lista de parâmetros e metas para as solicitações do Ajax. script.js Part 2 // Enviar uma nova entrada de bate-papo: $('#submitform').submit(function(){ var text = $('#chattext').val(); if(text.length == 0){ return false; if(working) return false; working = true; // Atribuir um ID temporário para o bate-papo: var tempid = 't'+math.round(math.random()*1000000), params = { id author gravatar : tempid, : chat.data.name, : chat.data.gravatar, text : text.replace(/</g,'<').replace(/>/g,'>') ; // Usando nosso método addchatline para adicionar o bate-papo // a tela imediatamente, sem esperar // o pedido AJAX para completar: 30 P á g i n a
chat.addchatline($.extend({,params)); // Usando o nosso método de invólucro tzpost para enviar o bate-papo // através de uma solicitação 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; ); // Desligar o usuário: $('a.logoutbutton').live('click',function(){ $('#chattopbar > span').fadeout(function(){ ); $(this).remove(); $('#submitform').fadeout(function(){ ); $('#loginform').fadein(); $.tzpost('logout'); 31 P á g i n a
return false; ); // Verificar se o usuário já está conectado (browser actualização) $.tzget('checklogged',function(r){ if(r.logged){ chat.login(r.loggedas.name,r.loggedas.gravatar); ); // Auto executar funções de tempo limite (function getchatstimeoutfunction(){ )(); chat.getchats(getchatstimeoutfunction); (function getuserstimeoutfunction(){ )(); chat.getusers(getuserstimeoutfunction);, Na segunda parte do script, vamos continuar com ouvintes de eventos de ligação. No formulário, você pode ver que quando o usuário adiciona um novo bate-papo, um temporário é criado e mostrado imediatamente, sem esperar que o pedido AJAX para ser concluído. Uma vez que a escrita tenha completado, o papo temporária é removida da tela. Isso dá aos usuários a sensação de que o bate-papo é muito rápido, enquanto o verdadeiro gravação é feita em segundo plano. Perto do fim do método init, corremos dois executores funções nomeadas auto. As próprias funções são passados como parâmetros para o respectivo chat.getchats () ou chat.getusers () método, de modo que o tempo limite adicionais podem ser programados (você pode ver isso na parte 5 do código). 32 P á g i n a
script.js Part 3 // O método de login esconde exibe os // doados de login do usuário e mostra o formulário de envio login : function(name,gravatar){ chat.data.name = name; chat.data.gravatar = gravatar; $('#chattopbar').html(chat.render('logintopbar',chat.data)); $('#loginform').fadeout(function(){ $('#submitform').fadein(); $('#chattext').focus(); );, // O método de renderização gera a marcação HTML // que é necessário para os outros métodos: render : function(template,params){ var arr = []; switch(template){ case 'logintopbar': arr = [ '<span><img src="',params.gravatar,'" width="23" height="23" />', '<span class="name">',params.name, 33 P á g i n a
rounded">logout</a></span>']; break; '</span><a href="" class="logoutbutton case 'chatline': arr = [ '<div class="chat chat-',params.id,' rounded"><span class="gravatar">'+ '<img src="',params.gravatar,'" width="23" height="23" '+ 'onload="this.style.visibility=\'visible\'" />', '</span><span class="author">',params.author, ':</span><span class="text">',params.text, '</span><span class="time">',params.time,'</span></div>']; break; case 'user': arr = [ '<div class="user" title="',params.name,'"><img src="',params.gravatar, '" width="30" height="30" onload="this.style.visibility=\'visible\'"'+ ' /></div>' ]; break; 34 P á g i n a
//concatenações // A única junção matriz é mais rápido do que várias return arr.join('');, Aqui, o método render () merece mais de nossa atenção. O que faz, é montar um modelo, dependendo do parâmetro molde passado. O método então cria e retorna o código HTML solicitado, incorporando os valores do segundo parâmetro - os Parâmetros objeto como necessário. Isto é utilizado pela maioria dos outros métodos aqui discutidos. script.js Part 4 // O método addchatline adicionar uma entrada de bate-papo para a //página. addchatline : function(params){ // Todos os horários são exibidos no fuso horário do usuário var d = new Date(); if(params.time) { // PHP retorna a hora em UTC (GMT). Vamos utilizá-lo //para alimentar o data // objeto e depois mostrar em fuso horário do usuário. // JavaScript e converte e para nós. d.setutchours(params.time.hours,params.time.minutes); params.time = (d.gethours() < 10? '0' : '' ) + d.gethours()+':'+ 35 P á g i n a
(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){ / / Se este for o primeiro de chat, remover o parágrafo: $('#chatlineholder p').remove(); // Se isto não é um bate-papo temporário: 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); // Como nós adicionamos novos conteúdos, precisamos // reinicializar o plugin JScrollPanel: chat.data.jspapi.reinitialise(); 36 P á g i n a
chat.data.jspapi.scrolltobottom(true);, O método addchat () leva um objeto de parâmetro com o conteúdo do bate-papo, o autor e gravatar, e insere a nova linha de bate-papo em local apropriado no # chatcontainer div. Cada chat (se não for um temporário) tem uma identificação única que é atribuído pelo MySQL. Essa identificação é atribuído como um nome de classe para o bate-papo na forma de chat-123. Quando o método addchat () é executado, ele verifica se existe a entrada de bate-papo anterior (para chat-123 que iria verificar chat-122). Se ela existe, ele insere o novo bate-papo depois. Se isso não acontecer, ele só acrescenta à div. Esta técnica simples consegue inserir todos os bate-papos na ordem certa e mantê-los dessa forma. Tempo em fuso horário do Usuário script.js Part 5 // Este método solicita as últimas conversas // (desde lastid), e as adiciona à página. 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]); 37 P á g i n a
if(r.chats.length){ chat.data.noactivity = 0; chat.data.lastid = r.chats[i-1].id; else{ // Se não foram recebidas conversas, incremento // o contador noactivity. chat.data.noactivity++; if(!chat.data.lastid){ chat.data.jspapi.getcontentpane().html('<p class="nochats">no chats yet</p>'); // A definição de um limite de tempo para a próxima // solicitação, dependendo da atividade de bate-papo: var nextrequest = 1000; // 2 segundos if(chat.data.noactivity > 3){ nextrequest = 2000; if(chat.data.noactivity > 10){ nextrequest = 5000; 38 P á g i n a