Related
I have JS code on a webpage that loads questions in from mysql db and displays the text . What happens is that it cuts off words at the end of the line and continues the word on the next line at the start. So all text across the screen starts/ends at the same point.
This seems to be the code where it displays the text.
For example the text will look like at the end of a line 'cont' and then on next line at the start 'inue'.
How do i fix this?
var questions = <?=$questions;?>;
// Initialize variables
//------------------------------------------------------------------
var tags;
var tagsClass = '';
var liTagsid = [];
var correctAns = 0;
var isscorrect = 0;
var quizPage = 1;
var currentIndex = 0;
var currentQuestion = questions[currentIndex];
var prevousQuestion;
var previousIndex = 0;
var ulTag = document.getElementsByClassName('ulclass')[0];
var button = document.getElementById('submit');
var questionTitle = document.getElementById('question');
//save class name so it can be reused easily
//if I want to change it, I have to change it one place
var classHighlight = 'selected';
// Display Answers and hightlight selected item
//------------------------------------------------------------------
function showQuestions (){
document.body.scrollTop = 0; // For Safari
document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera
if (currentIndex != 0) {
// create again submit button only for next pages
ulTag.innerHTML ='';
button.innerHTML = 'Submit';
button.className = 'submit';
button.id = 'submit';
if(quizPage<=questions.length){
//update the number of questions displayed
document.getElementById('quizNumber').innerHTML = quizPage;
}
}
//Display Results in the final page
if (currentIndex == (questions.length)) {
ulTag.innerHTML = '';
document.getElementById('question').innerHTML = '';
if(button.id == 'submit'){
button.className = 'buttonload';
button.innerHTML = '<i class="fa fa-spinner fa-spin"></i>Loading';
}
showResults();
return
}
questionTitle.innerHTML = "Question No:" + quizPage + " "+currentQuestion.question.category_name +"<br/>"+ currentQuestion.question.text;
if(currentQuestion.question.filename !== ''){
var br = document.createElement('br');
questionTitle .appendChild(br);
var img = document.createElement('img');
img.src = currentQuestion.question.filename;
img.className = 'imagecenter';
img.width = 750;
img.height = 350;
questionTitle .appendChild(img);
}
// create a for loop to generate the options and display them in the page
for (var i = 0; i < currentQuestion.options.length; i++) {
// creating options
var newAns = document.createElement('li');
newAns.id = 'ans'+ (i+1);
newAns.className = "notSelected listyle";
var textAns = document.createTextNode(currentQuestion.options[i].optiontext);
newAns.appendChild(textAns);
if(currentQuestion.options[i].file !== ''){
var br = document.createElement('br');
newAns .appendChild(br);
var img1 = document.createElement('img');
img1.src = currentQuestion.options[i].file;
img1.className = 'optionimg';
img1.width = 250;
img1.height = 250;
newAns .appendChild(img1);
newAns .appendChild(br);
}
var addNewAnsHere = document.getElementById('options');
addNewAnsHere.appendChild(newAns);
}
//.click() will return the result of $('.notSelected')
var $liTags = $('.notSelected').click(function(list) {
list.preventDefault();
//run removeClass on every element
//if the elements are not static, you might want to rerun $('.notSelected')
//instead of the saved $litTags
$liTags.removeClass(classHighlight);
//add the class to the currently clicked element (this)
$(this).addClass(classHighlight);
//get id name of clicked answer
for (var i = 0; i < currentQuestion.options.length ; i++) {
// console.log(liTagsid[i]);
if($liTags[i].className == "notSelected listyle selected"){
//store information to check answer
tags = $liTags[i].id;
// tagsClass = $LiTags.className;
tagsClassName = $liTags[i];
}
}
});
//check answer once it has been submitted
button.onclick = function (){
if(button.id == 'submit'){
button.className = 'buttonload';
button.innerHTML = '<i class="fa fa-spinner fa-spin"></i>Loading';
}
setTimeout(function() { checkAnswer(); }, 100);
};
}
//self calling function
showQuestions();
The website is on my local now but i can upload a screenimage if need be and the whole code of the webpage. Or is the issue in html?
edit: here is html/css code
<style>
/*========================================================
Quiz Section
========================================================*/
/*styling quiz area*/
.main {
background-color: white;
margin: 0 auto;
margin-top: 30px;
padding: 30px;
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
/*white-space: nowrap;*/
}
/*Editing the number of questions*/
.spanclass {
font-size: x-large;
}
#pages{
border: 3px solid;
display: inline-flex;
border-radius: 0.5em;
float: right;
}
#question{
word-break: break-all;
}
/*format text*/
p {
text-align: left;
font-size: x-large;
padding: 10px 10px 0;
}
.optionimg{
border: 2px solid black;
border-radius: 1.5em;
}
/*Form area width*/
/*formatting answers*/
.listyle {
list-style-type: none;
text-align: left;
background-color: transparent;
margin: 10px 5px;
padding: 5px 10px;
border: 1px solid lightgray;
border-radius: 0.5em;
font-weight: normal;
font-size: x-large;
display: inline-grid;
width: 48%;
height: 300px;
overflow: auto;
}
.listyle:hover {
background: #ECEEF0;
cursor: pointer;
}
/*Change effect of question when the questions is selected*/
.selected, .selected:hover {
background: #FFDEAD;
}
/*change correct answer background*/
.correct, .correct:hover {
background: #9ACD32;
color: white;
}
/*change wrong answer background*/
.wrong, .wrong:hover {
background: #db3c3c;
color: white;
}
/*========================================================
Submit Button
========================================================*/
.main button {
text-transform: uppercase;
width: 20%;
border: none;
padding: 15px;
color: #FFFFFF;
}
.submit:hover, .submit:active, .submit:focus {
background: #43A047;
}
.submit {
background: #4CAF50;
min-width: 120px;
}
/*next question button*/
.next {
background: #fa994a;
min-width: 120px;
}
.next:hover, .next:active, .next:focus {
background: #e38a42;
}
.restart {
background-color:
}
/*========================================================
Results
========================================================*/
.circle{
position: relative;
margin: 0 auto;
width: 200px;
height: 200px;
background: #bdc3c7;
-webkit-border-radius: 100px;
-moz-border-radius: 100px;
border-radius: 100px;
overflow: hidden;
}
.fill{
position: absolute;
bottom: 0;
width: 100%;
height: 80%;
background: #31a2ac;
}
.score {
position: absolute;
width: 100%;
top: 1.7em;
text-align: center;
font-family: Arial, sans-serif;
color: #fff;
font-size: 40pt;
line-height: 0;
font-weight: normal;
}
.circle p {
margin: 400px;
}
/*========================================================
Confeeti Effect
========================================================*/
canvas{
position:absolute;
left:0;
top:11em;
z-index:0;
border:0px solid #000;
}
.imagecenter{
display: block;
margin: 0 auto;
}
.buttonload {
background-color: #04AA6D; /* Green background */
border: none; /* Remove borders */
color: white; /* White text */
padding: 12px 24px; /* Some padding */
font-size: 16px; /* Set a font-size */
}
/* Add a right margin to each icon */
.fa {
margin-left: -12px;
margin-right: 8px;
}
#media only screen and (max-width: 900px){
.listyle {
width: 100% !important;
height: auto !important;
}
.imagecenter {
width: 100% !important;
}
.listyle img{
width: inherit !important;
height: unset !important;
}
.ulclass
{
padding:0px !important;
}
}
</style>
<!-- Main page -->
<div class="main">
<!-- Number of Question -->
<div class="wrapper" id="pages">
<span class="spanclass" id="quizNumber">1</span><span class="spanclass">/<?=$count?></span>
</div>
<!-- Quiz Question -->
<div class="quiz-questions" id="display-area">
<p id="question"></p>
<ul class="ulclass" id="options">
</ul>
<div id="quiz-results" class="text-center">
<button type="button" name="button" class="submit" id="submit">Submit</button>
</div>
</div>
</div>
<canvas id="canvas"></canvas>
<script src="https://code.jquery.com/jquery-3.2.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script>
I'm guessing that #question{ word-break: break-all; } is probably the culprit then? –
CB..yes that fixed it:)
I am trying to solve my problem with if-else in Javascript.
I would highly appreciate your help.
I wanted to filter the name via gender, also safe the keys - woman / man to local storage.
But I can not find out how to make if-else clause.
Can someone help me?
There is also the link:
https://drive.google.com/file/d/1RNJxbiU_DsFTCqGJWgxpepCgdOhGuzIj/view?usp=sharing
Thanks a lot, it means world to me, I am new here. :-)
$(document).ready(function() {
function displayName() {
let safeNameVal = localStorage.getItem('woman');
let safeName;
if (safeNameVal) {
safeName = JSON.parse(safeNameVal);
} else {
safeName = [];
}
//find list
let nameUl = $('#list_2');
nameUl.empty(); //.html('')
//making list
$.each(safeName, function(key, name) {
let nameLi = $('<li></li>');
nameLi.text(name);
//remove link
let jmenoRemoveLink = $('x');
jmenoRemoveLink.click(function(e) {
e.preventDefault();
//name
let safeNameVal = localStorage.getItem('woman');
let safeName;
if (safeNameVal) {
safeName = JSON.parse(safeNameVal);
} else {
safeName = [];
}
//remove
safeName.splice(key, 1);
//safe name
localStorage.setItem('woman', JSON.stringify(safeName));
//display name
displayName();
});
nameLi.append(jmenoRemoveLink);
nameUl.append(nameLi);
});
}
$('#formular').submit(function(e) {
e.preventDefault();
let zadaneJmeno = $('#name').val();
if (zadaneJmeno) {
//safe
let safeNameVal = localStorage.getItem('woman');
let safeName;
if (safeNameVal) {
safeName = JSON.parse(safeNameVal);
} else {
safeName = [];
}
safeName.push(zadaneJmeno);
localStorage.setItem('woman', JSON.stringify(safeName)); /// ["Tom"]
//list
displayName();
$('#name').val('');
} else {
// alert
alert('please enter the name"');
$('#name').focus();
}
});
$('#removeAll').click(function() {
localStorage.setItem('woman', '[]'); ///localStorage.setItem('woman', JSON.stringify([]));
displayName();
});
displayName();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="formular">
<label for="name">Enter the name</label>
<input type="text" id="name" required />
<label for="section">Gender</label>
<select name="selectSection" id="section" required>
<option value="">---</option>
<option value="man" id="man">man</option>
<option value="woman" id="woman">woman</option>
</select>
<input type="submit" value="add" />
</form>
<button id="removeAll">Remove</button>
<div id="man_div">
<h1>man:</h1>
<ul id="list"></ul>
</div>
<div id="woman_div">
<h1>woman:</h1>
<ul id="list_2"></ul>
</div>
I made a number of changes to your script, do note that as I am solving your problem, I removed the 'x' function on click because it is too verbose to read while solving your problem, do add it back later, and make sure you remove from the correct localStorage.
$(document).ready(function () {
function displayName() {
//Separate the local storage into man and woman keys
let manSafeNameVal = localStorage.getItem('man');
let manSafeName;
let womanSafeNameVal = localStorage.getItem('woman');
let womanSafeName
if (manSafeNameVal) {
manSafeName = JSON.parse(manSafeNameVal);
} else {
manSafeName = [];
}
if (womanSafeNameVal) {
womanSafeName = JSON.parse(womanSafeNameVal);
} else {
womanSafeName = [];
}
//find list
//Use list and list_2 to display
let manUl = $('#list');
let womanUl = $('#list_2');
manUl.empty(); //.html('')
womanUl.empty();
//list for man
$.each(manSafeName, function (key, name) {
let nameLi = $('<li></li>');
nameLi.text(name);
//do add back your 'x' remove here, because it is too verbose to read when I am trying to read the code
manUl.append(nameLi);
});
//list for woman
$.each(womanSafeName, function (key, name) {
let nameLi = $('<li></li>');
nameLi.text(name);
//Also here, the 'x' for woman list
womanUl.append(nameLi);
});
}
$('#formular').submit(function (e) {
e.preventDefault();
let zadaneJmeno = $('#name').val();
//get the selected gender, either man or woman
let gender = $('#section').val();
console.log(gender);
console.log(zadaneJmeno);
if (zadaneJmeno && gender !== "") {
//safe into the localStorage of selected gender
let safeNameVal = localStorage.getItem(gender);
let safeName;
if (safeNameVal) {
safeName = JSON.parse(safeNameVal);
} else {
safeName = [];
}
safeName.push(zadaneJmeno);
localStorage.setItem(gender, JSON.stringify(safeName));/// ["Tom"]
//list
displayName();
$('#name').val('');
} else {
// alert
alert('please enter the name"');
$('#name').focus();
}
});
$('#removeAll').click(function () {
localStorage.setItem('woman', '[]'); ///localStorage.setItem('woman', JSON.stringify([]));
displayName();
});
displayName();
});
const katText = document.getElementById('txtKategorie');
const oText=document.querySelector('input[homework="homework"]');
// selektor tlačítka uložit úkol
const oBttn=document.querySelector('input[type="submit"]');
// selektor tlačítka na odstranění všech úkolů z kategorie
const oDelete=document.querySelector('button#removeAll');
const createlist=function(){
let parent=document.getElementById('lists');
Object.keys(localStorage).forEach(function (key) {
let category = key;
let div = document.createElement('div');
div.id = category;
let h1 = document.createElement('h1');
h1.textContent = category;
let ul = document.createElement('ul');
div.appendChild(h1);
div.appendChild(ul);
div.onclick = oznacDiv;
parent.appendChild(div);
});
parent.querySelectorAll('div').forEach( div=>{
div.addEventListener('click',function(e){
// odstranění určité položky
if( e.target!=e.currentTarget && e.target.tagName=='A') deleteitem( e );
});
// při načtení stránky načíst úkoly z localStorage a vytvoření listu
// podmmínka -- pokud není úložiště prázdné
let store=div.id;
if( localStorage.getItem(store)!=null )JSON.parse( localStorage.getItem( store ) ).forEach( homework=>{
addlistitem(homework,store);
})
});
}
//na klik oznaci div
function oznacDiv() {
if (oBttn.disabled) oBttn.disabled = false;
document.querySelectorAll('div.active').forEach(div => {
div.classList.remove('active')
});
document.querySelector('div#' + this.id).classList.add('active')
}
const clearstoreitems=function(category){
localStorage.setItem( category, JSON.stringify([]) );
document.querySelector( 'div#' + category ).querySelector('ul').innerHTML='';
};
const deleteitem=function(e){
let parent=e.target.parentNode;
let homework=parent.dataset.homework;
let category=parent.dataset.category;
parent.parentNode.removeChild(parent);
let data=JSON.parse(localStorage.getItem(category));
if( data!=null )data.splice(data.indexOf(homework),1);
localStorage.setItem(category,JSON.stringify(data));
};
const addlistitem=function(homework,category){
let p=document.createElement('button');
p.innerHTML=' Uprava';
p.onclick =function(){
editWorking(li);
}
let a=document.createElement('a');
a.href='#';
a.innerHTML=' Hotovo';
let li=document.createElement('li');
li.value=homework;
li.textContent=homework;
li.dataset.homework=homework;
li.dataset.category=category;
li.appendChild( a );
li.appendChild(p);
document.querySelector( 'div#' + category ).querySelector('ul').appendChild( li );
};
function editWorking(e){
let editValue = prompt('Přejete si upravit úkol?', e.firstChild.nodeValue);
e.firstChild.nodeValue = editValue;
let parent=e.parentNode;
let homework=parent.dataset.homework;
let category=parent.dataset.category;
addlistitem(editValue,category);
addstoreitem(editValue,category);
}
const addstoreitem=function(homework,category){
let data=localStorage.getItem( category );
if( data!=null ){
let json=JSON.parse( data );
json.push(homework);
data=JSON.stringify(json);
}
else
{
data=JSON.stringify([homework]);
}
localStorage.setItem( category, data );
};
//prida novej div s kategorii a poznamkou
const addNewItemList = function () {
let parent = document.getElementById('lists');
let category = katText.value;
let div = document.createElement('div');
div.id = category;
let h1 = document.createElement('h1');
h1.textContent = category;
let ul = document.createElement('ul');
div.appendChild(h1);
div.appendChild(ul);
div.onclick = oznacDiv;
parent.appendChild(div);
parent.querySelectorAll('div').forEach(div => {
div.addEventListener('click', function (e) {
// odstranění určité položky
if (e.target != e.currentTarget && e.target.tagName == 'A') deleteitem(e);
});
// při načtení stránky načíst úkoly z localStorage a vytvoření listu
// podmmínka -- pokud není úložiště prázdné
let store = div.id;
if (localStorage.getItem(store) != null) JSON.parse(localStorage.getItem(store)).forEach(homework => {
addlistitem(homework, store);
})
});
}
oBttn.addEventListener('click',function(e){
e.preventDefault();
if (oText.value != '') {
if (katText.value != '') {
if (document.querySelector('div#' + katText.value) == null) {
addNewItemList()
}
addlistitem(oText.value, katText.value);
addstoreitem(oText.value, katText.value);
oText.value = '';
return true;
} else {
alert('Zadejte kategorii prosím...');
}
} else {
alert('Zadejte úkol prosím...');
}
});
// vymazat, resetovat pole
oDelete.addEventListener('click', function (e) {
document.querySelectorAll('div.active').forEach(div => {
//clearstoreitems(document.querySelectorAll('div.active').id);
clearstoreitems(div.id);
//div.classList.remove('active')
});
});
createlist();
#charset "UTF-8";
/* CSS Document */
#import url('https://fonts.googleapis.com/css2?family=Poppins:wght#100;200;300;400;500;600;700;800;900&display=swap');
*{
padding: 100;
margin: 100;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
/**styly pro tělo celé aplikace **/
body{
background: rgb(131,58,180);
background: linear-gradient(90deg, rgba(131,58,180,1) 0%, rgba(253,29,29,1) 50%, rgba(252,176,69,1) 100%);
/* background: linear-gradient(139deg, rgba(193,62,62,1) 0%, rgba(230,179,50,1) 100%);
background-image: url("pozadi.png");*/
overflow-x: hidden;
background-repeat: no-repeat;
background-size: cover;
background-position: center;
background-attachment: fixed;
height: 100%;
}
.weather{
width: 100%;
margin: 20px;
padding: 30px;
}
/** pomohla jsem si tady https://the-echoplex.net/flexyboxes/ **/
/**
.flex-container {
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-webkit-flex-wrap: nowrap;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
-webkit-align-content: center;
-ms-flex-line-pack: center;
align-content: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
}
.flex-item:nth-child(1) {
-webkit-order: 0;
-ms-flex-order: 0;
order: 0;
-webkit-flex: 0 1 auto;
-ms-flex: 0 1 auto;
flex: 0 1 auto;
-webkit-align-self: auto;
-ms-flex-item-align: auto;
align-self: auto;
}
.flex-item:nth-child(2) {
-webkit-order: 0;
-ms-flex-order: 0;
order: 0;
-webkit-flex: 0 100 auto;
-ms-flex: 0 100 auto;
flex: 0 100 auto;
-webkit-align-self: auto;
-ms-flex-item-align: auto;
align-self: auto;
}
**/
/**nadpis aplikace **/
#nadpis {
/** margin: auto;
width: 50%;
padding: 5px; **/
text-align: center;
font-size: 40px;
}
.predpoved {
/** width: 30%; **/
border-radius: 15px 50px;
border:4px solid white;
background: black;
-webkit-box-shadow: 7px 8px 6px 0px rgba(0,0,0,0.52);
box-shadow: 7px 8px 6px 0px rgba(0,0,0,0.52);
margin:0 auto;
height: 10%;
width:60%;
padding: 0 auto;
}
.nadpis_1{
font-size: 50px;
color:white;
font:bold;
}
label{
color:white;
font:oblique;
text-transform:inherit;
}
#lists > div{
padding:1rem;
margin:1rem auto;
border-radius: 15px 50px;
border:4px solid white;
margin-left: 30px;
margin-right: 30px;
-webkit-box-shadow: 7px 8px 6px 0px rgba(0,0,0,0.52);
box-shadow: 7px 8px 6px 0px rgba(0,0,0,0.52);
}
.active{
background: linear-gradient(90deg, rgba(252,176,69,1) 0%, rgba(253,29,29,1) 50%, rgba(131,58,180,1)100%);
}
h1{
text-transform:capitalize;
color:white;
}
ul{
list-style: square;
}
ul li{
color:white;
margin-top: 40px;
font-size: 20px;
}
ul a {
color:white;
font:oblique;
padding: 10px;
margin:10px;
margin-left:100px;
border-radius: 15px ;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
}
ul a:hover {
color:white;
font:oblique;
background:rgba(252,176,69,1);
padding: 10px;
margin:10px;
margin-left:100px;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
}
form{
color: white;
padding: 20px;
width: 600px;
margin: 0 auto;
height: auto;
}
#removeAll{
color:white;
font:oblique;
background: black;
border-radius: 15px ;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
margin: 0 auto;
height: auto;
padding:10px;
margin-left: 30px;
margin-right: 30px;
}
#removeAll:hover {
color:white;
font:oblique;
background: red;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
padding:10px;
margin: 0 auto;
height: auto;
margin-left: 30px;
margin-right: 30px;
}
#refresh{
color:white;
font:oblique;
background: black;
border-radius: 15px ;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
margin: 0 auto;
height: auto;
padding: 10px;
}
#refresh:hover {
color:white;
font:oblique;
background: red;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
padding:10px;
margin: 0 auto;
height: auto;
}
#safe{
color:white;
font:oblique;
background: black;
border-radius: 15px ;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
margin: 0 auto;
height: auto;
padding: 10px;
}
#safe:hover {
color:white;
font:oblique;
background: red;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
padding:10px;
margin: 0 auto;
height: auto;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Deadline</title>
<link rel="stylesheet" href="style.css">
<script src="//code.jquery.com/jquery-3.3.1.min.js"></script>
</head>
<body>
<div class="flex-container">
<div id="nadpis">
<h1>Deadline</h1>
<form>
<label for="txtHomework">Your homework.. </label>
<input type="text" id="txtHomework" homework="homework" required />
<label for="txtKategorie">Category</label>
<input type="text" id="txtKategorie" kategorie="valKategorie" required />
<!--<select name="selectSection" required>
<option selected hidden disabled>---</option>
<option value="škola">Škola</option>
<option value="Práce">Práce</option>
<option value="Doma">Doma</option>
<option value="Jiné">Jiné</option>
</select>-->
<!--</label>-->
<!-- tlačítko uložit je nedostupné dokud nevybereme kategorii a nezapíšeme úkol -->
<input id ="safe" type="submit" value="Uložit" />
</form>
<div id="lists"></div>
<button id="removeAll">Vyčistit kategorii</button>
I know you already have a solution but I offer an alternative, in vanilla Javascript rather than jQuery, that splits the names according to gender - assigns them to individual areas in localStorage based upon gender and has the functionality to remove individual items from the store. Any items stored in any of the generated stores will be used to populate the HTML lists on page load. I don't use jQuery which is why I wrote this in plain js - no doubt you can cherrypick things from it that might be useful - I hope that it is useful anyway.
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>Gender splitter</title>
<style>
#lists > div{
padding:1rem;
margin:1rem auto;
border:1px dotted gray;
}
.active{
background:whitesmoke
}
h1{text-transform:capitalize}
</style>
</head>
<body>
<form>
<label>Enter the name
<input type='text' name='name' required />
</label>
<label>Gender
<select name='selectSection' required>
<option selected hidden disabled>---
<option value='male'>Male
<option value='female'>Female
<option value='teapot'>Teapot
<option value='crocodile'>Crocodile
</select>
</label>
<!-- initially disabled to prevent adding when no gender is selected -->
<input type='submit' value='add' disabled />
</form>
<button id='removeAll'>Remove</button>
<div id='lists'></div>
<script>
const oSelect=document.querySelector('select[name="selectSection"]');
const oText=document.querySelector('input[name="name"]');
const oBttn=document.querySelector('input[type="submit"]');
const oDelete=document.querySelector('button#removeAll');
// generate the necessary HTML nodes to display names/genders based
// upon the options in the select menu.
const createlist=function(){
let parent=document.getElementById('lists');
oSelect.querySelectorAll('option').forEach( option=>{
if( option.value !== oSelect.childNodes[1].value ){
let gender=option.value;
let div=document.createElement('div');
div.id=gender;
let h1=document.createElement('h1');
h1.textContent=gender;
let ul=document.createElement('ul');
div.appendChild(h1);
div.appendChild(ul);
parent.appendChild( div );
}
});
parent.querySelectorAll('div').forEach( div=>{
div.addEventListener('click',function(e){
// delete specific item from the store
if( e.target!=e.currentTarget && e.target.tagName=='A') deleteitem( e );
});
// load any names from the store on page load and recreate the lists
let store=div.id;
if( localStorage.getItem(store)!=null )JSON.parse( localStorage.getItem( store ) ).forEach( name=>{
addlistitem(name,store);
})
});
}
// erase store content by gender and clear html list display
const clearstoreitems=function(gender){
localStorage.setItem( gender, JSON.stringify([]) );
document.querySelector( 'div#' + gender ).querySelector('ul').innerHTML='';
};
// delete specific item from particular store
const deleteitem=function(e){
let parent=e.target.parentNode;
let name=parent.dataset.name;
let gender=parent.dataset.gender;
parent.parentNode.removeChild(parent);
let data=JSON.parse(localStorage.getItem(gender));
if( data!=null )data.splice(data.indexOf(name),1);
localStorage.setItem(gender,JSON.stringify(data));
};
// add new item to HTML list based upon gender
const addlistitem=function(name,gender){
let a=document.createElement('a');
a.href='#';
a.innerHTML='X';
let li=document.createElement('li');
li.value=name;
li.textContent=name;
li.dataset.name=name;
li.dataset.gender=gender;
li.appendChild( a );
document.querySelector( 'div#' + gender ).querySelector('ul').appendChild( li );
};
// add new name to the localStorage in gender specific named store
const addstoreitem=function(name,gender){
let data=localStorage.getItem( gender );
if( data!=null ){
let json=JSON.parse( data );
json.push(name);
data=JSON.stringify(json);
} else { data=JSON.stringify([name]); }
localStorage.setItem( gender, data );
};
// Add new item listener
oBttn.addEventListener('click',function(e){
e.preventDefault();
if( oText.value!='' ){
addlistitem(oText.value,oSelect.value);
addstoreitem(oText.value,oSelect.value);
oText.value='';
return true;
}
alert('Name please...');
});
oSelect.addEventListener('change',function(e){
// ensure the "Add" button is enabled
if( oBttn.disabled )oBttn.disabled=false;
document.querySelectorAll('div.active').forEach( div=>{
div.classList.remove('active')
});
// assign a class to visually identify which gender is selected
document.querySelector( 'div#' + this.value ).classList.add('active')
});
// erase this entire store - reset to empty array
oDelete.addEventListener('click',function(e){
clearstoreitems(oSelect.value);
});
createlist();
</script>
</body>
</html>
I do my ToDo list. (I learn vanilla JS). And I have some problem with saving some items to localStorage. When I use Google chrome(F12), I see undefiend. Maybe, I do not save correctly to localStorage. I tried to change var task to array, but it does not help. Pleas, show me my mistakes. I know, my code must be rewritten, it is my first code on JS. P.s. in console (in stackOverflow) I have that error
{
"message": "Uncaught SyntaxError: Unexpected identifier",
"filename": "https://stacksnippets.net/js",
"lineno": 348,
"colno": 6
}
but in my browser not.
var task = document.querySelector("ul");
var forTask;
function toLocal(){
forTask = task.innerHTML;
localStorage.setItem("forLocal",forTask);
}
function newElement(newChild) {
let btnDel= document.createElement("button");
btnDel.className = "fa fa-trash-o";
let myEd = document.getElementById("myEdit");
let spanClose1 = document.getElementsByClassName("close1")[0];
let spanRedact = document.getElementsByClassName("redact")[0];
let myDel = document.getElementById("myDelete");
let spanClose = document.getElementsByClassName("close")[0];
let spanYes = document.getElementsByClassName("yes")[0];
//create button
let divWithBut = document.createElement("div");
divWithBut.className = "forButt";
let btnRedact = document.createElement("button");
btnRedact.className = "fa fa-pencil";
//redact but
btnRedact.onclick = function(){
myEd.style.display = "block";
let editText = document.getElementById("editText");
let divWithText = divWithBut.parentElement.getElementsByClassName("todoPost")[0];
editText.value = divWithText.innerHTML;
editText.currentTarget;
spanRedact.onclick = function(){
divWithText.textContent = editText.value;
divWithText.className = "todoPost";
myEd.style.display = "none";
};
spanClose1.onclick = function() {
myEd.style.display = "none";
};
}
/*************************** */
/*done but*/
let doneBut = document.createElement("button");
doneBut.className = "fa fa-check-circle-o";
doneBut.onclick = function(){
let divWithText = divWithBut.parentElement.getElementsByClassName("todoPost")[0];
divWithText.classList.toggle("checked");
}
/******************* */
divWithBut.appendChild(btnRedact);
divWithBut.appendChild(doneBut);
divWithBut.appendChild(btnDel);
/******************/
//for index
let indexDiv = document.createElement("div");
indexDiv.className = "indexDiv";
let numbInd = 1;
indexDiv.innerHTML = numbInd;
/*********************************** */
//create arrow
let divWithArrow = document.createElement("div");
divWithArrow.className = "myArrow";
let arrowUP = document.createElement("i");
arrowUP.className = "fa fa-chevron-up";
let arrowDown = document.createElement("i");
arrowDown.className = "fa fa-chevron-down";
divWithArrow.appendChild(arrowUP);
divWithArrow.appendChild(arrowDown);
//for date
let date = new Date();
let curr_date = date.getDate();
let curr_month = date.getMonth()+1;
let curr_year = date.getFullYear();
let curr_hour = date.getHours();
let curr_minutes = date.getMinutes();
let d = (curr_date + "." + curr_month + "." + curr_year+"<br>"+curr_hour+":"+curr_minutes);
let divTime = document.createElement("div");
divTime.style.textAlign = "center";;
divTime.innerHTML = d;
//***************************/
let div1 = document.createElement("div");
div1.className = "timeComent";
let myli = document.createElement("li");
myli.className = "todoPost";
let addField = document.getElementById("addField").value;
task = document.createTextNode(addField);
myli.appendChild(task);
div1.appendChild(divTime);
div1.appendChild(indexDiv);
div1.appendChild(divWithArrow);
div1.appendChild(myli);
divWithBut.style.display = "flex";
div1.appendChild(divWithBut);
if (addField === '') {
alert("You must write something!");
} else {
document.getElementById("forToDo").appendChild(div1);
toLocal();
}
document.getElementById("addField").value = "";
//delete but
btnDel.onclick = function(){
myDel.style.display = "block";
spanClose.onclick = function() {
myDel.style.display = "none";
};
spanYes.onclick = function() {
myDel.style.display = "none";
div1.remove();
};
}
toLocal();
}
if(localStorage.getItem("forLocal")){
task.innerHTML = localStorage.getItem("forLocal");
}
*{
margin: 0;
padding: 0;
}
header{
width: 100%;
display: flex;
align-items: center;
align-content: center;
justify-content: center;
overflow: auto;
}
.firstBar{
width: 100%;
display: flex;
align-items: center;
align-content: center;
justify-content: center;
overflow: auto;
}
.indexDiv{
font-style: normal;
text-align: center;
color: #fff;
width: 15px;
height: 20px;
margin: 10px;
background-color: #888;
}
.fafaArrow{
font-size: 24px;
color: #000;
}
.timeComent{
margin-top: 15px;
margin-bottom: 15px;
display: flex;
justify-content:center;
align-items: center;
}
.numberpost{
padding: 5px;
color: rgb(255, 255, 255);
background: rgb(141, 112, 112);
}
.todoPost{
background-color: #eee;
width: 50%;
margin: 5px;
overflow: auto;
text-align: justify;
}
.shadow {
background: rgba(102, 102, 102, 0.5);
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
display: none;
}
.window {
width: 300px;
height: 50px;
text-align: center;
padding: 15px;
border: 3px solid #0000cc;
border-radius: 10px;
color: #0000cc;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
background: #fff;
}
.shadow:target {display: block;}
.redact {
display: inline-block;
border: 1px solid #0000cc;
color: #0000cc;
margin: 10px;
text-decoration: none;
background: #f2f2f2;
font-size: 14pt;
cursor:pointer;
right: 0;
top: 0;
padding: 12px 16px 12px 16px;
}
.redact:hover {
background-color: #68f462;
color: white;}
.close{
display: inline-block;
border: 1px solid #0000cc;
color: #0000cc;
margin: 10px;
text-decoration: none;
background: #f2f2f2;
font-size: 14pt;
cursor:pointer;
right: 0;
top: 0;
padding: 12px 16px 12px 16px;
}
.close:hover{
background-color: #f44336;
color: white;
}
/* Style the close button */
.close3 {
position: absolute;
right: 0;
top: 0;
padding: 12px 16px 12px 16px;
}
.yes {
display: inline-block;
border: 1px solid #0000cc;
color: #0000cc;
margin: 10px;
text-decoration: none;
background: #f2f2f2;
font-size: 14pt;
cursor:pointer;
right: 0;
top: 0;
padding: 12px 16px 12px 16px;
}
.yes:hover{
background-color: #68f462;
color: white;
}
.close1{
display: inline-block;
border: 1px solid #0000cc;
color: #0000cc;
margin: 10px;
text-decoration: none;
background: #f2f2f2;
font-size: 14pt;
cursor:pointer;
right: 0;
top: 0;
padding: 12px 16px 12px 16px;
}
.close1:hover{
background-color: #f44336;
color: white;
}
/* When clicked on, add a background color and strike out text */
div li.checked {
background: #888;
color: #fff;
text-decoration: line-through;
}
/* Add a "checked" mark when clicked on */
div li.checked::before {
content: '';
position: absolute;
border-color: #fff;
border-style: solid;
border-width: 0 2px 2px 0;
top: 10px;
left: 16px;
transform: rotate(45deg);
height: 15px;
width: 7px;
}
<!DOCTYPE html>
<html>
<head>
<title>TO DO List</title>
<link rel="stylesheet" type="text/css" href="styles/style.css" >
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<header>
<input id="addField" type="text" size="70%" placeholder="Task" name="Task">
<button type="button" onclick="newElement()">Add</button>
</header>
<div>
<div class="firstBar">
<div class="fafaArrow">
<i class="fa fa-caret-up" ></i>
<i class="fa fa-caret-down"></i>
<input class="inptxt" type="text" size="50%" name="Task">
<i class="fa fa-filter"></i>
</div>
</div>
</div>
<ul id="forToDo" >
</ul>
<div id="myDelete" class="shadow">
<div class="window">Delete item?<br>
<span class="yes">Yes</span>
<span class="close">No</span>
</div>
</div>
<div id="myEdit" class="shadow">
<div class="window">
Edit text?<br>
<label>
<textarea id="editText"></textarea>
</label>
<span class="redact">Save</span>
<span class="close1">Cancel</span>
</div>
</div>
<script src="js/script2.js"></script>
</body>
</html>
When you add an element to the page, at a certain point you do this
task = document.createTextNode(addField);
Since task is a global variable (you declared it at the top), you're overshadowing it with the TextNode you're creating, so that when you then call toLocal and you do
forTask = task.innerHTML;
task has no innerHTML attribute, so it returns undefined.
Also, for some reason, you call toLocal again at the end of newElement. It's not the problem but it's something you may want to think about. I'm not sure it's what you want.
#TakayashiHarano gave a couple of hints to solve this, but I'm not sure what you want is just to have the latest element in the local storage. So I would re-write toLocal so that it takes a string (the text of the item) as input, writes it at the end of a JSON array (already populated with what was in the local storage previously), and puts the array back in local storage.
function toLocal(toAdd) {
let storage = localStorage.getItem('forLocal');
if (storage === null) {
storage = [];
} else {
storage = JSON.parse(storage);
}
storage.push(toAdd);
localStorage.setItem('forLocal', JSON.stringify(storage));
}
Then you should modify the part of the code that reads the local storage (the one at the end) to basically simulate adding a new item as you would do when creating a new task, but for each item in the parsed JSON coming from local storage.
To be fair, your code needs a good dose of rewriting to achieve this, so I'll just leave you with this as an exercise.
The following changes are needed.
1 - Set up two variables separably for the following task variable.
var task = document.querySelector("ul");
task = document.createTextNode(addField);
For example, "ulElement" for the first one, and "task" for the second one.
This is to prevent to override the previously defined value.
2 - Move the timing for obtaining the ul element and load localStorage.
function onReady() {
ulElement = document.querySelector("ul");
if(localStorage.getItem("forLocal")){
ulElement.innerHTML = localStorage.getItem("forLocal");
}
}
window.addEventListener('DOMContentLoaded', onReady, true);
To ensure the element existence, document.querySelector() should be called after the DOMContentLoaded event fired.
https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event
3 - Delete toLocal(); in the end of the newElement() function.
As far as my testing code, there is no need this statement.
I'm trying to create a simple metronome using the web audio oscillator, so that no external audio files are needed. I'm creating the sound of the metronome by ramping the volume of the oscillator up and down very quickly (since you can't use start() and stop() more than once), and then repeating that function at a set interval. It ends up sounding like a nice little wood block.
The code below works/sounds great in Chrome, Safari and Opera. But in Firefox, there's a nasty intermittent "click" when the volume ramps up. I've tried changing the attack/release times to get rid of the click, but they have to be really, really long before it consistently disappears. So long, in fact, that the oscillator just sounds like a sustained note.
var audio = new (window.AudioContext || window.webkitAudioContext)();
var tick = audio.createOscillator();
var tickVol = audio.createGain();
tick.type = 'sine';
tick.frequency.value = 1000;
tickVol.gain.value = 0; //setting the volume to 0 before I connect everything
tick.connect(tickVol);
tickVol.connect(audio.destination);
tick.start(0);
var metronome = {
start: function repeat() {
now = audio.currentTime;
//Make sure volume is 0 and that no events are changing it
tickVol.gain.cancelScheduledValues(now);
tickVol.gain.setValueAtTime(0, now);
//Play the osc with a super fast attack and release so it sounds like a click
tickVol.gain.linearRampToValueAtTime(1, now + .001);
tickVol.gain.linearRampToValueAtTime(0, now + .001 + .01);
//Repeat this function every half second
click = setTimeout(repeat, 500);
},
stop: function() {
if(typeof click !== 'undefined') {
clearTimeout(click);
tickVol.gain.value = 0;
}
}
}
$("#start").click(function(){
metronome.start();
});
$("#stop").click(function(){
metronome.stop();
});
Codepen
Is there any way to get FF to sound like the other 3 browsers?
I was getting the exact same problem in latest Opera and found the problem to be the individual sounds 'decimal time length'.
I wrote a morse code translator, and like yours, it's just a series of simple short sounds/beeps created via createOscillator.
With morse code you have a speed count (words per minute) based on a 5 letter long word like codex or paris.
To get 20 or 30 paris' per minute to finish exactly on the minute, I had to use a sound time length of, for example, 0.61. In Opera, this caused the 'end of sound click'. On changing this to 0.6 and the click disappeared across all browsers - except Firefox.
I've tried freq = 0 and gain = 0 between sounds but still get the click at the end in FF and I don't know enough about Web Audio to try anything else.
On another note, I noticed you're using a loop and timeout to get to the next tick. Have you tried an 'Oscillator onended function' instead? I've used it with a simple counter increment and variable length blank sound/note. Go to the very end of my JS if you want to have a look.
**UPDATE - I've been fiddling about with setValueAtTime() and linearRampToValueAtTime() and appeared to have cracked the click problem. Scroll to bottom of script to see example. **
(function(){
/* Morse Code Generator & Translator - Kurt Grigg 2003 (Updated for sound and CSS3) */
var d = document;
d.write('<div class="Mcontainer">'
+'<div class="Mtitle">Morse Code Generator Translator</div>'
+'<textarea id="txt_in" class="Mtxtarea"></textarea>'
+'<div class="Mtxtareatitle">Input</div>'
+'<textarea id="txt_out" class="Mtxtarea" style="top: 131px;"></textarea>'
+'<div class="Mtxtareatitle" style="top: 172px;">Output</div>'
+'<div class="Mbuttonwrap">'
+'<input type="button" class="Mbuttons" id="how" value="!">'
+'<input type="button" class="Mbuttons" id="tra" value="translate">'
+'<input type="button" class="Mbuttons" id="ply" value="play">'
+'<input type="button" class="Mbuttons" id="pau" value="pause">'
+'<input type="button" class="Mbuttons" id="res" value="reset"></div>'
+'<select id="select" class="Mselect">'
+'<option value=0.07 selected="selected">15 wpm</option>'
+'<option value=0.05>20 wpm</option>'
+'<option value=0.03>30 wpm</option>'
+'</select>'
+'<div class="sliderWrap">volume <input id="volume" type="range" min="0" max="1" step="0.01" value="0.05"/></div>'
+'<div class="Mchckboxwrap">'
+'<span style="text-align: right;">separator <input type="checkbox" id="slash" class="Mchckbox"></span>'
+'</div>'
+'<div id="about" class="Minfo">'
+'<b>Input morse</b><br>'
+'<ul><li>Enter morse into input box using full stop (period) and minus sign (hyphen)</li>'
+'<li>Morse letters must be separated by 1 space</li>'
+'<li>Morse words must be separated by 3 or more spaces</li>'
+'<li>You can use / to separate morse words. There must be at least 1 space before and after each separator used</li>'
+'</ul>'
+'<b>Input text</b><br>'
+'<ul class="Mul"><li>Enter text into input box</li>'
+'<li>Characters that cannot be translated will be ignored</li>'
+'<li>If morse and text is entered, the converter will assume morse mode</li></ul>'
+'<input type="button" value="close" id="clo" class="Mbuttons">'
+'</div><div id="mdl" class="modal"><div id="bdy"><div id="modalMsg">A MSG</div><input type="button" value="close" id="cls" class="Mbuttons"></div></div></div>');
var ftmp = d.getElementById('mdl');
var del;
d.getElementById('tra').addEventListener("click", function(){convertToAndFromMorse(txtIn.value);},false);
d.getElementById('ply').addEventListener("click", function(){CancelIfPlaying();},false);
d.getElementById('pau').addEventListener("click", function(){stp();},false);
d.getElementById('res').addEventListener("click", function(){Rst();txtIn.value = '';txtOt.value = '';},false);
d.getElementById('how').addEventListener("click", function(){msgSelect();},false);
d.getElementById('clo').addEventListener("click", function(){fadeOut();},false);
d.getElementById('cls').addEventListener("click", function(){fadeOut();},false);
d.getElementById('bdy').addEventListener("click", function(){errorSelect();},false);
var wpm = d.getElementById('select');
wpm.addEventListener("click", function(){wpMin()},false);
var inc = 0;
var playing = false;
var txtIn = d.getElementById('txt_in');
var txtOt = d.getElementById('txt_out');
var paused = false;
var allowed = ['-','.',' '];
var aud;
var tmp = (window.AudioContext || window.webkitAudioContext)?true:false;
if (tmp) {
aud = new (window.AudioContext || window.webkitAudioContext)();
}
var incr = 0;
var speed = parseFloat(wpm.options[wpm.selectedIndex].value);
var char = [];
var alphabet = [["A",".-"],["B","-..."],["C","-.-."],["D","-.."],["E","."],["F","..-."],["G","--."],["H","...."],["I",".."],["J",".---"],
["K","-.-"],["L",".-.."],["M","--"],["N","-."],["O","---"],["P",".--."],["Q","--.-"],["R",".-."],["S","..."],["T","-"],["U","..-"],
["V","...-"],["W",".--"],["X","-..-"],["Y","-.--"],["Z","--.."],["1",".----"],["2","..---"],["3","...--"],["4","....-"],["5","....."],
["6","-...."],["7","--..."],["8","---.."],["9","----."],["0","-----"],[".",".-.-.-"],[",","--..--"],["?","..--.."],["'",".----."],["!","-.-.--"],
["/","-..-."],[":","---..."],[";","-.-.-."],["=","-...-"],["-","-....-"],["_","..--.-"],["\"",".-..-."],["#",".--.-."],["(","-.--.-"],[" ",""]];
function errorSelect() {
txtIn.focus();
}
function modalSwap(msg) {
d.getElementById('modalMsg').innerHTML = msg;
}
function msgSelect() {
ftmp = d.getElementById('about');
fadeIn();
}
function fadeIn() {
ftmp.removeEventListener("transitionend", freset);
ftmp.style.display = "block";
del = setTimeout(doFadeIn,100);
}
function doFadeIn() {
clearTimeout(del);
ftmp.style.transition = "opacity 0.5s linear";
ftmp.style.opacity = "1";
}
function fadeOut() {
ftmp.style.transition = "opacity 0.8s linear";
ftmp.style.opacity = "0";
ftmp.addEventListener("transitionend",freset , false);
}
function freset() {
ftmp.style.display = "none";
ftmp.style.transition = "";
ftmp = d.getElementById('mdl');
}
function stp() {
paused = true;
}
function wpMin() {
speed = parseFloat(wpm.options[wpm.selectedIndex].value);
}
function Rst(){
char = [];
inc = 0;
playing = false;
paused = false;
}
function CancelIfPlaying(){
if (window.AudioContext || window.webkitAudioContext) {paused = false;
if (!playing) {
IsReadyToHear();
}
else {
return false;
}
}
else {
modalSwap("<p>Your browser doesn't support Web Audio API</p>");
fadeIn();
return false;
}
}
function IsReadyToHear(x){
if (txtIn.value == "" || /^\s+$/.test(txtIn.value)) {
modalSwap('<p>Nothing to play, enter morse or text first</p>');
fadeIn();
txtIn.value = '';
return false;
}
else if (char.length < 1 && (x != "" || !/^\s+$/.test(txtIn.value)) && txtIn.value.length > 0) {
modalSwap('<p>Click Translate button first . . .</p>');
fadeIn();
return false;
}
else{
playMorse();
}
}
function convertToAndFromMorse(x){
var swap = [];
var outPut = "";
x = x.toUpperCase();
/* Is input empty or all whitespace? */
if (x == '' || /^\s+$/.test(x)) {
modalSwap("<p>Nothing to translate, enter morse or text</p>");
fadeIn();
txtIn.value = '';
return false;
}
/* Remove front & end whitespace */
x = x.replace(/\s+$|^\s*/gi, '');
txtIn.value = x;
txtOt.value = "";
var isMorse = (/(\.|\-)\.|(\.|\-)\-/i.test(x));// Good enough.
if (!isMorse){
for (var i = 0; i < alphabet.length; i++){
swap[i] = [];
for (var j = 0; j < 2; j++){
swap[i][j] = alphabet[i][j].replace(/\-/gi, '\\-');
}
}
}
var swtch1 = (isMorse) ? allowed : swap;
var tst = new RegExp( '[^' + swtch1.join('') + ']', 'g' );
var swtch2 = (isMorse)?' ':'';
x = x.replace( tst, swtch2); //remove unwanted chars.
x = x.split(swtch2);
if (isMorse) {
var tidy = [];
for (var i = 0; i < x.length; i++){
if ((x[i] != '') || x[i+1] == '' && x[i+2] != '') {
tidy.push(x[i]);
}
}
}
var swtch3 = (isMorse) ? tidy : x;
for (var j = 0; j < swtch3.length; j++) {
for (var i = 0; i < alphabet.length; i++){
if (isMorse) {
if (tidy[j] == alphabet[i][1]) {
outPut += alphabet[i][0];
}
}
else {
if (x[j] == alphabet[i][0]) {
outPut += alphabet[i][1] + ((j < x.length-1)?" ":"");
}
}
}
}
if (!isMorse) {
var wordDivide = (d.getElementById('slash').checked)?" / ":" ";
outPut = outPut.replace(/\s{3,}/gi, wordDivide);
}
if (outPut.length < 1) {
alert('Enter valid text or morse...');
txtIn.value = '';
}
else {
txtOt.value = outPut;
}
var justMorse = (!isMorse) ? outPut : tidy;
FormatForSound(justMorse);
}
function FormatForSound(s){
var n = [];
var b = '';
if (typeof s == 'object') {
for (var i = 0; i < s.length; ++i) {
var f = (i == s.length-1)?'':' ';
var t = b += (s[i] + f);
}
}
var c = (typeof s == 'object')? t : s;
c = c.replace(/\//gi, '');
c = c.replace(/\s{1,3}/gi, '4');
c = c.replace(/\./gi, '03');
c = c.replace(/\-/gi, '13');
c = c.split('');
for (var i = 0; i < c.length; i++) {
n.push(c[i]);
}
char = n;
}
function vlm() {
return document.getElementById('volume').value;
}
function playMorse() {
if (paused){
playing = false;
return false;
}
playing = true;
if (incr >= char.length) {
incr = 0;
playing = false;
paused = false;
return false;
}
var c = char[incr];
var freq = 550;
var volume = (c < 2) ? vlm() : 0 ;
var flen = (c == 0 || c == 3) ? speed : speed * 3;
var osc = aud.createOscillator();
osc.type = 'sine';
osc.frequency.value = freq;
var oscGain = aud.createGain();
oscGain.gain.value = volume;
osc.connect(oscGain);
oscGain.connect(aud.destination);
var now = aud.currentTime;
osc.start(now);
/*
Sharp volume fade to stop harsh clicks if wave is stopped
at a point other than the (natural zero crossing point)
*/
oscGain.gain.setValueAtTime(volume, now + (flen*0.8));
oscGain.gain.linearRampToValueAtTime(0.0, now + (flen*0.9999));
osc.stop(now + flen);
osc.onended = function() {
incr++;
playMorse();
}
}
})();
body {
text-align: center;
}
.Mcontainer {
display: inline-block;
position: relative;
width: 382px;
height: 302px;
border: 1px solid #000;
border-radius: 6px;
text-align: center;
font: bold 11px sans-serif;
background-color: rgb(203,243,65);
box-shadow: 0px 4px 2px rgba(0,0,0,0.3);
}
.Mtitle {
-webkit-user-select: none;
-moz-user-select: none;
display: inline-block;
position: absolute;
width: 380px;
height: 20px;
margin: auto;
left: 0; right: 0;
font-size: 16px;
line-height: 20px;
color: #666;
}
.Mtxtareatitle {
-webkit-user-select: none;
-moz-user-select: none;
display: block;
position: absolute;
top: 60px;
left: -36px;
height: 22px;
width: 106px;
font-size: 18px;
line-height: 22px;
text-align: center;
color: #555;
transform: rotate(-90deg);
}
.Mtxtarea {
display: block;
position: absolute;
top: 18px;
margin: auto;
left: 0; right: 0;
height: 98px;
width: 344px;
border: 0.5px solid #000;
border-radius: 6px;
padding-top: 6px;
padding-left: 24px;
resize: none;
background-color: #fffff0;
font: bold 10px courier;
color: #555;
text-transform: uppercase;
overflow: auto;
outline: 0; box-shadow: inset 0px 2px 5px rgba(0,0,0,0.5);
}
.Minfo {
display: none;
position: absolute;
top: -6px; left:-6px;
padding: 6px;
height: auto;
width: 370px;
text-align: left;
border: 0.5px solid #000;
border-radius: 6px;
box-shadow: 0px 4px 2px rgba(0,0,0,0.3);
background-color: rgb(203,243,65);
font: 11px sans-serif;
color: #555;
opacity: 0;
}
.Mbuttonwrap {
display: block;
position: absolute;
top: 245px;
margin: auto;
left: 0; right: 0;
height: 26px;
width: 100%;
}
.Mbuttons {
display: inline-block;
width: 69px;
height: 22px;
border: none;
margin: 0px 3.1px 0px 3.1px;
background-color: transparent;
font: bold 11px sans-serif;
color: #555;
border-radius: 20px;
cursor: pointer;
box-shadow: 0px 2px 2px rgba(0,0,0,0.5);
outline: 0;
}
.Mbuttons:hover {
background-color: rgb(213,253,75);
}
.Mbuttons:active {
position: relative;
top: 1px;
box-shadow: 0px 1px 2px rgba(0,0,0,0.8);
}
.Mchckboxwrap {
display: block;
position: absolute;
top: 274px;
left: 289px;
width: 87px;
height: 21px;
line-height: 22px;
border: 0.5px solid #000;
color: #555;
background: #fff;
-webkit-user-select: none;
-moz-user-select: none;
}
.Mselect {
display: block;
position: absolute;
top: 274px;
left: 6px;
width: 88px;
height: 22px;
border: 0.5px solid #000;
padding-left: 5%;
background: #fff;
font: bold 11px sans-serif;
color: #555;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
outline: 0;
}
::selection {
color: #fff;
background: #555;
}
.Mchckbox {
margin-top: 1px;
vertical-align: middle;
cursor: pointer;
outline: 0;
}
.modal {
display: none;
position: absolute;
margin: auto;
top: 0;right: 0;bottom: 0;left: 0;
background: rgba(0,0,0,0.5);
-webkit-user-select: none;
-moz-user-select: none;
opacity: 0;
text-align: center;
}
.modal > div {
display: inline-block;
position: relative;
width: 250px;
height: 70px;
margin: 10% auto;
padding: 10px;
border: 0.5px solid #000;
border-radius:6px;
background-color: rgb(203,243,65);
font: bold 11px sans-serif;
color: #555;
box-shadow: 4px 4px 2px rgba(0,0,0,0.3);
text-align: center;
}
.sliderWrap {
display: block;
position: absolute;
top: 274px;
margin:auto;padding: 0;
left: 0; right: 0;
width: 184px;
height: 21px;
border: 0.5px solid #000;
background: #fff;
font: bold 11px sans-serif;
color: #555;
line-height: 21px;
text-align: center;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
outline: 0;
}
input[type=range] {
-webkit-appearance: none;
width: 50%;
margin: 0;padding: 0;
vertical-align: middle;
}
input[type=range]:focus {
outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 4px;
cursor: pointer;
background: #666;
}
input[type=range]::-webkit-slider-thumb {
box-shadow: 1px 1px 0.5px rgba(0, 0, 0, 0.5);
border: none;
height: 10px;
width: 20px;
border-radius: 5px;
background: #ffffff;
cursor: pointer;
-webkit-appearance: none;
margin-top: -3px;
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #666;
}
input[type=range]::-moz-range-track {
width: 100%;
height: 4px;
cursor: pointer;
background: #666;
}
input[type=range]::-moz-range-thumb {
box-shadow: 1px 1px 0.5px rgba(0, 0, 0, 0.5);
height: 10px;
width: 20px;
border: none;
border-radius: 5px;
background: #ffffff;
cursor: pointer;
}
input[type=range]::-ms-thumb {
height: 10px;
width: 20px;
border: none;
border-radius: 5px;
background: #ffffff;
box-shadow: 1px 1px 0.5px rgba(0, 0, 0, 0.5);
cursor: pointer;
}
input[type=range]::-ms-track {
width: 100%;
height: 4px;
cursor: pointer;
background: transparent;
border: 5px solid transparent;
color: transparent;
}
input[type=range]::-ms-fill-lower {
background: #666;
}
input[type=range]::-ms-fill-upper {
background: #666;
}
::-ms-tooltip {
display: none;
}
select::-ms-expand {
display: none;
}
It would be best to get Firefox to fix the issue (if indeed it is a Firefox bug with automations). Having said that, you could probably make all the browsers be consistent by using an AudioBufferSource node that has a precomputed click waveform that you want. Just generate a sine wave, ramp it up and down as you want (manually) and play that back at regular intervals.
Not great, but it should be cross-platform.
AFAIK this issue is not specific to Firefox, although looking at your code, I'm unsure why it doesn't happen in other browsers.
The problem is that the moment you schedule a *rampToValueAtTime to an audible source when that source is not currently interpolating between two ramp points, the "clicking" sound occurrs, possibly due to how the underlying implementation will immediately start taking the new ramp point into consideration, even if it's scheduled to happen the future.
The clicking sound will also be heard if you schedule a new ramp point between two points between which interpolation is occurring.
What I came up with as a workaround solution is either using an alternative approach to gradually changing AudioParam values, setTargetAtTime, or setting the value property of the AudioParam to the first ramp point value. Not setValueAtTime, but assigning to the value property itself, before anything audible happens on the given branch.
setTargetAtTime
You'll be needing neither cancelScheduledValues nor setValueAtTime, just two calls to setTargetAtTime, which is just a setValueAtTime with an exponential interpolation with a specified length.
var metronome = {
start: function repeat() {
now = audio.currentTime;
//Play the osc with a super fast attack and release so it sounds like a click
tickVol.gain.setTargetAtTime(1, now, 0.01);
tickVol.gain.setTargetAtTime(0, now + 0.01, 0.01);
//Repeat this function every half second
click = setTimeout(repeat, 500);
}
}
Live demo on JSFiddle
Asking for help. My mapbox.js code is all fine except I'm unable to finish the one last thing: I want the toggle to work in a way so that only one layer/button is active at a time. So that when a new button is pushed the other one goes silent.
Probably a pretty simple thing for someone familiar with js. Note that there both tilelayers, tooltips interaction and legends coupled with the buttons.
If someone could lead me in the right direction I'd be so grateful. Code below:
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Russian Waterways</title>
<script src='http://api.tiles.mapbox.com/mapbox.js/v1.6.4/mapbox.js'></script>
<link href='http://api.tiles.mapbox.com/mapbox.js/v1.6.4/mapbox.css' rel='stylesheet' />
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<style>
#map-ui {
position: absolute;
top: 15px;
left: 10px;
list-style: none;
margin: 0;
padding: 0;
z-index: 100;
}
#map-ui a {
font: normal 13px/18px 'Helvetica Neue', Helvetica, sans-serif;
background: #FFF;
color: #3C4E5A;
display: block;
margin: 0;
padding: 0;
border: 1px solid #BBB;
border-bottom-width: 0;
min-width: 138px;
padding: 10px;
text-decoration: none;
}
#map-ui a:hover {
background: #ECF5FA;
}
#map-ui li:last-child a {
border-bottom-width: 1px;
-webkit-border-radius: 0 0 3px 3px;
border-radius: 0 0 3px 3px;
}
#map-ui li:first-child a {
-webkit-border-radius: 3px 3px 0 0;
border-radius: 3px 3px 0 0;
}
#map-ui a.active {
background: #3887BE;
border-color: #3887BE;
border-top-color: #FFF;
color: #FFF;
}
</style>
<ul id='map-ui'></ul>
<div id='map'></div>
<script type='text/javascript'>
var map = L.mapbox.map('map', 'maxmeles.map-a2km8b40', { zoomControl: false }).setView([56.54, 52.16], 4);
var ui = document.getElementById('map-ui');
addLayer(L.mapbox.tileLayer('maxmeles.Spb-Moscow'), L.mapbox.gridLayer('maxmeles.Spb-Moscow'),'Petersburg-Moscow', 1);
addLayer(L.mapbox.tileLayer('maxmeles.Astrakan-MoscowLegend'), L.mapbox.gridLayer('maxmeles.Astrakan-MoscowLegend'),'Moscow-Astrakhan', 2);
addLayer(L.mapbox.tileLayer('maxmeles.SPB-ASTRAKHANLEGENDRED'), L.mapbox.gridLayer('maxmeles.SPB-ASTRAKHANLEGENDRED'),'Petersburg-Astrakhan', 3);
addLayer(L.mapbox.tileLayer('maxmeles.Perm-MoscowLegend'), L.mapbox.gridLayer('maxmeles.Perm-MoscowLegend'),'Moscow-Perm', 4);
addLayer(L.mapbox.tileLayer('maxmeles.moskvakazan'), L.mapbox.gridLayer('maxmeles.moskvakazan'),'Moscow-Kazan', 5);
addLayer(L.mapbox.tileLayer('maxmeles.DonLegend'), L.mapbox.gridLayer('maxmeles.DonLegend'),'Rostov-Astrakhan', 6);
addLayer(L.mapbox.tileLayer('maxmeles.DneprRed'), L.mapbox.gridLayer('maxmeles.DneprRed'),'Kiev-Odessa', 7);
addLayer(L.mapbox.tileLayer('maxmeles.RedTulceaIstanbul'), L.mapbox.gridLayer('maxmeles.RedTulceaIstanbul'),'Tulcea-Istanbul', 8);
addLayer(L.mapbox.tileLayer('maxmeles.SPB-ROSTOVLEGENDRED'), L.mapbox.gridLayer('maxmeles.SPB-ROSTOVLEGENDRED'),'Rostov-Petersburg', 9);
addLayer(L.mapbox.tileLayer('maxmeles.Rostov-MoscowLegend'), L.mapbox.gridLayer('maxmeles.Rostov-MoscowLegend'),'Rostov-Moscow', 10);
addLayer(L.mapbox.tileLayer('maxmeles.Trans-Siberian'), L.mapbox.gridLayer('maxmeles.Trans-Siberian'),'Trans-Siberian', 11);
function addLayer(layer, gridlayer, name, zIndex) {
layer
.setZIndex(zIndex)
gridlayer
// add the gridControl the active gridlayer
var gridControl = L.mapbox.gridControl(gridlayer, {follow: false}).addTo(map);
// Create a simple layer switcher that toggles layers on and off.
var item = document.createElement('li');
var link = document.createElement('a');
link.href = '#';
link.className = '';
link.innerHTML = name;
link.onclick = function(e) {
e.preventDefault();
e.stopPropagation();
if (map.hasLayer(layer)) {
map.removeLayer(layer);
map.removeLayer(gridlayer);
map.legendControl.removeLegend(layer.getTileJSON().legend);
this.className = '';
} else {
map.addLayer(layer);
map.addLayer(gridlayer);
map.legendControl.addLegend(layer.getTileJSON().legend);
this.className = 'active';
}
};
item.appendChild(link);
ui.appendChild(item);
}
new L.Control.Zoom({ position: 'topright' }).addTo(map);
</script>
</body>
</html>