both buttons trigger one script - javascript

I have a button that triggers a script on a webpage. One instance works. When I try to add a second button/script, both buttons trigger the second script only. I know (think?) it's because the var I'm defining for the buttons are not unique to their individual scripts, but every way I attempt I break the whole thing.
button {
display: block;
cursor: pointer;
margin-left: 10px;}
button:after {
content: " (off)";
}
button.on:before {
content: "✓ ";
}
button.on:after {
content:" ";
}
.frac span {
-webkit-font-feature-settings: "frac" 1;
font-feature-settings: "frac" 1;
}
.onum span {
-webkit-font-feature-settings: "onum" 1;
font-feature-settings: "onum" 1;
}
Html:
<button name="frac" id="frac">Fractions</button>
<button name="onum" id="onum">Oldstyle Numbers</button>
This text is supposed change OT features when the buttons are pressed.
JS:
<script> var btn = document.getElementById("frac"),
body = document.getElementById("textA"),
activeClass = "frac";
btn.addEventListener("click", function(e){
e.preventDefault();
body.classList.toggle(activeClass);
btn.classList.toggle('on');
}); </script>
<!-- onum -->
<script> var btn = document.getElementById("onum"),
body = document.getElementById("textA"),
activeClass = "onum";
btn.addEventListener("click", function(f){
f.preventDefault();
body.classList.toggle(activeClass);
btn.classList.toggle('on');
}); </script>
The variance between the scripts/buttons are some of the changes from different things I've done, but I've gone mostly back to the beginning so it's simpler.

In javascript, every variable that you declare is inherently available across the entire page. So, putting them in separate tags will have no effect.
So essentially, your second variable btn is actually overwriting the first one. Rename the second variable to say, btn2.
Or, as an alternative, change the line
btn.classList.toggle('on')
to
this.classList.toggle('on')
this within the click handler will always point to the current button being clicked.

You can do it in fewer lines of code
// you create the array of buttons
let butons = Array.from(document.querySelectorAll("button")),
// you define the _body
_body = document.getElementById("textA")
// for every button in the buttons array (map is an iterator)
butons.map((btn) =>{
//you define the activeClass to be the name attribute of the button
let activeClass = btn.getAttribute("name");
// everytime you click the button
btn.addEventListener("click", (e) =>{
/*this was in your code. I don't know why you need it
e.preventDefault();*/
//you toggle the activeClass & the on class
_body.classList.toggle(activeClass);
btn.classList.toggle("on");
})
})
button {
display: block;
cursor: pointer;
margin-left: 10px;
}
button:after {
content: " (off)";
}
button.on:before {
content: "✓ ";
}
button.on:after {
content: " ";
}
/* I'm using color to visualize the change */
.frac span {
color: red;
}
.onum span {
color: green;
}
<button name="frac" id="frac">Fractions</button>
<button name="onum" id="onum">Oldstyle Numbers</button>
<p id="textA">The variance between the <span>scripts/buttons</span> are some of the changes from different things I've done, but I've gone mostly back to the beginning so it's simpler.</p>

Related

Is it possible to make these functions into one function?

I'm trying to get this program to add a special character when the assigned button for the character is pressed. The problem is, I'm going to have a lot of functions. Can I somehow just make one function that I can use for all of the buttons?
//These are buttons
var aa = document.querySelector('#aa')
var oo = document.querySelector('#oo')
var uu = document.querySelector('#uu')
var khii = document.querySelector('#khii')
//This is the text box
var textBox = document.querySelector('#typeIn')
//Functions to add a character into the text box
function addAa() {
textBox.innerHTML += "ā";
}
function addOo() {
textBox.innerHTML += "ō";
}
function addUu() {
textBox.innerHTML += "ū";
}
function addKhii() {
textBox.innerHTML += "χ";
}
//Telling the buttons to call on the functions when clicked
aa.onclick = addAa
oo.onclick = addOo
uu.onclick = addUu
khii.onclick = addKhii
Additionally: why does this not work?
var aa = document.querySelector('#aa')
var textBox = document.querySelector('#text')
function addLetter(a) {
textBox.innerHTML += a
}
aa.onclick = addLetter("ā")
This just adds the character once into the text box. Clicking on the button then does nothing. Why does it do that?
Yes you can do it with only one function. Pass the character as parameter to the function. Like that:
version with addEventListener (prefered)
const btns = document.querySelectorAll('button');
const textBox = document.querySelector('#typeIn');
btns.forEach(b => {
b.addEventListener('click', e => {
textBox.innerHTML += e.target.getAttribute('data-char')
})
});
#typeIn {
margin:10px;
padding: 10px;
color: white;
min-height:40px;
background: gray;
}
<button data-char="aa">aa</button>
<button data-char="X">X</button>
<button data-char="ō">ō</button>
<button data-char="ū">ū</button>
<div id="typeIn"></div>
Generally try to avoid onclick events and use eventListener instead.
Version onclick Event
const textBox = document.querySelector('#typeIn');
function add(what) {
textBox.innerHTML += what;
}
#typeIn {
margin:10px;
padding: 10px;
color: white;
min-height:40px;
background: gray;
}
<button onclick="add('aa')">aa</button>
<button onclick="add('X')">X</button>
<button onclick="add('ō')">ō</button>
<button onclick="add('ū')">ū</button>
<div id="typeIn"></div>
You could do something like this:
Add (for example) data-value attributes to each of your buttons
<button data-value="A">A</button>
<button data-value="B">B</button>
<button data-value="C">C</button>
Grab all these buttons, and add "click" event listeners to each, like so:
document
.querySelectorAll('button') // Use appropriate class name here
.forEach(button =>
button
.addEventListener("click", (e) =>
console.log(e.target.dataset.value) // Do whatever you want here
)
)
Modify the listener function's body as per your needs
Here's a link to a JsFiddle that I've created for demo.

