AJAX WEB CHAT PHP, MYSQL, JQUERY, CSS3, HTML5 BY ALISSONBORGES



Documentos relacionados
Posicionamento e Layout com CSS

02 - Usando o SiteMaster - Informações importantes

Programação para Internet I

DOCUMENTAÇÃO DO FRAMEWORK - versão 2.0

Programação Orientada a Objetos com PHP & MySQL Cookies e Sessões. Prof. MSc. Hugo Souza

Trabalhando com conexão ao banco de dados MySQL no Lazarus. Prof. Vitor H. Migoto de Gouvêa Colégio IDESA 2011

Acessando um Banco de Dados

Vamos criar uma nova Página chamada Serviços. Clique em Adicionar Nova.

Programação Web com PHP. Prof. Wylliams Barbosa Santos Optativa IV Projetos de Sistemas Web

UNIVERSIDADE FEDERAL DO AMAPÁ PRÓ REITORIA DE ADMINISTRAÇÃO E PLANEJAMENTO DEPARTAMENTO DE INFORMÁTICA. Manual do Moodle- Sala virtual

JavaScript. JavaScript é uma linguagem de script usada em navegadores web. É uma linguagem dinâmica, estruturada e orientada em objetos.

WEBDESIGN. Professor: Paulo Marcos Trentin - paulo@paulotrentin.com.br Escola CDI de Videira

mkdir /srv/www/default/html/calculadora/imagens mkdir /srv/www/default/html/calculadora/blocos

Programando em PHP. Conceitos Básicos

MANUAL DE MEMBRO COMUNIDADE DO AMIGO

