How do I trigger javascript from a button click - javascript

I'm trying to trigger javascript to start, stop and restart a stopwatch from a button in the html file. What is the best way to pass an event from the html to the javascript?
I have managed to trigger a console log when the button is pressed, but I can't put in the javascript in the second js file. I just receive errors. Would socket.io work? I have investigated Event emitters and listeners but I think it's out of my skill level.
server.js
var express = require('express');
var app = express();
var path = require('path');
var Stopwatch = require("node-stopwatch").Stopwatch;
const EventEmitter = require('events');
var stopwatch = Stopwatch.create();
app.use(express.static('public'));
// start the express web server listening on 8080
app.listen(8080, () => {
console.log('listening on 8080');
});
// serve the homepage
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
stopwatch.start();
/*
stopwatch output test
*/
console.log("ticks: " + stopwatch.elapsedTicks);
console.log("milliseconds: " + stopwatch.elapsedMilliseconds);
console.log("seconds: " + stopwatch.elapsed.seconds);
console.log("minutes: " + stopwatch.elapsed.minutes);
console.log("hours: " + stopwatch.elapsed.hours);
//stop it now
stopwatch.stop();
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
console.log('an event occurred!');
});
client.js
console.log('Client-side code running');
const button = document.getElementById('myButton');
button.addEventListener('click', function(e) {
console.log('button was clicked');
});
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Stopwatch</title>
</head>
<body>
<h1>Stopwatch</h1>
<p id="counter">Loading button click data.</p>
<button id="myButton">Click me!</button>
</body>
<script src="client.js"></script>
</html>
I expected to trigger the javascript on button click but I cannot run it in client.js

Use in the client.js
window.addEventListener("load", myFunction);
and place your code to myFunction

If this console is printed, console.log('Client-side code running');
Try to add your button event inside a function.
function onLoadBody() {
const button = document.getElementById('myButton');
button.addEventListener('click', function(e) {
console.log('button was clicked');
});
}
<body onload="onLoadBody()" >...

let say you have two files, client.js and server.js
You can use socket.io for quicker response as apposed to HTTP request
You just need to emit a key to the server and the server will respond to that emit.
Client.js
let socket = io();
socket.emit('start')
Server.js
socket.on('start',(data)=>{
// do what ever you want and send back to client with the same emit method
// `socket.emit()` sends message to connected client
// socket.broadcast.emit() send message to all clients except you
// io.emit() send message to all including you
})

Related

Why my messages are being displayed many times?

I made a chat room using electron. But when I send a message to the server and from there the message will be displayed to the users for some reason the message is being displayed multiple times. Example: I send -> "hello" the message will be displayed once, when I send a second message ->"Hello server" the message will be display two times, when I sent a third message ->"ok" this message will be displayed three times. The fourth message will be displayed 4 times etc.
this is the renderer.js code:
const ws = new WebSocket("ws://127.0.0.1:5000");
ws.addEventListener('open', function(event){
ws.send('hello server');
console.log("data sent");
});
function send_data(){
console.log("button clicked");
ws.send(document.getElementById("input_text").value);
ws.addEventListener('message', function(event){
console.log("server send something");
let mess=event.data;
console.log(mess);
update_chat(mess);
});
};
function update_chat(mess){
const div = document.createElement('div');
div.classList.add('message');
div.innerHTML = `okwpegjwpgj said: ${mess}`;
document.querySelector('.chat_messages').appendChild(div);
}
this is the server.js code:
const WebSocket = require('ws');
let broadcast_msg;
const PORT = 5000;
const wss = new WebSocket.Server({
port: PORT
});
wss.on("connection", ws =>{
ws.on('message', function incoming(message){
broadcast_msg=message;
console.log('received: ', message);
ws.send(message);
});
});
console.log("Server is liestening on port " + PORT);
Because you add the addEventListener('message') on every send_data() call.
Add the eventlistener once and remove it from the send_data() method. you don't need to add a new eventlistener every time you send data.
ws.addEventListener('message', function(event){
console.log("server send something");
let mess=event.data;
console.log(mess);
update_chat(mess);
});
function send_data(){
console.log("button clicked");
ws.send(document.getElementById("input_text").value);
};
Change your renderer.js file to this:
const ws = new WebSocket("ws://127.0.0.1:5000");
ws.addEventListener('open', function(event){
ws.send('hello server');
console.log("data sent");
});
ws.addEventListener('message', function(event){
console.log("server send something");
let mess=event.data;
console.log(mess);
update_chat(mess);
});
function send_data(){
console.log("button clicked");
ws.send(document.getElementById("input_text").value);
};
function update_chat(mess){
const div = document.createElement('div');
div.classList.add('message');
div.innerHTML = `okwpegjwpgj said: ${mess}`;
document.querySelector('.chat_messages').appendChild(div);
}

