git clone git@github.com:zdimon/marafon-js-quiz-template.git
Скопируем его в папку public проекта.
Поставим простенький сервер.
npm install lite-server
Запуск.
cd public
../node_modules/lite-server/bin/lite-server
Работать будем внутри файла app.js.
Нам вначале необходимо создать изолированную область видимости переменных.
(function( $ ) {
$.fn.quizPlugin = function() {
console.log('my plugin');
};
})(jQuery);
В jQuery fn - это псевдоним прототипа.
Ключевое слово jQuery (или $) - это всего лишь функция-конструктор, и все объекты, создаваемые этим конструктором будут наследовать все свойства и методы его прототипа.
$.fn.quizPlugin = function() {..}
Так мы создаём новое свойство-функцию для объекта jQuery, где именем нового свойства будет имя нашего плагина.
Для того, чтобы небыло конфликтов со знаком $ рекомендуется «обернуть» объект jQuery в непосредственно выполняемую функцию-выражение.
Применяем плагин.
<script>
var app = $('#myapp').quizPlugin();
</script>
app.start = function() {
if(sessionStorage.getItem('username')) {
this.initRoom();
} else {
this.loginForm()
}
}
app.loginForm = function() {
}
app.initRoom = function() {
}
Тут мы предполагаем, что в случае авторизованного пользователя у нас будет существовать переменная username в локальном хранилище браузера.
app.loginForm = function() {
let form = $('#loginForm').show();
let url = 'http://quizapi.webmonstr.com/v1/quiz/sticker/list';
$.get( url, function( data ) {
data.forEach((el) => {
let img_tag = `<img width="50" src="${el.get_url}" />`;
let parent = $('#stickers').append(img_tag);
})
});
}
$.get - функция jQuery отсылающая http запрос.
data.forEach((el) => {}) - функция, перебирающая список.
$(‘#stickers’).append() - добавление html в выбранный элемент.
let img_tag = `<img data-id="${el.id}" class="sticker" width="50" src="${el.get_url}" />`;
...
$('.sticker').on('click',(event)=>{
$('.sticker').each((indx,el)=>{
$(el).removeClass('active-sticker');
})
$(event.target).addClass('active-sticker');
})
$(‘.sticker’).on(‘click’,(event)=>{}) - привязка событий к коллбеку в jQuery.
Тут мы набрасывае класс sticker на элемент img чтобы далее по ним пройтись циклом и убрать класс active-sticker. Далее мы устанавливаем класс active-sticker на том изображении, на которое кликнул пользователь.
.active-sticker {
border: 1px solid red;
}
Создадим функцию отправки данных методом post с передачей json в теле запроса.
app.submitLogin = function() {
let data = {
name: $('#userName').val(),
sticker_id: this.sticker
};
let url = 'http://quizapi.webmonstr.com/v1/quiz/player/join';
$.post( url, data, ( response ) => {
sessionStorage.setItem('username',response.name);
let form = $('#loginForm').hide();
});
}
$(‘#userName’).val() - получение данных, вводимых пользователем в элемент input.
$.post( url, data, ( response ) => {}) - передача данных POST в jQuery.
Привяжем функцию к нажатию кнопки с id = “chat-start”.
app.loginForm = function() {
...
$('#chat-start').on('click',() => {this.submitLogin()});
}
app.getCurrentQuestion = function() {
let url = 'http://quizapi.webmonstr.com/v1/quiz/get_current_question';
$.get( url, ( response ) => {
$('#currentQuestionBlock').html(response.question);
});
}
$(‘…’).html(content) - забрасываение html внутрь полученного элемента.
app.getMessages = function() {
let url = 'http://quizapi.webmonstr.com/v1/quiz/message/list';
$.get( url, ( response ) => {
response.forEach((el)=> {
let tpl = ` <div class="chat">
<div class="chat-user">
<a class="avatar m-0">
<img src="${el.playerimage}" alt="avatar" class="avatar-35 ">
</a>
<span class="chat-time mt-1">${el.playername}</span>
</div>
<div class="chat-detail">
<div class="chat-message">
<p>${el.text}</p>
</div>
</div>
</div>`;
$('#chatContent').append(tpl);
})
});
};
...
app.socketConnection = function() {
let webSocket = new WebSocket('ws://quizapi.webmonstr.com:7777/quiz/');
webSocket.onerror = (evt) => {
}
webSocket.onmessage = (event) => {
var payload = JSON.parse(event.data)
console.log(payload);
}
webSocket.onclose = (event) => {
console.log('Close connection');
};
webSocket.onopen = (event) => {
console.log('Connection established');
};
}
При создании объекта соединения нам необходимо определить несколько обработчиков.
onerror - при ошибке
onmessage - приход нового сообщения
onopen, onclose - открытие и закрытие соединения.
app.sendMessage = function() {
let data = {
message: $('#messageBox').val(),
playername: sessionStorage.getItem('username')
}
let url = 'http://quizapi.webmonstr.com/v1/quiz/save_message';
$.post( url, data, ( response ) => {
$('#messageBox').val('');
});
};
$(‘#messageBox’).val(‘’) - очищение input-а.
....
webSocket.onmessage = (event) => {
var payload = JSON.parse(event.data)
if(payload.type === 'message'){
this.getMessages();
}
}
...
...
app.getUserList = function() {
$('#playerListBlock').empty();
let url = 'http://quizapi.webmonstr.com/v1/quiz/player/list';
$.get( url, ( response ) => {
response.forEach((el) => {
let tpl = `<div class="media-height p-3">
<div class="media align-items-center mb-4">
<div class="iq-profile-avatar status-online">
<img class="rounded-circle avatar-50" src="${el.sticker.get_url}" alt="">
</div>
<div class="media-body ml-3">
<h6 class="mb-0"><a href="#">${el.name}</a></h6>
<p class="mb-0">${el.account}</p>
</div>
</div>
</div>`;
$('#playerListBlock').append(tpl);
});
});
};
app.initRoom = function() {
this.setCurrentUser();
this.getUserList();
this.getCurrentQuestion();
this.getMessages();
this.socketConnection();
$('#sendButton').on('click',()=>{
this.sendMessage();
});
}