I'm starting with javascript, websockets and jQuery developing a simple example. In the html page I only have a button, that, when pressed, has to send its state (ON/OFF for instance). In index html, I have the following code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"></meta>
<title>First App</title>
<link rel="stylesheet" href="css/style.css">
<script src="js/jquery-3.3.1.min.js"></script>
<script src="js/APP.js"></script>
</head>
<body>
<div id='hello_message'>
Connecting...
</div>
<button id='state'>Turn on</button>
<div id='off'>OFF</div>
<div id='on'>ON</div>
</body>
</html>
My intention is to open a websocket between the client and the server when the page is loaded, and keep it open for any information to be sent between both of them. To this end, I have the following file containing the js code (APP.js):
window.onload = APPStart;
// Page onload event handler
function APPStart() {
state = false;
if ("WebSocket" in window)
{
var ws = new WebSocket("ws://10.30.0.142:8020");
ws.onopen = function()
{
alert ("Connected");
$('#hello_message').text("Connected");
};
ws.onmessage = function (evt)
{
var received_msg = evt.data;
};
ws.onclose = function()
{
alert("Connection is closed...");
};
window.onbeforeunload = function(event) {
socket.close();
};
}
else
{
// The browser doesn't support WebSocket
alert("WebSocket NOT supported by your Browser!");
}}
Now, every time someone clicks on button, I would like to execute the following code:
// program checks if led_state button was clicked
$('#state').click(function() {
alert ("click");
// changes local led state
if (led_state == true){
$('#on').hide();
$('#off').show();
state = false;
ws.send("ON");
}
else{
$('#off').hide();
$('#on').show();
state = true;
ws.send("OFF");
}
});
I've tried to put this part of the code inside the function APPStart, but it doesn't work. I also suspect that jQuery is not working either since messages are not updated. Any suggestion to make it work?
Thanks for the comments. The code works, the problem was in the cache of the browser. Once I noticed it, I cleaned the cache and everything started to work. Silly me.
Related
I want an audio file to play automatically when a web page loads. I've tried the following simple code but for some reason it's not working. Any thoughts? I understand this may be caused by some default behavior of Google Chrome. Thanks.
<!DOCTYPE html>
<html>
<head>
<title>My Audio</title>
</head>
<body>
<script type="text/javascript">
window.onload=function(){
const audio = new Audio("wonderful.mp3");
audio.play();
}
</script>
</body>
</html>
Simply you can't.
Browsers don't allow you to play audio when the user has not interacted with your site at least once.
You should create a simple function that, when the user click for the first time on your page, play your audio.
Error : Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.
This snippet allows you to play your audio when the user click on your document for the first time :
<!DOCTYPE html>
<html>
<head>
<title>My Audio</title>
</head>
<body>
<div>Test</div>
<audio id="my-audio" autoplay
src="https://file-examples.com/storage/fe8bd9dfd063066d39cfd5a/2017/11/file_example_MP3_5MG.mp3"></audio>
<script type="text/javascript">
var isAudioPlayed = false;
function playAudio() {
isAudioPlayed = true;
const myAudio = document.getElementById("my-audio");
myAudio.play();
}
document.body.onclick = ()=>{
if(isAudioPlayed) return ;
playAudio();
}
/*
window.onload = () => {
const myAudio = document.getElementById("my-audio");
console.log(myAudio);
myAudio.addEventListener('canplay', (event) => {
console.log("CnPlay",event)
event.target.play()
})
}
*/
</script>
</body>
</html>
Else you can use canplay event
In the Firefox extension, I want to implement a simple toggle switch that will enable/disable an extension. A basic idea is that the change of state will be saved as a boolean into browser (sync) storage. The state should be read every time, so an extension will know if should work or not.
But - my Javascript knowledge is so poor that I came into trouble.
Here is simple HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="styles.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.2/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
<form id="form" class="ps-3 mt-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="flexSwitch">
<label class="form-check-label" for="flexSwitch">Plugin ON/OFF</label>
</div>
</form>
<label id="test"></label>
<br>
<script src="options.js"></script>
</body>
</html>
And here is a simple JS file:
function CheckAndSave()
{
var state = document.getElementById("flexSwitch");
if(state.checked)
{
document.getElementById('test').innerHTML = 'ON';
browser.storage.sync.set({ delovanje: 1 });
}
else
{
document.getElementById('test').innerHTML = 'OFF';
browser.storage.sync.set({ delovanje: 0 });
}
restoreState();
}
function restoreState()
{
//browser.storage.sync.get("delovanje", function(items) { console.log(items)});
let getting4 = browser.storage.sync.get("delovanje");
getting4.then(setCurrentChoice, onError);
function onError(error) {
console.log(`Error: ${error}`);
}
function setCurrentChoice()
{
var toggle = document.getElementsByName("flexSwitch");
if (result.delovanje === 1)
toggle.checked = true;
else
toggle.checked = false;
}
}
document.addEventListener("DOMContentLoaded", restoreState);
document.getElementById("flexSwitch").addEventListener('change', CheckAndSave);
What is wrong with my code? Is my way of saving Boolean ok?
I tried to write to the console for "debugging", but I don't know how to do it - this is a pop-up after a user press an icon, and nothing is shown in the console.
Most of all you did a mistake here:
function setCurrentChoice(result)
{
var toggle = document.getElementsByName("flexSwitch");
if (result.delovanje === 1)
toggle.checked = true;
else
toggle.checked = false;
}
In this case, toggle will be array like object, but not the element you expect.
You should use document.getElementById("flexSwitch") as previously.
Another issue that you missed an argument in the setCurrentChoice function. It should take settings like this:
function setCurrentChoice(result){...}
I would also suggest to hide the logic of getting element behind the scene by either wrapping it to the function:
const getToggle = () => document.getElementById("flexSwitch")
Or even move it to the separate class and encapsulate all logic there:
class Toggle {
constructor() {
this._el = document.getElementById("flexSwitch");
}
setCheck(value) {
this._el.checked = value;
}
}
Here is the working sample:
function CheckAndSave()
{
var state = document.getElementById("flexSwitch");
if(state.checked)
{
document.getElementById('test').innerHTML = 'ON';
chrome.storage.sync.set({ delovanje: 1 });
}
else
{
document.getElementById('test').innerHTML = 'OFF';
chrome.storage.sync.set({ delovanje: 0 });
}
}
function restoreState()
{
chrome.storage.sync.get("delovanje",setCurrentChoice );
function setCurrentChoice(result)
{
var toggle = document.getElementById("flexSwitch");
if (result.delovanje === 1)
toggle.checked = true;
else
toggle.checked = false;
}
}
document.addEventListener("DOMContentLoaded", restoreState);
document.getElementById("flexSwitch").addEventListener('change', CheckAndSave);
This approach will help you reduce the code and accidental mistakes.
P.S. Here is how I worked with the storage
The code seems okay, while there are some things I would change (for refactoring purposes to match my flavour) I think it should be working without much issue.
In any case verify the following.
The browser.storage.sync API is only available from extensions, so check that the HTML and JS that you are posting are actually part of the extension that you are using.
The manifest.json is what tells the browser what resources can your extension access, verify that you did add the "storage" permission on there here you can read more about it for chrome, though it will be the same for other browsers
For debugging purposes always remember that the browser lets you have great tools. Read more about developer tools, but as a starter I would tell you to open them and put a debugger statement there where you feel like there's something that isn't working as expected. And then with the console start looking for the properties that you are not finding.
To log items to the console use console.log('XXX') and it should show what you want
I think the problem is that the change event is not fired when setting toggle.checked with JavaScript. Just call CheckAndSave(); from the end of setCurrentChoice.
The brief page below does not work. Specifically, "window.speechSynthesis.speak(msg)" does not work until the button has been pressed. If the button has been pressed then the "Hello" message works. If it has not then any calls to "window.speechSynthesis.speak(msg)" do not produce any audible output.
Suspecting that it has something to do with initialization of speechSynthesis - some things have been tried below to ensure that it is initialized when "Hello" is called. None have worked. Although it seems like it should have. It seems like it is getting properly initialized only if it is called from the button press.
The setup of the SpeechSynthesisUtterance itself is the same whether called from the button or the timeout. That setup works when called by the button. But nowhere else until it has been called by the button.
What is wrong here?
<!DOCTYPE html>
<html>
<head>
<title>Voice Test 3</title>
</head>
<body>
<div id="header">User Interface Terminal</div>
<input type="text" id="control_box"></input><br>
<button id="startButton" onclick="voicemessage('Button');">start</button><br>
<script>
function voicemessage(ttstext) {
var msg = new SpeechSynthesisUtterance(ttstext);
msg.volume = 1;
msg.rate = 0.7;
msg.pitch = 1.3;
window.speechSynthesis.speak(msg);
document.getElementById('control_box').value = ttstext;
}
window.speechSynthesis.onvoiceschanged = function() {
document.getElementById('control_box').value = "tts voices recognized";
window.setTimeout(function() {
voicemessage("Hello");
}, 5000);
};
window.addEventListener('load', function () {
var voices = window.speechSynthesis.getVoices();
})
</script>
</body>
</html>
This may be due to the browser itself...
Recent updates in some browsers (Firefox and Chrome) have policies to prevent audio from being accessed unless some user interaction triggers it (like a button click)...
Hi I am trying to disable a function with a click of a button and then enable it again once another button is clicked I have tried unbind but I am getting no where
any suggestions to how I can go about this?
Code:
Mute
Unmute
$('.MuteOn').on('click tap touch', function() {
//Disable soundListen function
});
$('.MuteOff').on('click tap touch', function() {
//Enable soundListen function
});
//
setInterval(function soundListen() {
if ($("body").hasClass("fp-viewing-1")) {
audio1.play();
} else {
audio1.pause();
audio1.currentTime = 0;
}
if ($("body").hasClass("fp-viewing-2")) {
audio2.play();
} else {
audio2.pause();
audio2.currentTime = 0;
}
if ($("body").hasClass("fp-viewing-3")) {
audio3.play();
} else {
audio3.pause();
audio3.currentTime = 0;
}
}, 100);
Thank you in advance for any suggestions.
Ok, so I understood it like this:
-On first page user can click mute/unmute button and that should be saved during navigation through all other pages/slides.
Then here is a code:
<!doctype>
<html lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title></title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<button id="mute">Mute</button>
<button id="unmute">Unmute</button>
<button id="reloadPage">Reload Page</button>
<script type="text/javascript">
//get variable from local variables or set to false(you can change it to TRUE if you like to mute on page load) by default
var isMuted = localStorage.getItem("IsMuted")||false;
//mute button onclick method
$(document).on('click','#mute',function(e){
isMuted = true;
//save to local variables
localStorage.setItem("IsMuted", isMuted);
});
//unmute button onclick method
$(document).on('click','#unmute',function(e){
isMuted = false;
//save to local variables
localStorage.setItem("IsMuted", isMuted);
});
//reload page. also you can use F5 or Ctrl+F5
$(document).on('click','#reloadPage',function(e){
location.reload();
});
$(document).ready(function(){
alert("IsMuted = "+isMuted);
//you can encapsulate this into separate function and bind to show-next-slide button
if(isMuted)
{
return;
}
else
{
//get clip id by class name or another suitable method
PlayMyCoolMusic(clipId);
}
});
function PlayMyCoolMusic(clipId)
{
//your audio player logic here
}
</script>
</body>
</html>
With this you can save you mute/unmute status even if page has been reloaded.
I have a pdf associated with a button . When i click the button i want to get the pdf printed. This is how my button is coded :
<input type="submit" class="btn-red" value="Print"
name="Submit" id="printbtn"
onclick="printPDF('http://www.irs.gov/pub/irs-pdf/fw4.pdf')" />
Now my print functionality works like this :
function printPDF(pdfUrl)
{
if ((navigator.appName == 'Microsoft Internet Explorer') )
window.print(pdfUrl,"_self");
else
{
var w = window.open(pdfUrl,"_self");
w.print();
w.close();
}
}
The problem is , it's working fine in IE and Fire fox , but does not work in chrome. In ie and Firefox, it opens up the xps printer option, but in chrome , it just opens up a new print window, with the print preview of the div and not the pdf . But i want the xps option to be opened up here.
EDIT : In chrome when i try to print , only the html element comes as preview and not the pdf. I am using chrome version : 20.0.1132.57
How can i get around this peculiarity ? kindly help .
This worked for me and didn't require a host HTML file. The key was to wait for onload:
For a link like this:
<a class="print-pdf-link" href="/your/pdf.pdf">Print PDF</a>
I used javascript:
$('a.print-pdf-link').click(function () {
var w = window.open($(this).attr('href'));
w.onload = function () {
w.print();
};
return false;
});
I had to do the same thing and I used a different approach, one that for me worked in both Chrome and Firefox.
My solution involved a print.html helper file, that received the PDF file's url as a GET type parameter, then loaded the pdf inside an iframe. Then it kept checking to see if the pdf had completely loaded (binding the check to the onload event did not work) and on completion it triggered the print method.
Here:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1">
<title>Print Page</title>
<meta name="title" content="Print" />
<script>
(function (window, document, undefined) {
var printy = {
urlGET: function (param) {
var params = document.URL.split('?');
if(params.length > 1) {
params = params[1].split('&');
for (var i = 0, len = params.length; i < len; i++) {
if (params[i].split('=')[0] === param) {
return params[i].split('=')[1];
}
}
}
return null;
},
init: function () {
var self = this;
window.onload = function () {
var src = self.urlGET('path');
//creating an iframe element
var ifr = document.createElement('iframe');
document.body.appendChild(ifr);
// making the iframe fill the viewport
ifr.width = '100%';
ifr.height = window.innerHeight;
// continuously checking to see if the pdf file has been loaded
self.interval = setInterval(function () {
if (ifr.contentDocument.readyState === 'complete') {
clearInterval(self.interval);
// doing the actual printing
ifr.contentWindow.print();
}
}, 100);
ifr.src = src;
}
}
}
printy.init();
})(window, document, undefined);
</script>
</head>
<body>
</body>
</html>
This solution is not tested on IE though. We use Macs at work so it was not an option.
In order to do the printing, I use it by calling an URL like this: http://example.com/print.html?path=docs/myfile.pdf