I am wondering how to change the border of lock:before to solid transparent when the correct password is entered.
My JavaScript is like this, I need a lock before value to change to solid transparent when the IF is triggered
function lock(){
alert("It's locked, you have to guess the password.");
var pass = prompt("");
if (pass == "opensesame") {
alert("Lock opened");
} else {
alert("Wrong password");
}
}
My CSS is like this, lock before needs to be changed to solid transparent by a javascript function.
body {
position: absolute;
color: #00ff80;
background: green;
top: 100px;
left: 200px;
}
#lock {
font-size: 8px;
position: relative;
width: 18em;
height: 13em;
border-radius: 2em;
top: 10em;
box-sizing: border-box;
border: 3.5em solid red;
border-right-width: 7.5em;
border-left-width: 7.5em;
margin: 0 0 6rem 0;
}
#lock:before {
content: "";
box-sizing: border-box;
position: absolute;
border: 2.5em solid red;
width: 14em;
height: 12em;
left: 50%;
margin-left: -7em;
top: -12em;
border-top-left-radius: 7em;
border-top-right-radius: 7em;
}
#lock:after {
content: "";
box-sizing: border-box;
position: absolute;
border: 1em solid red;
width: 5em;
height: 8em;
border-radius: 2.5em;
left: 50%;
top: -1em;
margin-left: -2.5em;
}
#button {
background: transparent;
}
My HTML is like this, all it does is make a button and some text.
<!DOCTYPE html>
<html>
<head>
<title>The lock</title>
</head>
<body>
<h1>Unlock the lock</h1>
<button id=button onclick="lock()"><div id=lock></div></button>
</body>
</html>
Try something like this..
var str = '1em solid transparent';
document.styleSheets[0].addRule('#lock:before','border: "'+str+'";');
the style of a pseudo-element can be changed by using a new class name. For example, add the class name unlocked to the #lock element once the entered password is valid.
You can add the following style for the new class:
#lock.unlocked::before {
border: 1em solid transparent;
/* Your style for unlocked goes here */
}
And your script with the new instruction which add the class .unlocked.
function lock() {
alert("It's locked, you have to guess the password.");
var pass = prompt("");
if (pass == "opensesame") {
alert("Lock opened");
document.getElementById("lock").classList.add("unlocked"); /* NEW */
} else {
alert("Wrong password");
}
}
Add and remove a class to and from the button. Pseudo elements can't be targeting directly from JavaScript so you have to use CSS to change the styling.
// Select the button
const button = document.querySelector('button');
function lock(){
alert("It's locked, you have to guess the password.");
var pass = prompt("");
if (pass == "opensesame") {
// Add the class.
button.classList.add('unlocked');
// If it already has the class..
} else if (button.classList.contains('unlocked')) {
//.. then remove it.
button.classList.remove('unlocked');
}
}
And in your CSS add the class with the styling you need.
#lock.unlocked::before {
border: 2.5em solid transparent;
}
In my project, I have a div, which is set to display: none; by default. When a user clicks an image, I use the onclick function to attempt to display the image. However this method does not work for some reason.
Here is my HTML:
<img onclick="hamburgerFunc()" class="hamburger-btn" width="38px" src="{% static 'hamburgericon.png' %}" alt="Image of hamburger icon">
<div class="box arrow-top"></div>
<script src="{% static 'home.js' %}"></script>
JS:
function hamburgerFunc(objs) {
objs = document.getElementsByClassName("box arrow-top")
objs.style.display = 'inline-block';
}
UPDATED CODE:
.box.arrow-top:after {
content: " ";
position: absolute;
right: 30px;
top: -15px;
border-top: none;
display: none;
border-right: 15px solid transparent;
border-left: 15px solid transparent;
border-bottom: 15px solid white;
}
The box arrow-top is the div I want to display once the image is pressed. Does anybody know why this code is not working? Thank you.
getElementsByClassName returns not a single element but an a live HTMLCollection. And you either need to iterate over all of them and set the style for each of them individually. Or if you only expect on the element you would directly access it objs[0].style.display = …
const objs = document.getElementsByClassName("box arrow-top")
objs[0].style.display = 'inline-block';
or
const objs = document.getElementsByClassName("box arrow-top")
for (const obj of objs) {
obj.style.display = 'inline-block';
}
Alternatively you can use querySelector or querySelectorAll
const obj = document.querySelector(".box.arrow-top")
obj.style.display = 'inline-block';
or if you really have multiple elements:
const objs = document.querySelectorAll(".box.arrow-top")
for (const obj of objs) {
obj.style.display = 'inline-block';
}
UPDATE
:after creates a pseudo element, those elements are not part of the DOM and cannot be selected.
What you want to do is to remove the display: none; from your css rule. And e.g. change the rule to .box.arrow-top.visible:after
.box.arrow-top.visible:after {
content: " ";
position: absolute;
right: 30px;
top: -15px;
border-top: none;
border-right: 15px solid transparent;
border-left: 15px solid transparent;
border-bottom: 15px solid white;
}
And then do:
obj.style.classList.add("visible");
function hamburgerFunc() {
document.querySelector(".box.arrow-top").style.display = 'inline-block'
}
.box.arrow-top{
display:none;
background:orange;
padding:1em;
position:relative;
width: 38px;
}
.box.arrow-top:after {
content: " ";
position: absolute;
border-top: none;
border-right: 15px solid transparent;
border-left: 15px solid transparent;
border-bottom: 15px solid white;
}
<img onclick="hamburgerFunc()" class="hamburger-btn" width="38px" src="https://placekitten.com/200/200" alt="Image of hamburger icon">
<div class="box arrow-top"></div>
Requirement : Star Shape should get added on click of a button .
I have implemented to add a circle by using the ng style in html, now i want to implement the star shape in similar way and for that i need to write a different class "star-six" in css.
But below html code already contains one css class "shapeClass". I have used the below jquery code in my controller method and added the css class "star-six".
The problem i am facing is my new css class"star-six" is replacing the existing class "shapeClass" for all the div's.
can someone please tell how to implment the star shape using the below controller .
HTML:
<div class="shapeClass" ng-repeat="element in viewModel.elementContainer.element"
data-ng-style="shapeCtrl.getShapeStyle($index)">
</div>
Controller:
vm.getShapeStyle = function (index) {
if ($scope.viewModel.elementContainer.element[index].name == "addCircle") {
return {
"width": "100px",
"height": "100px",
"background": "red",
"-moz-border-radius": "50px",
"-webkit-border-radius": "50px",
"border-radius": "50px"
};
}
if ($scope.viewModel.elementContainer.element[index].name == "addStar") {
$('.shapeClass').hasClass('star-six')
if ($('.star-six').hasClass('shapeClass')) {
$('.star-six').removeClass('shapeClass');
}
return {
};
}
CSS:
.shapeClass {
margin: 3px;
border: 1px solid;
position: relative;
background-color: blue;
overflow: hidden;
}
.star-six {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
position: relative;
}
.star-six:after {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-top: 100px solid red;
position: absolute;
content: "";
top: 30px;
left: -50px;
}
I tried to write a program to practice my js skills. There are 3 balls and they are hidden at first. I want the ball_1 shows up first, and after 1 sec, ball_1 disappears. Next, ball_2 shows up and after 1 sec it disappears; same logic goes with ball_3. When I run my code, the first two balls does not hide. I am not sure what is going wrong. The code below are the html, css, and js code that i wrote. Hope someone could help me out. Thank you in advance.
$(document).ready(function() {
var notes = ['ball_1', 'ball_2', 'ball_3'];
for (i = notes.length; i > 0; i--) {
var note = notes.shift();
$('#' + note).addClass('shown');
setTimeout(function() {
$('#' + note).removeClass('shown');
}, 1000);
}
});
#ball_1 {
width: 10px;
height: 10px;
background: #000000;
border: 2px solid #ccc;
border-radius: 50%;
}
#ball_2 {
width: 10px;
height: 10px;
background: #0000FF;
border: 2px solid #ccc;
border-radius: 50%;
}
#ball_3 {
width: 10px;
height: 10px;
background: #7FFF00;
border: 2px solid #ccc;
border-radius: 50%;
}
#ball_1,
#ball_2,
#ball_3 {
width: 10px;
height: 10px;
border: 2px solid #ccc;
border-radius: 50%;
}
.not_shown {
display: none;
}
.shown {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div id="ball">
<div id="ball_1" class="not_shown"></div>
<div id="ball_2" class="not_shown"></div>
<div id="ball_3" class="not_shown"></div>
</div>
In general never modify an array when iterating using a for loop. The shift method will remove the first item from the array thus modifying it's length. Instead do this:
$(document).ready(function() {
var notes = ['ball_1','ball_2','ball_3'];
var i; // You were declaring "i" in global namespace before. Don't do that.
for(i = 0; i < notes.length; i++){
var note = notes[i];
$('#' + note).addClass('shown');
setTimeout(function() {
$('#' + note).removeClass('shown');
},1000);
}
});
Also you will see from my note that you were defining "i" in the global namespace. It is never good to do that so always make sure to define your variables at the beginning of the function block if using "var".
EDIT: missed a semicolon
EDIT2: completely missed that i needed to change up the loop condition.
You are looking for an asnychronous play of events - first ball_1 shows up for 1 sec and after that ball_2 shows up for 1 sec and so forth.
Something like this won't work:
for( var i = 0; i < notes.length; i++){
$('#' + notes[i]).addClass('shown');
setTimeout(function() {
$('#' + notes[i]).removeClass('shown');
},1000);
}
because the timeouts will be registered one after the other in quick succession and all the balls will show up and hide in little over one second.
So you can create a callback and set the timeout for the next ball only after the previous ball has been shown fully for 1 sec - see demo below:
$(document).ready(function() {
var notes = ['ball_1', 'ball_2', 'ball_3'];
hideBall(notes,0);
});
function hideBall(notes,i) {
$('#' + notes[i]).addClass('shown');
hide(function() {
if(++i < notes.length) {
hideBall(notes,i);
}
}, notes[i]);
}
function hide(callback, note) {
setTimeout(function() {
$('#' + note).removeClass('shown');
callback();
}, 1000);
}
#ball_1 {
width: 10px;
height: 10px;
background: #000000;
border: 2px solid #ccc;
border-radius: 50%;
}
#ball_2 {
width: 10px;
height: 10px;
background: #0000FF;
border: 2px solid #ccc;
border-radius: 50%;
}
#ball_3 {
width: 10px;
height: 10px;
background: #7FFF00;
border: 2px solid #ccc;
border-radius: 50%;
}
#ball_1,
#ball_2,
#ball_3 {
width: 10px;
height: 10px;
border: 2px solid #ccc;
border-radius: 50%;
}
.not_shown {
display: none;
}
.shown {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div id="ball">
<div id="ball_1" class="not_shown"></div>
<div id="ball_2" class="not_shown"></div>
<div id="ball_3" class="not_shown"></div>
</div>
Hope this is what you need
$(document).ready(function() {
var notes = ['ball_1','ball_2','ball_3'];
for(i = notes.length; i > 0; i--){
var note = notes[i];
$('#' + note).addClass('shown');
hideBall(note, i)
}
});
function hideBall(note) {
setTimeout(function() {
$('#' + note).removeClass('shown');
},1000 * i);
}
#ball_1{
width: 10px;
height: 10px;
background: #000000;
border: 2px solid #ccc;
border-radius: 50%;
}
#ball_2{
width: 10px;
height: 10px;
background: #0000FF;
border: 2px solid #ccc;
border-radius: 50%;
}
#ball_3{
width: 10px;
height: 10px;
background: #7FFF00;
border: 2px solid #ccc;
border-radius: 50%;
}
#ball_1, #ball_2, #ball_3 {
width: 10px;
height: 10px;
border: 2px solid #ccc;
border-radius: 50%;
}
.not_shown {
display: none;
}
.shown {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id = "ball">
<div id = "ball_1" class = "not_shown"></div>
<div id = "ball_2" class = "not_shown"></div>
<div id = "ball_3" class = "not_shown"></div>
</div>
What you are trying won't work as it will run the for loop all in one go, setting up 3x timeouts.
try something like this
jQuery(document).ready(function($) {
function myBallLoop(){
// increment as needed
if(typeof note == 'undefined') {
var note = 1;
} else if (note == 3){
break; // end loop
} else {
note ++;
}
// show current ball qickly
$('#ball_' + note).show('fast', function(){
// call back after show event
// hide current ball after 1 sec
r = setTimeout(function(){$('#ball_' + note).hide()}, 1000);
// self call function after 2 seconts
t = setTimeout(function(){myBallLoop();, 2000}
});
}
// loop start
myBallLoop();
});
Take advantage of what jquery gives you.
Iterate using $.each is also the same as ES5's forEach. Using delay method to delay a function of adding classes is similar to setTimeout.
$(document).ready(() => {
var notes = ['ball_1','ball_2','ball_3'];
let showBalls = (i, item) => {
$('#' + item).delay(i * 1000).queue(() => {
$('#' + item).addClass('shown');
$('#' + notes[i - 1]).removeClass('shown').clearQueue();
});
}
$.each(notes, (i, item) => {
showBalls(i, item);
});
});
#ball_1{
width: 10px;
height: 10px;
background: #000000;
border: 2px solid #ccc;
border-radius: 50%;
}
#ball_2{
width: 10px;
height: 10px;
background: #0000FF;
border: 2px solid #ccc;
border-radius: 50%;
}
#ball_3{
width: 10px;
height: 10px;
background: #7FFF00;
border: 2px solid #ccc;
border-radius: 50%;
}
#ball_1, #ball_2, #ball_3 {
width: 10px;
height: 10px;
border: 2px solid #ccc;
border-radius: 50%;
}
.not_shown {
display: none;
}
.shown {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id = "ball">
<div id = "ball_1" class = "not_shown"></div>
<div id = "ball_2" class = "not_shown"></div>
<div id = "ball_3" class = "not_shown"></div>
</div>
After clicking a div i want to change it's color and disable the hover. When clicked again i want it to switch to it's previous color and enable the hover again.
So i have this div:
<div class="leftTeam"></div>
Which have this hover:
.leftTeam {
border: 1px solid #d9d9d9;
margin-auto;
float: left;
border-radius: 4px;
background-color: #fff;
width: 200px;
height: 30px;
}
.leftTeam:hover {
border: 1px solid #adadad;
background-color: #e6e6e6;
transition: 1s;
}
This images shows the desired behaviour. Doesn't matter if it will be pure CSS code or javascript included. Thanks!
[]
Try this:
function switchClass(ele){
if(ele.className == "leftTeam"){
ele.className+=" clicked";
}
else{
ele.className = "leftTeam";
}
}
.leftTeam {
border: 1px solid #d9d9d9;
margin-auto;
float: left;
border-radius: 4px;
background-color: #fff;
width: 200px;
height: 30px;
}
.clicked:hover {
border: 1px solid #adadad;
background-color: #e6e6e6;
transition: 1s;
}
<div class="leftTeam" onclick="switchClass(this)">Click to change the class!</div>
Toggle style (hover, color) after click event on element:
function toggleStyle(el){
if(el.className == "initial"){
el.className="clicked";
}
else{
el.className = "initial";
}
}
div { border: 1px solid black; border-collapse: collapse}
.initial{ background-color: #efefef; }
.initial:hover { background-color: #B4FDAB; }
.clicked { background-color: red; }
p.css3{background-color: #efefef;}
p.css3:hover{ background-color: #B4FDAB; }
p.css3:focus{background-color: #B6C2EF; }
p.css3:active{background-color: #B6C2EF; }
<div class="initial" onclick="toggleStyle(this)">Click to change the class!</div>
<div class="initial" onclick="toggleStyle(this)">Click to change the class!</div>
<h3>Testing css 3 focus or active </h3>
<p class="css3">css 3 focus or active seem to be insufficient</p>
Testing a css 3 only solution
It seems that using active or focus are not sufficient, since the hover state is not replaced
p.css3{background-color: #efefef;}
p.css3:hover{ background-color: #B4FDAB; }
p.css3:focus{background-color: #B6C2EF; }
p.css3:active{background-color: #B6C2EF; }
<p class="css3">css 3 focus or active</p>