Contenteditable paragraphs in html

I am creating a contenteditable paragraph in html. I have a button which on clicking will make the text bold. The first time it is clicked the text should change to bold,and the next time it is clicked ,the text should be normal(not bolder).This is similar to the Stack overflow question editor.html code:
<button type="button" id="bold" onclick="bold()">B</button>
<div id="content">
<p id="hey" contenteditable="true">Hi how are you</p>
</div>
JS:
let boldClick=0;
let p=document.getElementById('hey');
function bold(){
if(boldClick%2==0){
p.innerHTML=p.innerHTML+' <span contenteditable="true">'+' boldtext'+'</span>';
}
else{
let pNew=document.createElement('p');
pNew.setAttribute("contenteditable","true");
document.getElementById('content').appendChild(pNew);
}
boldClick++;
}
CSS:
#bold{
font-weight: bold;
}
span{
font-weight: bold;
background-color: grey;
}
p{
display: inline;
}
I can make the text bolder by clicking the button.Bolder texts must be inside the span element and non-bolder texts must be outside span but inside
p element.How do I solve it?
approach 1:
let boldClick=0;
let p=document.getElementById('hey');
p.innerHTML=p.innerHTML+' <span contenteditable="true" id="bold">'+' boldtext'+'</span>';
const boldTag = document.getElementById('bold');
function bold(){
if(boldClick%2==0){
boldTag.style.fontWeight="";
}
else{
boldTag.style.fontWeigh="bold";
}
boldClick++;
}
approach 2:
let boldClick=0;
let p=document.getElementById('hey');
p.innerHTML=p.innerHTML+' <span contenteditable="true" id="bold">'+' boldtext'+'</span>';
const boldTag = document.getElementById('bold');
function bold(){
if(boldClick%2==0){
boldTag.id="";
}
else{
boldTag.id="bold";
}
boldClick++;
}
these approaches are not optimized , but hope you get the concept .
the shortest way. Create a class named Bold. Add the properties you want to this class. Select elements with Javascript and assign a function to have this class.
In general , creating a class with css and using javascript is the simplest way to solve problems, which element of this class should be added when.
let clicked = false;
function bold() {
let paragraph = document.getElementById("paragraph");
let span = document.getElementById("span");
if (clicked) {
span.contentEditable = false;
span.classList.remove("bold");
clicked = false;
} else {
span.contentEditable = true;
span.classList.add("bold");
clicked = true;
}
}
p {
display: inline;
}
.bold {
font-weight: bold;
}
<button type="button" id="bold-button" onclick="bold()">B</button>
<div id="content">
<p id="paragraph">Hi how are you
<span id="span">how are you</span>
</p>
</div>
First off, please tag your post with java script instead of java, similar name, different language. Here is the code you should use:
let isBold = false;
let p=document.getElementById('hey');
function bold(){
if(isBold == false){
p.style.fontWeight = "bold";
isBold = true;
}
else{
p.style.fontWeight = "normal";
isBold = false;
}
}
It changes the font weight (if it is bold or not) instead of the complex code you had. If you are just turning something on and off (bold or not) then use a boolean value (true + false) true will make it bold, false will make it normal. For HTML graphics, you should use CSS language. You can change the variable's CSS values by saying style then the thing you want to change.

creat button for change background color

I want to create two buttons in HTML called 'green' and 'red'. When clicking on them, the style "background-color: {COLOR-SELECTED}" should be changed dynamically.
var verde = document.getElementById('verde')
var vermelho = document.getElementById('vermelho')
var body = document.querySelector('body')
function verde() {
body.className = "verde";
}
function vermelho() {
body.className = "vermelho";
}
.verde {
background-color: darkgreen;
}
.vermelho {
background-color: darkred;
}
<body>
<button class="verde" onclick="verde ()" id="verde"></button>
<button class="vermelho" onclick="vermelho ()" id="vermelho"></button>
</body>
You should use the classList API to add or remove a class to body.
More info HERE
function verde () {
body.classList.remove('vermelho');
body.classList.add('verde');
}
Here are a few changes I've made:
Remove the space between the function name and the () in the HTML.
Removed the first two lines of the javascript – you never use these variables.
Changed querySelector to getElementsByTagName, which creates a list of elements, so that you can select the first one using [0]
The snippet below should work as expected:
var body = document.getElementsByTagName('body')[0];
function verde() {
body.className = "verde";
}
function vermelho() {
body.className = "vermelho";
}
.verde {
background-color: darkgreen;
}
.vermelho {
background-color: darkred;
}
<body class="none">
<button class="verde" onclick="verde()" id="verde"></button>
<button class="vermelho" onclick="vermelho()" id="vermelho"></button>
</body>

