I've been trying out socket.io and have obviously started with their chat app. The client-side code on their side looks somthing like this:
<!doctype html>
<html>
<head>
<title>Socket.IO chat</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font: 13px Helvetica, Arial; }
form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
#messages { list-style-type: none; margin: 0; padding: 0;}
#messages li { padding: 5px 10px; }
#messages li:nth-child(odd) { background: #eee; }
</style>
</head>
<body>
<ul id="messages"></ul>
<form action="" id = "frm">
<input id="m" autocomplete="off" /><button id='b'>Send</button>
</form>
<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
</script>
</body>
</html>
Now, my problem is that if I try to change the code inside the callback function inside the socket.on block with something like:
document.getElementById('messages').innerHTML += '<li>' + msg + '</li>';
the li element appears, for like half a second, and then the innerHTML resets, the same thing happens if I try editing any other part of the DOM inside the callback ?
I don't use Jquery but common sense made me assume
$('#messages').append($('<li>').text(msg))
; is basically equivalent with modifying the innerHTML in the way I wrote above. What am I doing wrong ? Is socket.io made in such a way that it can only use Jquery inside its call backs ? (I tried this in serveral browser).
The two codes perform equally in JSFiddle, so I can't tell why one works within socket.io and one doesn't, but in looking up related questions, I've seen a few answers suggesting not to use += with document.innerHTML. I haven't found a reason why this poses any problems beyond the minor security concern, but they suggest using appendChild() instead.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I'm ready to throw my pc through the window, somehow I can't seem to find my mistake. I feel like I am going insane. I have a simple login page in which you enter a name and a room code then you press submit. After you press submit I want to hide the form and show an element that says you are connected to the server. I'm using the following ejs/HTML page:
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
<script
src="https://code.jquery.com/jquery-3.5.0.min.js"
integrity="sha256-xNzN2a4ltkB44Mc/Jz3pT4iU1cmeR0FkXs4pru/JxaQ="
crossorigin="anonymous"></script>
<link href="/assets/styles.css" rel="stylesheet" type="text/css" />
<script src="/assets/zoomFriendsAjax.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.7.3/socket.io.js"></script>
</head>
<body>
<script src="/assets/sockets.js"></script>
<h2>Welcome To ZoomFriends</h2>
<div id="pagecontent">
<div id="serverform">
<form>
<label for="servercode"><strong>Server Code:</strong></label>
<input type="text" id="servercode" name="servercode" placeholder="Insert your server code here..." required>
<label for="nickname"><strong>Your Nickname</strong></label>
<input type="text" id="nickname" name="nickname" placeholder="Insert your nickname here..." required>
<button type=submit>join room</button>
</form>
<div>
<div id="connpage">
<h2>Connected to server</h2>
</div>
</div>
</body>
</html>
and then there is this ajax js file, which activates on submit and contains a function to show connected which should show the "connpage" and hide the "form" it only does the latter:
$(document).ready(function(){
$('#serverform').on('submit', function(){
var player = $('input[type="text"]#nickname');
var room = $('input[type="text"]#servercode');
var joindata = {player: player.val(), room: room.val()};
$.ajax({
type: 'POST',
url: '/button',
data: joindata,
success: function(data){
serverconnected();
}
});
return false;
});
function serverconnected(){
$('#connpage').show();
$('#serverform').hide();
}
});
Then there is this css in which connpage is set to display: none;
body{
background: #0d1521;
font-family: tahoma;
color: #989898;
text-align: center;
}
#todo-table{
position: relative;
width: 95%;
background: #090d13;
margin: 0 auto;
padding: 20px;
box-sizing: border-box;
}
#todo-table form:after{
margin: 0;
content: '';
display: block;
clear: both;
}
#connpage{
display: none;
}
input::placeholder {
font-style: italic;
}
input[type="text"]{
width: 100%;
padding: 20px;
background:#181c22;
border: 0;
float: left;
font-size: 20px;
color: #989898;
text-align: center;
}
label{
width: 100%;
padding: 20px;
background:#23282e;
border: 0;
float: left;
font-size: 20px;
color: #989898;
text-align: center;
}
button{
padding: 20px;
width: 100%;
float: left;
background: #23282e;
border: 0;
box-sizing: border-box;
color: #fff;
cursor: pointer;
font-size: 80px;
}
ul{
list-style-type: none;
padding: 0;
margin: 0;
}
li{
width: 100%;
padding: 20px;
box-sizing: border-box;
font-family: arial;
font-size: 20px;
cursor: pointer;
letter-spacing: 1px;
}
li:hover{
text-decoration: line-through;
background: rgba(0,0,0,0.2);
}
h1{
background: url(/assets/logo.png) no-repeat center;
margin-bottom: 0;
text-indent: -10000px;
text-align: center;
}
And this is the part of the server script that deals with the clicking of the submit button:
//if submit button is pressed
app.post('/button', urlencodedParser, function(req, res){
//console.log("pushed the button")
var message = req.body.player;
var found = rooms.some(el => el.roomcode === req.body.room);
if (found){
var targetindex = rooms.findIndex(element => element.roomcode === req.body.room);
io.to(rooms[targetindex].gamesocketid).emit('joinroom', {player: req.body.player, room: req.body.room, socket: socket.id});
//var currentroom = rooms.find(element => element.roomcode === req.body.room);
rooms[targetindex].players.push({nickname: req.body.player, id: socket.id});
//currentroom.players.push({nickname: req.body.player, id: socket.id});
console.log('player ' + req.body.player + ' joined room ' + req.body.room + ' with socket ID ' + socket.id);
//console.log(currentroom);
console.log(rooms[targetindex]);
res.json(rooms[targetindex]);
}
});
as far as I know everything is going as it should, EXCEPT the connpage NEVER SHOWS, i get through every function, all data is logged the way I want, except $('#connpage').show(); does nothing, it doesn't even have the common decency to send me an error or something ;p. Can anyone please help, I'm going nuts.... Eventually I need lots of show and hide to go on, to go through all the states of the page, without refreshing the page. Any help would really be welcome, thank you for even taking a look.
You have a syntax error in your HTML. You never close your serverform TAG.That way your connpage is INSIDE that container and gets hidden too Change
<div id="serverform">
....
<div>
to
<div id="serverform">
...
</div>
normally $("#connpage").show(); should work, maybe in some part of your app you are overriding it, you can use $('#connpage').css('display', '') as an alternatif.
if none of them work , you can remove the display none, and at the beginning you can hide it with .hide() .
i wish it helps
I'm attempting to create a chatapp on a webpage. I have a list of messages being sent. Problem is, that the newest messages aren't making the page autoscroll to that message.
I tried:
socket.on('chat message', function (msg) {
$('#messages').append($('<li>').text(msg));
// then you can scroll down once to show the new messages
var elem = document.getElementsByName('#messages');
elem.scrollTop = elem.scrollHeight;
});
I also tried experienting with the overflow: scroll option No luck there. As well as the position: relative option in the form css (which kinda worked, but unfurtunately the textbox was at the top of the webpage at the start, following the messages downwards - Looks like this:)
The problem I am facing seems to be looking a lot like this stack overflow page
Scroll HTML page before it 'reaches' the bottom
But I did not understand the answer marked as solved
Here is the code I have so far in my html document:
<!doctype html>
<html>
<head>
<title>HF-Chat</title>
<link href="https://fonts.googleapis.com/css?family=Roboto&display=swap" rel="stylesheet">
<style>
/* width */
::-webkit-scrollbar {
width: 6px;
}
/* Track */
::-webkit-scrollbar-track {
background: #2F3136;
border-radius: 5px;
}
/* Handle */
::-webkit-scrollbar-thumb {
background: #202225;
border-radius: 5px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font: 13px Roboto;
color:#DCDDDE;
background-color: #36393F;
}
form {
background: #36393F;
padding: 3px;
position: fixed;
bottom: 0;
width: 100%;
}
form input {
background: #484C52;
color:#DCDDDE;
border: 0;
padding: 10px;
width: 90%;
margin-right: .5%;
margin-left: .2%;
margin-bottom: .2%;
border-radius: 5px;
outline-color: transparent;
}
form button {
width: 9%;
background: #7289DA;
border: none;
padding: 10px;
margin-bottom: .2%;
border-radius: 5px;
}
#messages {
list-style-type: none;
margin: 0;
padding: 5px;
padding-bottom: 50px; /*Sets the distance between the textbox and bottom message once enough messages has been sent for the scrollbar to appear */
}
#messages li {
padding: 5px 10px;
background: #36393F;
border-bottom: 1px solid #484C52;
}
#messages li:nth-child(odd) {
background: #36393F;
}
</style>
</head>
<body>
<div>
<ul id="messages"></ul>
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
$(function () {
var socket = io();
$('form').submit(function (e) {
e.preventDefault(); // prevents page reloading
if ($('#m').val().startsWith("/")) {
socket.emit('user command', $('#m').val());
}
else{
socket.emit('chat message', $('#m').val());
}
$('#m').val('');
return false;
});
socket.on('chat message', function (msg) {
$('#messages').append($('<li>').text(msg));
// then you can scroll down once to show the new messages
var elem = document.getElementsByName('#messages');
elem.scrollTop = elem.scrollHeight;
});
});
</script>
</div>
<form action="">
<input id="m" autocomplete="off" /><button><font color="#DCDDDE">Send</font></button>
</form>
</body>
</html>
Try to scroll using .animate
const $li = $('<li>').text(msg);
$('#messages').append($li);
$('html, body').animate({
scrollTop: $li.offset().top
}, 2000); // change the animation delay to whatever you like
Get the top offset of the element
var offset = $('.element').offset().top;
$('html, body').animate({
scrollTop: offset
})
I like event listeners:
document.addEventListener(
"load",
function(event) {
event.composedPath().forEach(function(dom) {
if (dom.classList && dom.classList.value === "classOfLoadedContent") {
$(".div-to-be-scrolled").scrollTop($(".content").innerHeight());
}
});
},
true
);
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
i have a small problem but i cant find the problem myself :/
So i have this small part of code:
<html>
<head>
<title>Chat</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box;}
body { font:13px Helvetica, Arial; }
form { background: #000; padding:3px; position:fixed; bottom:0; width:100%;}
form input { border:0; padding: 10px; width: 90%; margin-right: .5%;}
form button { width:9%; background: rgb(130,224,255); border: none; padding:10px;}
#messages { list-style-type: none; margin:0; padding:0;}
#messages li { padding: 5px 10px;}
#messages li:nth-child(odd) { background: #eee; }
</style>
</head>
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off"/><button>Send</button>
</form>
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script
<script>
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
</script>
</body>
</html>
But, the part between the <script></script> where the var socket = io();
starts is being spit out as plain text...
And i cant find the problem, maybe one of you guys know...
Thanks!
You're missing a >
<script src="http://code.jquery.com/jquery-1.11.1.js"></script
Should be:
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
This line right here:
<script src="http://code.jquery.com/jquery-1.11.1.js"></script
Is missing the closing > after </script
var socket = io();
$('form').submit(function() {
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chat message', function(msg) {
$('#messages').append($('<li>').text(msg));
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font: 13px Helvetica, Arial;
}
form {
background: #000;
padding: 3px;
position: fixed;
bottom: 0;
width: 100%;
}
form input {
border: 0;
padding: 10px;
width: 90%;
margin-right: .5%;
}
form button {
width: 9%;
background: rgb(130, 224, 255);
border: none;
padding: 10px;
}
#messages {
list-style-type: none;
margin: 0;
padding: 0;
}
#messages li {
padding: 5px 10px;
}
#messages li:nth-child(odd) {
background: #eee;
}
<html>
<head>
<title>Chat</title>
</head>
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" />
<button>Send</button>
</form>
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
</body>
</html>
The closing script tag is missing a >.
Try:
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
I am doing this
http://socket.io/get-started/chat/
I am on the section Emitting events
When I type a message in the text box and hit send it refreshes the page and takes me to the url
localhost:3000/?
instead of logging the message on the server.
Why is the button failing to trigger the $('form').submit(function(){ line?
If I open the JS console on chrome and enter
socket.emit("chat message", 'testing from console')
it logs the message in my commandline server window as expected. So I do not think there is an error in the server side code.
I had hand typed out everything but when it wasn't working I copy pasted to make sure I had it right.
So index.html for me is
<!doctype html>
<html>
<head>
<title>Socket.IO chat</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font: 13px Helvetica, Arial; }
form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
#messages { list-style-type: none; margin: 0; padding: 0; }
#messages li { padding: 5px 10px; }
#messages li:nth-child(odd) { background: #eee; }
</style>
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
</script>
</head>
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
</body>
</html>
and index.js is
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http)
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
socket.on('chat message', function(msg){
console.log('message: ' + msg);
});
});
http.listen(3000, function(){
console.log('listneing on *:3000')
});
using chrome Version 47.0.2526.80 (64-bit)
Try wrapping your code in a document ready block. The form may not exist yet.
$(function(){
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
});
I am stuck at the get-started part of socket.io tutorial, on emitting events. Before that, I did get the user connected and user disconnected in the console. However, in the emitting part, I don't get any message passed by the socket.io client in the console.
This is the code so far:
index.js:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname+'/index.html');
});
io.on('connection', function(socket){
socket.on('chat message', function(msg){
console.log('message: ' + msg);
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
index.html:
<!doctype html>
<html>
<head>
<title>Socket.IO chat</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font: 13px Helvetica, Arial; }
form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
#messages { list-style-type: none; margin: 0; padding: 0; }
#messages li { padding: 5px 10px; }
#messages li:nth-child(odd) { background: #eee; }
</style>
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
</script>
</head>
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
</body>
</html>
I would really appreciate if you could guide me through this problem. Thank you.
You're missing a line in your index.js
Instead of:
io.on('connection', function(socket){
socket.on('chat message', function(msg){
console.log('message: ' + msg);
});
});
You should have:
io.on('connection', function(socket){
socket.on('chat message', function(msg){
console.log('message: ' + msg);
io.emit('chat message', msg);
});
});
What's happening is that in the html file, when you submit a chat message, you are emitting it back to to server, who needs to emit it back to all of the other users. Without that io.emit line, all of the other users will not get the message
*edit: Also in your html file, it should look like this:
<!doctype html>
<html>
<head>
<title>Socket.IO chat</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font: 13px Helvetica, Arial; }
form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
#messages { list-style-type: none; margin: 0; padding: 0; }
#messages li { padding: 5px 10px; }
#messages li:nth-child(odd) { background: #eee; }
</style>
</head>
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
</body>
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
</script>
</html>
It wasn't working because you were running your script first which references a jQuery element that doesn't exist yet. If you wanted to keep the body where it was, you would need to wrap the scripts in a $(document).ready function. Also you were forgetting to append the message on incoming chat message sockets.