Styling elements as selected onclick - javascript

How can I turn an element like this:
Element1
Element2
Element3
To be like a selected button, for example, Its normal look be
.select {
border: 1px solid red;
}
But if I clicked on one element of them it turn to be
.select {
background-color: red;
}
But the trick I want to learn here is, How can I make it only one element being able to have the style, Like a radio buttons, Only one button to have the selected style, and if I clicked on another button, the style be removed from the previous one and be at the clicked one, Using JavaScript and CSS only if possible

//get all buttons
var btns = document.getElementsByClassName("select");
function clicker() {
//loop through all buttons
for (y = 0; y < btns.length; ++y) {
//if button is not the current button remove the background class
if (btns[y].classList.contains && btns[y] != this) {
btns[y].classList.remove("colorize")
} //end if
//add background class to current button
this.classList.add("colorize");
}
}
//add an event handler to all buttons
for (x = 0; x < btns.length; ++x) {
btns[x].addEventListener("click", clicker)
}
.select {
border: 1px solid red;
}
.colorize {
background-color: red;
}
Element1
Element2
Element3

You can try this:- First, remove selected class from all the links and then add selected class to that clicked link (using jQuery).
HTML
Element1
Element2
Element3
CSS
.select {
border: 1px solid red;
}
.selected {
background-color: red;
}
jQuery
$(document).ready(function(){
$('.select').click(function(){
$('.select').removeClass('selected');
$(this).addClass('selected');
});
})
Live Example

You can do this quite easily using JavaScript and the addClass() method.
Firstly, don't use the same ID for multiple elements.
HTML:
Element1
Element2
Element3
CSS:
.select {
border: 1px solid red;
}
.clicked {
background-color: red;
}
JavaScript:
$(document).ready(function () {
$(".select").click(function () {
$(".select").addClass("clicked");
});
});
Note this method uses jQuery

Related

Is there a way to change a function by clicking on different divs?