How to select a new added element and edit it?

I have an <a> element:
<a id='addNewElementk' onclick='//Some Js Code' class='continueButton'>Click To Add</a>
When this anchor is clicked , A new element added:
New Added Element
And the first anchor which was clicked , Is removed.
I want to select that new element.
I tried:
window.onload = function(){
var newElem = document.getElementsByClassName('continueButton')[1];
alert(newElem.innerHTML);
}
I'm using ('continueButton')[1] , As there is another input with the same class before that anchor.
But for sure I get Click To Add from the first one , As that's was found when the page is loaded.
So how can I select that new element?
You're attempting to select the element before it exists in the DOM.
You instead need to run that code within the click event handler of the first <a>, like this:
window.onload = function() {
document.querySelector('#addNewElementk').addEventListener('click', function(e) {
e.preventDefault();
var a = document.createElement('a');
a.textContent = 'New Added Element';
a.href = '#';
a.classList.add('continueButton');
a.addEventListener('click', function(e) {
console.log(a.innerHTML);
});
this.parentNode.insertBefore(a, this);
this.remove();
});
}
<a id='addNewElementk' href="#" class='continueButton'>Click To Add</a>
Note the use of addEventListener() over the outdated on* event attributes which should be avoided.
You are attempting to select on an element that doesn't exist in the DOM. Dynamically added elements can be accessed in a couple of ways, above someone has an answer that adds an event listener to the created element which is a solid solution. The other most common way would be to use event delegation (if you are familiar with jQuery that would be $(parentElement).on('action', 'elementWeWantToWatch', function)) in Vanilla js the pattern is effectively the same, find or make a container element for your dynamic html, then add a listener to that container. Inside the listener you will want to ensure the target matches whatever your dynamic selection would be and execute when you find a match.
In this Example
The event listener is initiated on page load to watch the container element. The listener watches for clicks on elements with the continueButton class and when it finds one it removes the clicked element and adds a new element (the counter is to demonstrate that new content is being displayed :D)
(function() {
let i = 1;
const makeButton = () => {
const a = document.createElement('a');
a.classList.add('continueButton');
a.href = '#';
a.textContent = `Button ${i}`
i++;
return a;
}
const init = () => {
const container = document.querySelector('.test');
container.addEventListener('click', e => {
if (e.target.classList.contains('continueButton')) {
let button = makeButton();
container.appendChild(button);
container.removeChild(e.target);
return;
}
});
};
if (document.readyState == 'loading') {
window.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})()
.test {
width: 100%;
display: block;
text-align: center;
}
.continueButton {
display: block;
color: white;
background-color: green;
border-radius 2px;
padding: 15px 30px;
line-height: 2;
margin: 50px auto;
width: 200px;
text-decoration: none
}
<section class="test">
<a id='addNewElementk' class='continueButton'>Click To Add</a>
</section>

Getting value from followup fieldset when prior one is clicked

I am able to dynamically create fieldsets on button click. Let say first time I click button it creates Definition 1 then Definition 2 then Definition 3 etc.
Each fieldset has X mark to remove the dynamically created fieldset if one was created by accident.
What I am trying to do is for example Definition 2 fieldset was deleted then Definition 3 one should say Definition 2.
What I need to know is when I click X mark in one fieldset, grab the value of the legend from the next fieldset and change it to the value of the one deleted.
Here is what my dynamic call looks like:
if($(".addDef").length > 0){
i++;
}else{
i = 2;
}
$(".definitionBlock").append("<fieldset><legend class='addDef'>Definition #"+ i +"</legend><div class='removeDef'><span>✖</span></div>
</fieldset>");
Thanks!
You can use .text(function(index, text){}) to replace digit portion of .textContent with index of element within collection
var n = 2;
$(".addDefBtn").on("click", function() {
if (!$(".addDef").length) {
n = 2;
}
$(".mvnDefinitionBlock").append("<fieldset class='addDef'><legend class='addDefTitle'>Definition #" + n++ + "</legend><div class='removeDef'><span>✖click</span></div></fieldset>");
});
$('body').on('click', '.removeDef', function() {
$(this).closest('fieldset').remove();
n = 2;
$(".addDef legend").text(function(index, text) {
return text.replace(/\d+/, n++);
});
});
.removeDef {
float: right;
margin-top: -20px;
font-size: 13px;
color: red;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
Add New Definition
<div class="mvnDefinitionBlock"></div>

Categories

Resources