English Português. By erickalves 25 Julho, :08. Devido à política (#) de segurança. Encontrar Blogs Crie o seu blog de graça Ganhe prêmios

Desenvolvimento de Aplicações para Internet Aula 11

WEBDESIGN. Professor: Paulo Marcos Trentin - paulo@paulotrentin.com.br Escola CDI de Videira

A barra de menu a direita possibilita efetuar login/logout do sistema e também voltar para a página principal.

Bem- Vindo ao manual de instruções do ECO Editor de COnteúdo.

Manual de Gerenciamento de Conteúdo

Listando itens em ComboBox e gravando os dados no Banco de Dados MySQL.

jquery André Tavares da Silva

Omega Tecnologia Manual Omega Hosting

Manual de configuração do sistema

MANUAL MIKOGO 1. VISÃO GERAL

FERRAMENTAS DE COLABORAÇÃO CORPORATIVA

Desenvolvendo Websites com PHP


Manual de utilização do site de contatos

AULA 4 VISÃO BÁSICA DE CLASSES EM PHP

Scriptlets e Formulários

Programação WEB II. Sessions e Cookies. progweb2@thiagomiranda.net. Thiago Miranda dos Santos Souza

1 - Entrando no Sistema

Roteiro 2: Conceitos de Tags HTML

Material de apoio a aulas de Desenvolvimento Web. Tutorial Java WEB JSP & HTML & CSS & CLASSE & OBJETOS. AAS -

Gravando uma Áudio Conferência

JavaScript (Funções, Eventos e Manipulação de Formulários)

Sistema de Gerenciamento Remoto

Desenvolvedor Web Docente André Luiz Silva de Moraes

Memória Flash. PdP. Autor: Tiago Lone Nível: Básico Criação: 11/12/2005 Última versão: 18/12/2006. Pesquisa e Desenvolvimento de Produtos

Plataforma Manual do Administrador/Revenda

Programação para Internet

Portal Sindical. Manual Operacional Empresas/Escritórios

Novell. Novell Teaming 1.0. novdocx (pt-br) 6 April 2007 EXPLORAR O PORTLET BEM-VINDO DESCUBRA SEU CAMINHO USANDO O NOVELL TEAMING NAVIGATOR

TRANSMISSOR ECF. Sistema de transmissão de arquivos Nota Fiscal Paulista. Manual de Utilização

Manual do Usuário CFCWeb BA

NewAgent enterprise-brain

BEM-VINDO AO dhl PROVIEW

Diazo. Módulo 7 Tema Diazo

Abaixo você conhecerá algumas técnicas de SEO utilizadas para obter grande sucesso com as postagens no WordPress.

Fluxo de trabalho do Capture Pro Software: Indexação de OCR e separação de documentos de código de correção

TUTORIAL PARA CONFIGURAÇÃO DE SEU SITE SITES GRÁTIS

2 echo "PHP e outros.";

Programa Intel Educar Tutorial: Ferramenta de Classificação Visual

Manual de Publicaça o no Blog da Aça o TRIBOS nas Trilhas da Cidadania

Imagens: <img src="..."> src <img src="tecnologia.jpg"> único atributo que não pode ser omitido neste TAG Nota: img

Basicamente iremos precisar de uma base de dados na qual iremos armazenar os registros feitos pelos vistantes: Vamos armazenar os seguintes dados:

Facebook Instruções de integração com PayPal

GUIA RÁPIDO DE UTILIZAÇÃO DO PORTAL DO AFRAFEP SAÚDE

Manual das funcionalidades Webmail AASP

Repeater no GASweb. Regiões

OI CONTA EMPRESA MANUAL DO USUÁRIO

1. Introdução pág.3 2. Apresentação do sistema Joomla! pág.4 3. Acessando a administração do site pág.4 4. Artigos 4.1. Criando um Artigo 4.2.

"Manual de Acesso ao Moodle - Discente" 2014

MANUAL DO ANIMAIL Terti Software

Controle de acesso. .com.br

UNIVERSIDADE FEDERAL DO RIO GRANDE DO NORTE ESCOLA AGRÍCOLA DE JUNDIAÍ EAJ - PRONATEC / REDE etec MÓDULO III DESENVOLVIMENTO PROFESSOR ADDSON COSTA

Google Drive. Passos. Configurando o Google Drive

Portal da Prefeitura de São Paulo SECOM. MANUAL DO WARAM v. 1.5 Secretarias

Utilizando Janelas e Frames

Manual de utilização do sistema de envio de sms marketing e corporativo da AGENCIA GLOBO. V

HTML / JAVASCRIPT. A versão atual é o HTML5 (seus predecessores imediatos são HTML 4.01, XHTML 1.1, etc.).

Web Design. Prof. Felippe

Tutorial do administrador do HelpCenterLive (Sistema de Ajuda)

Melhorias e Correções Patch's

Operador de Computador. Informática Básica

Imagens: <IMG SRC="..."> SRC <IMG SRC="tecnologia.jpg"> único atributo que não pode ser omitido neste tag Nota: img

Introdução. História. Como funciona

Manual do Publicador. Wordpress FATEA Sistema de Gerenciamento de Conteúdo Web

SUMÁRIO 1. AULA 6 ENDEREÇAMENTO IP:... 2

Tutorial Folha Express. Como otimizar a confecção da folha de pagamento.

GUIA BÁSICO DA SALA VIRTUAL

Segmentação de Lista de Contatos

Manual do Google agenda. criação e compartilhamento de agendas

CSS é a abreviatura para Cascading Style Sheets Folhas de Estilo em Cascata

Capture Pro Software. Introdução. A-61640_pt-br

O QUE É A CENTRAL DE JOGOS?

Satélite. Manual de instalação e configuração. CENPECT Informática cenpect@cenpect.com.br

Figura 1: tela inicial do BlueControl COMO COLOCAR A SALA DE INFORMÁTICA EM FUNCIONAMENTO?

Desenvolvendo plugins WordPress usando Orientação a Objetos

MANUAL DE UTILIZAÇÃO

Conceitos de extensões Joomla!

Curso Superior de Tecnologia em Análise e Desenvolvimento de Sistemas Prof. Felippe Scheidt IFPR Campus Foz do Iguaçu 2014/2

Vamos criar uma nova Página chamada Serviços. Clique em Adicionar Nova.

Prof Evandro Manara Miletto. parte 2

Desenvolvimento de Sites com PHP e Mysql Docente André Luiz Silva de Moraes

PHP. Hypertext Pre-Processor

Tutorial Plone 4. Manutenção de Sites. Universidade Federal de São Carlos Departamento de Sistemas Web Todos os direitos reservados

Manual Sistema de Autorização Online GW

Transcrição:

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