socket.io, getting io is not defined on console

I am setting a basic chat app using sockets, but in the initial stage of programming I am getting this error: “io is not defined” on the client side.
I have tried including the CDN and adding
<script src="/socket.io/socket.io.js"></script>,
but no success.
HTML
<head>
<script src="jquery-3.2.1.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="script.js"></script>
</head>
script.js
let socket = io();
console.log("socket formed on " + socket.id)
server.js
const express = require('express')
const path = require('path')
const socketio = require('socket.io')
const http = require('http')
const app = express();
const server = http.createServer(app)
const io = socketio(server)
app.use('/', express.static(path.join(__dirname, 'frontend')))
io.on('connection', (socket) => {
console.log("New socket formed fksrom " + socket.id)
})
server.listen(2345, () => console.log('website open on http://localhost:2345'))
I expect the socket ID to be shown in the console,
but on console it is displaying “io is not defined”.
I think you should check if document has loaded so here's the code below:
// Pure Javascript
if(document.readyState === "complete") {
//Already loaded!
}
else {
//Add onload or DOMContentLoaded event listeners here: for example,
window.addEventListener("onload", function () {/* Move your code here */}, false);
//or
//document.addEventListener("DOMContentLoaded", function () {/* code */}, false);
}
Since you already have jQuery:
$(document).ready(function(){
/** Your code here */
})
You're trying to access a script before it is loaded so the above code should help you run your script only when you've done with loading the jQuery library and socket.io.js library.

Listening for Automatically-Triggered Client Events with page.on('customEvent', fn)

This gist seems to cover what I want to do, but it appears to be a thought experiment, rather than working code. In any case, I'm having trouble getting it to work for me.
I'm opening a page in PhantomJs that loads a JavaScript library and starts a process. When the process completes, that library triggers an event within the context of the instance object. I'd like to either
(a) set up PhantomJS to listen for the right event in the instance object in the client page
OR
(b) add some code to the client page that "bubbles-up" the event to window and set up PhantomJS to listen for that.
Here's what I've tried for option B.
client.html:
<html>
<body>
<script src='https://example.com/library.js'></script>
<script>
function sendWindowEvent() {
// I've also tried document, top.parent, etc.
window.dispatchEvent( new CustomEvent('myEvent', {
detail: {
message: "Hello World!",
time: new Date(),
},
bubbles: true,
cancelable: true
}));
}
var instance = new myLibrary.constructor();
instance.addEventListener("onInitialized", sendWindowEvent);
instance.start();
</script>
</body>
</html>
In node.js app:
const headlessBrowser = await phantom.create();
const page = await headlessBrowser.createPage();
await page.on('onResourceRequested', (requestData) => {
console.info('Requesting', requestData.url); // displays http://localhost:1337/client.html & https://example.com/library.js
});
await page.on('myEvent', async (evt) => {
console.log('event detected:', evt); // never triggered
});
const openStatus = await page.open('http://localhost:1337/client.html');
console.log('phantom status:', openStatus); // displays true
Any ideas on what I'm missing? Is this not a supported feature? Thanks in advance.
page.on event listeners are responding to specific technical events generated by PhantomJS, not by its target page. To receive native page events you will have to subscribe to them in the browser context:
await page.evaluate(function(){
window.addEventListener("myEvent", function(e){ console.log(e)})
});
Be sure to subscribe to page.onConsoleMessage callback to get that message.
window.callPhantom() was what I was looking for. Documentation is here.
client.html:
<html>
<body>
<script src='https://example.com/library.js'></script>
<script>
function sendWindowEvent() {
if (typeof window.callPhantom === 'function') {
window.callPhantom({hello: 'world'});
}
}
var instance = new myLibrary.constructor();
instance.addEventListener("onInitialized", sendWindowEvent);
instance.start();
</script>
</body>
</html>
In node.js app:
const headlessBrowser = await phantom.create();
const page = await headlessBrowser.createPage();
page.on('onCallback', data => {
console.log('CALLBACK: ' + JSON.stringify(data)); // Prints 'CALLBACK: {"hello":"world"}'
});
page.open('http://localhost:1337/client.html');

Socket.io and nodeJS javascript robotics

