I am trying to serve html files from server without using template engines. Please find the below script for starting the server.
// script.js
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
app.use(express.static(__dirname));
app.get("/", (req, res) => {
res.set("Content-Type", "text/html");
const f = require("./templates")();
console.log(f);
res.send(f);
});
app.listen(3103, () => console.log("hi"));
// template.js
const fs = require("fs");
const html = fs.readFileSync(__dirname + "/temp.html", "utf8");
module.exports = (variables) => {
return html;
};
Following is my html file:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=<device-width>, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="./script.js"></script> <!-- The click function was served in a different file -->
</head>
<body>
<p>Home Page</p>
<input type="button" value="Click Me" id="btn" onclick="click()">
<script>
console.log("hi");
function click(){ console.log("_Button clicked"); }
//document.getElementById("btn").addEventListener("click", () => {
//console.log("Button Clicked");
//});
</script>
</body>
</html>
I tried the following without any success:
I included the click() inline in the button element, and the function was declared in script tag in the same html file. This did not work.
I included the fromScript function in script.js file and served that file as static content. This did not work as expected.
Then I used addEventListener to bind the click event to input element. Now whenever I click the button, "Button Clicked" message is printed twice.
What is the correct/best practice for binding dom events to the elements?
Edit
Thanks for the answer Thijs Kramer. But the problem is due to the function name.
If I name the function as click it is not working. But if I rename it to fromScript it is working.
Should we not use "click" for function name?
Your problem has nothing to do with express :)
The best practice for binding click events is for example the following:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=<device-width>, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<p>Home Page</p>
<input type="button" value="Click Me" id="btn">
<script>
const button = document.getElementById("btn");
button.addEventListener("click", () => {
console.log("Button Clicked");
});
</script>
</body>
</html>
Edit: I think I know what you mean:
If you rename the function fromScript to click, you obviously have to change the value of the onclick attribute as well:
<input type="button" onclick="click()" />
The reason for your naming problem is that the HTMLElement API (which all html elements inherit from) has a click property. It is a function meant to be used to programmatically trigger a click event on the element.
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click
To avoid confusion and unpredictable behaviour, always make sure to name your variables and functions unambigously with regard to inherited and built-in properties from the prototype chain.
The below code should work fine:
// script.js
const express = require("express");
// const bodyParser = require("body-parser");
const app = express();
app.use(express.static(__dirname));
app.listen(3103, () => console.log("hi"));
then node script.js and try to access it by going to http://localhost:3103/temp.html
?
Related
I have server side code which serves up a pug file, the pug file has variables parsed to it when rendered by my server side code.
I would like to be able to update that variable in pug when a check box is checked / unchecked.
my server side code:
// load the express module
const express = require('express');
const simpleVarDisplaySite = 'simpleVarDisplay.pug';
const app = express();
app.use(express.urlencoded({extended: false}))
app.use(express.static(__dirname+'/static'));
// simpleVarDisplaySite page
app.get('/', function (req, res) {
console.log(req.url);
let myHeading = 'Simple Pug Page';
let simpleObject = {
'date': {
'day': 'time'
}
}
res.render(simpleVarDisplaySite, {
heading: myHeading,
pugObject: simpleObject,
});
})
app.listen(8082)
my pug file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Simple Pug</title>
<link rel="stylesheet" href="/styles/MainStyling.css">
<script src="/scripts/pugVarUpdater.js"></script>
</head>
<body>
<form method="POST">
<div>
<header>
<h1 class="HeaderEl" id="heading">#{ heading }</h1>
</header>
<div>
<input type="checkbox" id="simpleCheckBox" onchange="JavaScript:updatePugVarFunc()">
</div>
<br>
each valueDict, date in pugObject
<div>
<div>
<span>#{date}</span>
</div>
<br>
each time, day in valueDict
<div>
<span>#{day}</span>
</div>
<div>
<span>#{time}</span>
</div>
</div>
</div>
</form>
</body>
</html>
my client-side js when checkbox is checked / unchecked:
function updatePugVarFunc() {
const simpleVarDisplaySite = 'simpleVarDisplay.pug';
let newSimpleObject = {
'new_date': {
'new_day': 'new_time'
}
}
alert(newSimpleObject)
let myNewHeading = 'My New Simple Heading'
alert(myNewHeading)
document.body.innerHTML = simpleVarDisplaySite({
heading: myNewHeading,
pugObject: newSimpleObject,
});
}
I would like to have pug variable: pugObject updated when the checkbox is checked / unchecked onChange event, and see the updates in my browser, which I have tried with:
document.body.innerHTML = simpleVarDisplaySite({
heading: myNewHeading,
pugObject: newSimpleObject,
});
But that does not work.
I know that client-side is handled rather differently from server-side, but I am soo hoping that there is a solution to my specific problem.
Please note that I am a nood with javascript and pug, and I am very open to any and all suggestions to better achieve my goal.
My File structure:
server.js
views
simpleVarDisplay.pug
static
scripts
pugVarUpdater.js
PS:
I have had a look at: use client-side js variable in pug
And that did not help me.
Your assistance and guidance is much appreciated.
I'm trying to write a script to extract email id and name from this website. I tried the following snippet but it doesn't work.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>foo</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div>
<strong style="color: darkgreen;">Can read this tag</strong>
<object id="external_page" type="text/html" data="https://aleenarais.com/buddy/" width="800px" height="600px"
style="overflow:auto;border:5px ridge blue">
<!-- I want to read tag values from this object -->
</object>
</div>
<script>
window.addEventListener('load', function () {
const item = [];
$('strong[style="color: darkgreen;"]').each(function () {
item.push($(this).text())
})
console.log(item)
})
</script>
</body>
</html>
Is there any better way to do this? Or is it possible to convert the whole page into a string and extract the email using RegEx?
The email and name of in the webpage are being rendered in an iframe. The source of iframe is an external source. In order for you to extract the information, you need to use a headless browser to do that.
I would suggest using Node.JS & Puppeteer (https://www.npmjs.com/package/puppeteer)
const puppeteer = require("puppeteer");
(async() => {
const url = "https://aleenarais.com/buddy/";
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(url, {
waitUntil: "networkidle0"
});
var frames = await page.frames();
var myframe = frames.find(
(f) => f.url().indexOf("https://feedium.app/fetchh.php") > -1
);
const textFeed = await myframe.$$eval("strong", (sElements) =>
sElements.map((el) => el.textContent)
);
console.log(textFeed.splice(1)); //Array contains both name and email
await browser.close();
})();
Puppeteer loads the page similar to how a user loads the page. It waits until all the network calls are done (see network idle0) and then it tries finding the iframe which has the url (fetchh.php). If you observe, name and email are present in strong tags and they are the only strong tags available. Hence, we are extracting the strong tags, removing the count and we are left with just the name and email.
Output:
[ 'JJ', 'j*j#gmail.com' ] //I have just masked the values but the program gives the actual ones
Steps to run the script:
Install Node.Js (https://nodejs.org/en/download/)
Install puppeteer using (npm i puppeteer)
copy the script and place it in file (demo.js)
In the terminal, navigate to the directory in which the demo.js is
present and then run node demo.js
You should see the output.
Try this:
window.addEventListener('load', function () {
let item = [];
$('strong[style*="color: darkgreen;"]').each(function (index, item) {
item.push($(this).text())
})
console.log(item)
}
I have a difficult question, I am trying to get the input value of an input field, however, I need this to happen within another function.
I already have code that works outside of this other function but I need to refactor it to work inside another function that I am calling.
Examples of working code and non-working code are below.
Here is the HTML where I am getting the input:
<!DOCTYPE HTML>
<HTML>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="css/styles.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript" src="js/require.js"></script>
<script type="text/javascript">
(function () {
var config = {
baseUrl: "js",
};
var dependencies = ["otherFile"];
require(config, dependencies);
})();
</script>
</head>
<body>
<div>
<label>Input URL</label>
<input type="url" />
<p id="targetInput"></p>
</div>
</body>
</html>
Here is the non-working JS that I am trying to call within another function:
function someOtherFunction() {
var getCurrentInput = function() { };
var input = document.querySelector("input");
var log = document.getElementById("targetInput");
input.addEventListener("input", getCurrentInput);
var getCurrentInput = function (e) {
log.currentInput = e.target.value;
};
}
});
Lastly here is the working code that works outside of the scope of someOtherFunction
var getCurrentInput = "";
var input = document.querySelector("input");
var log = document.getElementById("targetInput");
input.addEventListener("input", getCurrentInput);
function getCurrentInput(e) {
log.currentInput = e.target.value;
}
Now you may notice that there isn't a form being submitted here, the reason for this is because this code is running on an iframe that is being called into another app. The submit is happening there but requires me to call a function to make it happen and technically isn't a submit, meaning I don't have control over it like a regular submit. This is why I need to call the current input value inside someOtherFunction.
Any help would be greatly appreciated here! Essentially I want to get the value inside the input and update my API with the value as a JSON string. There must be a better way!
Was a bit difficult to follow at first given the nesting, but something like this?
const doThing = (e) => {
let input = document.getElementById("input");
let log = document.getElementById("targetInput");
log.textContent = input.value;
}
<div>
<label>Input URL</label>
<input type="url" id="input"/>
<p id="targetInput"> </p>
</div>
<button onclick="doThing()">Click</button>
Essentially an external submit that takes an internal input value, and injects it into another internal element?
Everything is working fine in this code except the result showing part after receiving any audio.Can someone tell me why this is not logging any value in console even after i speak in the headphone.
<!DOCTYPE html>
<head></head>
<body>
<div id="msg"></div>
<div id="msg2"></div>
<script>
(function(){
var reco = new webkitSpeechRecognition();
var msgid = document.getElementById('msg');
reco.interimResults = true;
reco.addEventListener('start',function(){
msgid.innerHTML = 'Listening...';
});
reco.addEventListener('audiostart',function(){
msgid.innerHTML = 'Recording...';
});
reco.start();
reco.onresult = function(e){
console.log(e);
}
})()
</script>
</body>
However, SpeechRecognition() is a constructor which is not supported by most of the browers, if you are running it in firefox, it won't help. Try this code in chrome. Later on in console -> Search for result -> Expand the result tab -> Search something called transcript. There it is, your recorded text.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<button class="talk">Talk</button>
<h3 class="content"></h3>
<script>
const btn = document.querySelector(".talk");
const content = document.querySelector(".content");
const SpeechRecognition =
window.SpeechRecognition || window.webkitSpeechRecognition;
const myRecognition = new SpeechRecognition();
myRecognition.onstart = function() {
console.log("voice is activated, you may now speak");
};
myRecognition.onresult = function() {
console.log(event);
};
//adding eventListener
btn.addEventListener("click", () => {
myRecognition.start();
});
</script>
</body>
</html>
Internet connection is required for working with speech recognition since the recorded speech must be fed through internet connection to a web service for processing.
https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API/Using_the_Web_Speech_API
I need my webite to display info in a certain language, based on a query in my webite's URL (e.g. www.website.com/index.php?country=FR). How can I do that with vanilla JS and not React/Angular?
My approach:
1) JS recognizes a query in the URL (in this case- 'country=FR') and then appends a js file, which has neccessary french words in it defined by variables.
2) JS in my script tag that's in the HTML file, appends the main page markup text with template literals in it.
3)
I don't know, whether the browser fails to either fetch the language file itself or its variables. At the moment it does not render anything.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="./js/main.js"></script>
</head>
<body>
<script>
const template= `
<h1>Good Morning: ${goodmorning} </h1>
<h2>Good Evening: ${goodevening} </h2>
<h3>My name is: ${mynameis}</h3>`
function markupAppend() {
$('body').html(template);
console.log('Markup loaded')
}
markupAppend()
</script>
</body>
</html>
=========================
Main.js
var domain = window.location.href;
var FRString = domain.includes("country=FR");
var ESString = domain.includes("country=ES");
if (FRString) {
$('head').append(`<script src="./Language_files/FRENCHwords.js" />`)
}
if (ESString) {
$('head').append(`<script src="./Language_files/SPANISHwords.js" />`)
}
=========================
FRENCHwords.js
const goodmorning = 'Bonjour';
const goodevening = 'Bonsoir';
const mynameis = 'Mon nom est';
=========================
SPANISHwords.js
const goodmorning = 'Buenos dias';
const goodevening = 'Buenas tardes';
const mynameis = 'Mi nombre es';
No errors displayed, the page is just not rendering...
In Your main.js file, you are using domain.includes, it only returns the domain name but not the entire URL. You can use window.location.href.includes for this.
Instead of: domain.includes("country=FR");
Try: window.location.href.includes("country=FR");