I just started school, and this is my first question ever asked on Stackoverflow, so I apologize up front regarding both formatting and wording of this question.
I want to change the border color of my div to a style I have already declared when I click on it. To show that this has been selected.
I have three divs with id="red/green/pink".
Now, is there a way to change this function to grab information from the div I clicked, so I dont have to write 3 (almost) identical functions?
.chosenBorder{
border: 3px solid gold;
}
<div id="red" class="mainDivs" onclick="newColor('red')">Red?</div>
<div id="green" class="mainDivs" onclick="newColor('green')">Green?</div>
<div id="pink" class="mainDivs" onclick="newColor('pink')">Pink?</div>
<div class="mainDivs" onclick="whatNow(changeBig)">Choose!</div>
<script>
let changeBig = "";
let chosenDiv = document.getElementById("body");
function newColor(thisColor) {
changeBig = thisColor;
// something that make this part dynamic.classList.toggle("chosenBorder");
}
function whatNow(changeBig) {
document.body.style.backgroundColor = changeBig;
}
</script>
Since you already have an id contains the name of color; get the advantage of it: and keep track of the selected color in your variable changeBig.
let changeBig = "";
function newColor(div) {
// initial all divs to black
initialDivs();
div.style.borderColor = div.id;
changeBig = div.id;
}
function initialDivs() {
[...document.querySelectorAll('.mainDivs')].forEach(div => {
div.style.borderColor = 'black'
});
}
function whatNow() {
document.body.style.backgroundColor = changeBig;
}
.mainDivs {
padding: 10px;
margin: 10px;
border: 3px solid;
outline: 3px solid;
width: fit-content;
cursor: pointer;
}
<div id="red" class="mainDivs" onclick="newColor(this)">Red?</div>
<div id="green" class="mainDivs" onclick="newColor(this)">Green?</div>
<div id="pink" class="mainDivs" onclick="newColor(this)">Pink?</div>
<div class="mainDivs" onclick="whatNow()">Choose!</div>
There are a few (modern) modifications you can make to simplify things.
Remove the inline JS.
Use CSS to store the style information.
Use data attributes to store the colour rather than the id.
Wrap the div elements (I've called them boxes here) in a containing element. This way you can use a technique called event delegation. By attaching one listener to the container you can have that listen to events from its child elements as they "bubble up" the DOM. When an event is caught it calls a function that 1) checks that the event is from a box element 2) retrieves the color from the element's dataset, and adds it to its classList along with an active class.
// Cache the elements
const boxes = document.querySelectorAll('.box');
const container = document.querySelector('.boxes');
const button = document.querySelector('button');
// Add a listener to the container which calls
// `handleClick` when it catches an event fired from one of
// its child elements, and a listener to the button to change
// the background
container.addEventListener('click', handleClick);
button.addEventListener('click', handleBackground);
function handleClick(e) {
// Check to see if the child element that fired
// the event has a box class
if (e.target.matches('.box')) {
// Remove the color and active classes from
// all the boxes
boxes.forEach(box => box.className = 'box');
// Destructure the color from its dataset, and
// add that to the class list of the clicked box
// along with an active class
const { color } = e.target.dataset;
e.target.classList.add(color, 'active');
}
}
function handleBackground() {
// Get the active box, get its color, and then assign
// that color to the body background
const active = document.querySelector('.box.active');
const { color } = active.dataset;
document.body.style.backgroundColor = color;
}
.boxes { display: flex; flex-direction: row; background-color: white; padding: 0.4em;}
.box { display: flex; justify-content: center; align-items: center; width: 50px; height: 50px; border: 2px solid #dfdfdf; margin-right: 0.25em; }
button { margin-top: 1em; }
button:hover { cursor: pointer; }
.box:hover { cursor: pointer; }
.red { border: 2px solid red; }
.green { border: 2px solid green; }
.pink { border: 2px solid pink; }
<div class="boxes">
<div class="box" data-color="red">Red</div>
<div class="box" data-color="green">Green</div>
<div class="box" data-color="pink">Pink</div>
</div>
<button>Change background</button>

How to get the style of an element with psuedo-class (:focus for example)

I would like to get certain css property (for example the border-color) of any elements, but when its on a 'non-base' states, such as focus and hover. For example:
<style>
.input {
border: 1px solid red;
}
.input:focus {
outline: none;
border-color: green;
}
</style>
<input type="text" class="input">
<script>
let input = document.querySelector('.input');
const inputBorderColor = window.getComputedStyle(input).getPropertyValue('border-color');
console.log(inputBorderColor); // rgb(255, 0, 0)
</script>
Using getComputedStyle, I can grab the border color of the input for the 'base' state, but how do I get the border color for when the input is on focus (in this case border-color: green)?
const input = document.querySelector('.input');
input.addEventListener("focus", function() {
console.log(window.getComputedStyle(input).color)
});
Codepen: https://codepen.io/disaladamsas/pen/KKvNZYz?editors=1111

How do I run queryCommandState for a certain div (and not the whole page)?

How do I detect if an item is bold, ONLY within my contenteditable div, and not when the user clicks anywhere else on the entire page?
Here's my JSFiddle with the code.
I'm trying to run document.queryCommandState("bold") but only for my contenteditable="true" div.
I've googled for a while and can't find anything. I've tried replacing/adding my div selector $(".text-editor") to the word document in a few different ways, which doesn't work. I feel like I'm missing something obvious. Thanks!
HTML:
<div contenteditable="true" class="text-editor">Content <b>editable</b>. Type here...</div>
<div class="normal-div">Content <b>not</b> editable.</div>
Click on the bold (and not bold) text in the two boxes. Result:
<div class="is-bold">The text your cursor's on is BOLD.</div>
<div class="is-not-bold">The text your cursor's on is NOT BOLD.</div>
<br>^^ I want this green result to only change when you're clicking inside the editable box.
CSS:
.text-editor {
border: 2px solid red;
margin-bottom: 10px;
}
.normal-div {
border: 2px solid blue;
margin-bottom: 10px;
}
.is-bold {
display: none;
color: green;
}
.is-not-bold {
display: none;
color: green;
}
.active {
display: block;
}
jQuery:
setInterval(function () {
var isItBold = document.queryCommandState("bold");
if (isItBold == true) {
$(".is-bold").addClass("active");
$(".is-not-bold").removeClass("active");
}
else {
$(".is-bold").removeClass("active");
$(".is-not-bold").addClass("active");
}
}, 100)
You can check if contenteditable is being focused first, before doing any of that.
var editable = $("[contenteditable]")
setInterval(function () {
if (!editable.is(":focus")) return
var isItBold = document.queryCommandState("bold");
if (isItBold == true) {
$(".is-bold").addClass("active");
$(".is-not-bold").removeClass("active");
}
else {
$(".is-bold").removeClass("active");
$(".is-not-bold").addClass("active");
}
}, 100)
Also setInterval is not necessary here. You can bind on click event for example.

Changing div text and CSS when clicking on a div, and reversing the change when you click again

I have a div named #increase-text-weight which says "INCREASE TEXT WEIGHT".
Whenever you click on it, the contents of another div named #post-content should get font-weight: 500 and the text of #increase-text-weight should be changed to "DECREASE TEXT WEIGHT".
When the div says "DECREASE TEXT WEIGHT" and you click on it,
#post-content
should get
font-weight: 300
and the text of
#increase-text-weight
should be changed to "INCREASE TEXT WEIGHT".
How can I do this?
EDIT:
I had tried doing it by getElementById but it didn't work.
Since you are learning, this is a short way to do this with two clases.
First of all, the id selector $('#test') gets the node element
Then attach a click event listener of to the reference.
After, the selector $(this), makes a reference to selector used in the event attached function, in this case we can say $(this) == $("#test").
After the dot, jQuery .toggleClass() method adds or remove a class from the element, also, if you pass a second true or false parameter, the method will add or remove the given class respectively.
So if you chain this two toggleClass() will add the class if it is not there or will remove it if it exist
$("#test").click(function(){ // also can be .on('click',function(){ ... })
$(this).toggleClass("decreased")
.toggleClass("increased");
});
.decreased {
font-weight: 100;
color: red;
cursor: pointer;
}
.increased {
font-weight: 300;
color: green;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test" class="decreased">Increase my font weight!</div>
A quick way to do this could be to use and if and else statement.
$('#increase-text-weight').on('click', function() {
if ($(this).text() === 'INCREASE TEXT WEIGHT') {
$('#post-content').addClass('highlight');
$(this).text('DECREASE TEXT WEIGHT');
} else {
$(this).text('INCREASE TEXT WEIGHT');
$('#post-content').removeClass('highlight');
}
});
$('#increase-text-weight').on('click', function() {
if ($(this).text() === 'INCREASE TEXT WEIGHT') {
$('#post-content').addClass('highlight');
$(this).text('DECREASE TEXT WEIGHT');
} else {
$(this).text('INCREASE TEXT WEIGHT');
$('#post-content').removeClass('highlight');
}
});
div {
width: 100%;
height: 100px;
text-align: center;
border: 1px solid;
margin: 0 0 25px 0;
cursor: pointer;
}
.highlight {
font-weight: 900;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='increase-text-weight'>INCREASE TEXT WEIGHT</div>
<div id='post-content'>Text text and text</div>
You can simply do this using an onClick event on the div you want to be changed. Each time it is clicked we check which class is associated with that <div>, and then do the required modifications to that <div> based on the class, like updating the text content inside the div with .text(), and then switching out the classes like so:
var myDiv = $("#test");
myDiv.click(function() {
if (myDiv.hasClass("decreased")) {
myDiv.removeClass("decreased")
.addClass("increased")
.text("Decrease my font weight!")
} else {
myDiv.removeClass("increased")
.addClass("decreased")
.text("Increase my font weight!")
}
});
.decreased {
font-weight: 100;
color: red;
cursor: pointer;
}
.increased {
font-weight: 300;
color: green;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test" class="decreased">Increase my font weight!</div>
Although you can easily do this with pure JavaScript like so:
var myDiv = document.getElementById("test");
myDiv.addEventListener("click", function() {
if (myDiv.className === "decreased") {
myDiv.classList.remove("decreased");
myDiv.className = "increased";
myDiv.textContent = "Decrease my font weight!";
} else {
myDiv.classList.remove("increased");
myDiv.className = "decreased";
myDiv.textContent = "Increase my font weight!";
}
});

<li> element toggle between different background colors

I want to change the background color of the button based upon the class. Why it is not going back after second click?
var $begin1 = $(".begin1").click(function(e) {
e.preventDefault();
var buttonState = $(this).attr("class");
if (buttonState != 'pressed') {
$begin1.removeClass('pressed');
$(this).addClass('pressed');
} else {
$(this).removeClass('pressed');
$(this).addClass('unpressed');
}
});
li {
list-style-type: none;
}
.begin1.unpressed,
.begin2.unpressed {
background-color: white;
color: black;
border: 2px solid #4CAF50;
margin: 0 0 10px 0;
}
li.begin1.pressed,
li.begin2.pressed {
background: #4CAF50;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<li class="begin1 unpressed">
<h2>Button</h2>
</li>
https://jsfiddle.net/nrebaL00/
You can simplify your code greatly. Apply the default styling from the beginning and you don't need an .unpressed class.
The issue with using .attr( 'class' ) is that it will retrieve all the classes applied to the element as a string. Performing a check like if ( 'a' === $el.attr( 'class' ) ) won't work where $el is <li class="a b c"> as $el.attr( 'class' ) would return 'a b c' and not 'a'. Which is why your check was failing after the first click. This kind of check would be good for .hasClass().
e.prevendDefault() is not required for an <li>, so remove that.
Note: the selector I used for jQuery is pretty generic. You may need to increase it's specificity if there are other <li> on the page that don't require the functionality. Something along the lines of adding a class to the <ul> and using that as the part of the jQuery selector. i.e. <ul class="clicky-mcclickens"> and $( '.clicky-mcclickens li' ).
$('li').on('click', function(e) {
$(this).toggleClass('pressed');
});
li {
list-style-type: none;
background-color: white;
color: black;
border: 2px solid #4CAF50;
margin: 0 0 10px 0;
}
.pressed {
background: #4CAF50;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
<h2>Button 1</h2>
</li>
<li>
<h2>Button 2</h2>
</li>
</ul>
Sometimes you need more control than simply adding/removing a class when an element is clicked. In those instances you can use .hasClass() to check if the element has the class in question and apply the appropriate action.
Your code is much more complex than it needs to be; you can just call toggleClass() like this:
var $begin1 = $(".begin1").click(function() {
$(this).toggleClass('pressed unpressed');
});
Updated fiddle
Note that e.preventDefault() is redundant for an li element as it has no default behaviour to prevent.
I would use toggleClass instead of adding and removing manually. This seems to work:
var $begin1 = $(".begin1").click( function(e) {
$begin1.toggleClass('pressed');
});
Instead of check the complete string of the class of the element you can check if the element has specific class using hasClass:
var $begin1 = $(".begin1").click( function(e) {
e.preventDefault();
if(!$(this).hasClass('pressed')){
$begin1.removeClass('unpressed');
$(this).addClass('pressed');
} else{
$(this).removeClass('pressed');
$(this).addClass('unpressed');
}
});
li{
list-style-type: none;
}
.begin1.unpressed,
.begin2.unpressed {
background-color: white;
color: black;
border: 2px solid #4CAF50;
margin: 0 0 10px 0;
}
li.begin1.pressed,
li.begin2.pressed{
background: #4CAF50;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<li class="begin1 unpressed"><h2>Button</h2></li>
The problem with using the attr('class') is that you can't know what exactly will be the final string.
Just replace your js with:
$(document).ready(function() {
$(".begin1").click(function(){
$(this).toggleClass("pressed");
});
});

Categories

Resources