I am currently working at a nodeJS robotics app and i am trying to use sockets.io in order to show some messages and data in browser.
I have the following nodeJS code:
app.get('/', function(req, res){
res.sendfile('index.html');
});
io.on('connection', function(socket){
console.log('A user connected');
socket.on('clientEvent', function(data){
function take_tool() {
while(!take_tool_flag) {
if(fs.existsSync('D:/flag.txt')) {
fs.writeFileSync('D:/input_robot.txt', '-1');
socket.emit('testerEvent', 'Robot is taking the writing tool!');
console.log('Robot is taking the writing tool!');
fs.unlinkSync('D:/flag.txt');
take_tool_flag = true;
}
}
}
function draw_table() {
while(!draw_table_flag && take_tool_flag) {
if(fs.existsSync('D:/flag.txt')) {
fs.writeFileSync('D:/input_robot.txt', '-3');
socket.emit('testerEvent', 'Robot is drawing the table game!');
console.log('Robot is drawing the table game!');
fs.unlinkSync('D:/flag.txt');
draw_table_flag = true;
}
}
}
function game() {
socket.emit('testerEvent', 'A new game has started!');
console.log("A new game has started!");
fs.writeFileSync('D:/input_robot.txt', '-99');
if(!take_tool_flag) { take_tool(); }
if(!draw_table_flag) { draw_table(); }
}
game();
});
socket.on('disconnect', function () {
console.log('A user disconnected');
});
});
http.listen(3000, function(){
console.log('listening on localhost:3000');
});
And then in HTML:
<!DOCTYPE html>
<html>
<head><title>Hello world</title></head>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
socket.on('testerEvent', function(data){document.write(data)});
function start() {
socket.emit('clientEvent', 'Sent an event from the client!');
}
</script>
<body>Hello world
<button onclick="start()">Start</button>
</body>
</html>
When i press the start button from html the first 3 instructions from game(); function are executed:
socket.emit('testerEvent', 'A new game has started!');
console.log("A new game has started!");
fs.writeFileSync('D:/input_robot.txt', '-99');
and i get the message in browser from socket.emit;
Then it enters in take_tool(); function where it waits for 'D:/flag.txt' to be created. When i create this file the execution of take_tool(); continues but i don't get in browser the message from socket.emit. Same thing for draw_table(); function. I receive those messages instead at the end of game(); function execution. I need those messages to be shown in browser in real time not at the end of function execution. What seems to be the problem? Thank you!

Nodejs, express & socket.io communicate between two static client pages

i am trying to build a remote for a gallery by using nodejs, express & socket.io.
the structure is as follows
/index.js
/public/screen.html
/screen.js
/remote.html
/remote.js
the idea is to have a gallery of images displayed on remote.html, select one and send the selected index to screen.html by using socket.io.
as of now my code looks like this:
index.js
var express = require('express');
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io').listen(server);
app.use(express.static('public'));
server.listen(8080, function(){
// setup image gallery and stuff...
connectToServer();
});
remote.js
var socket = null;
document.addEventListener("DOMContentLoaded", function(event) {
//some stuff
connectToServer();
});
function showImage (index){ //called by events
console.log('selected incdex: ' + index);
if(socket != null) {
socket.emit('selection', {id: index});
};
}
function connectToServer(){
socket = io.connect('http://localhost:8080');
socket.on('connection', function (socket) {
var text = document.querySelector('#name');
socket.emit('newRemote', 'new remote connected');
console.log('emitted welcome');
socket.on('newScreen', function (data) {
console.log(data);
});
});
}
screen.js
var socket = null;
document.addEventListener("DOMContentLoaded", function(event) {
//some stuff
connectToServer();
});
function connectToServer(){
socket = io.connect('http://localhost:8080');
socket.on('connection', function (socket) {
var text = document.querySelector('#name');
socket.emit('newScreen', { name: name });
socket.on('newRemote', function (data) {
console.log(data);
});
});
};
when starting with node index.js i get
listening on *:8080
and when loading screen or remote.html i get
debug - client authorized
info - handshake authorized MwtGFRCZamcyKkUpK5_W
as I see it: somehow a connection is established, but:
no messages are sent / received on both ends
no logs are printed to the console for the connection events
any idea why nothing is happening?
It appears that you have mixed server-side code into your client. The 'connection' event is an event that needs to be listened to on the server, not your client files. Additionally, you cannot directly call client-side functions from your server-side code.
The below code does not work:
server.listen(8080, function(){
// setup image gallery and stuff...
connectToServer();
});
To achieve the above you will need to put the following code on your server:
server.listen(8080, function(){
socket.on('connection', function (socket) {
// setup image gallery and stuff...
socket.emit('connectToServer', myPassedParameters);
});
});
And the following listener for that event on the client:
socket.on('connectToServer', function (myPassedParameters) {
var text = document.querySelector('#name');
// stuff for client side here
});
});
In addition to the above, you cannot do calls from one client file to another client file using socket.io. You would have to do a call to the server first and then call a function on the other file once it has been loaded for the user.

Categories