I'm looking to have the mouse hover function active only when my button is On and when my button is off have it not activate the hover function. I can get the hover to work but not when its on
function changeBoxColor() {
let myBox = document.getElementById("myBox");
if (myBox.style.backgroundColor === "green") {
myBox.style.backgroundColor = "red";
} else {
myBox.style.backgroundColor = "green";
}
}
document.getElementById("myBox").addEventListener("mouseover", changeBoxColor);
document.getElementById("myBox").addEventListener("mouseleave", changeBoxColor);
function changeToggleButton() {
let toggleButton = document.getElementById("toggleButton");
if (toggleButton.value === "ON") {
toggleButton.value = "OFF";
} else {
toggleButton.value = "ON";
}
}
document.getElementById("toggleButton").addEventListener("click", changeToggleButton);
<input id="toggleButton" type="button" value="ON">
<div style="height: 400px; width: 400px; background-color: red;" id="myBox"></div>
Like j08691 commented above, you just aren't binding the change in EventListeners on load, or change of the toggle button. Here is updated code that does exactly this:
function changeToggleButton() {
let toggleButton = document.getElementById("toggleButton");
if (toggleButton.value === "ON") {
toggleButton.value = "OFF";
document.getElementById("myBox").removeEventListener("mouseover", changeBoxColor);
document.getElementById("myBox").removeEventListener("mouseleave", changeBoxColor);
} else {
toggleButton.value = "ON";
document.getElementById("myBox").addEventListener("mouseover", changeBoxColor);
document.getElementById("myBox").addEventListener("mouseleave", changeBoxColor);
}
}
document.getElementById("myBox").addEventListener("mouseover", changeBoxColor);
document.getElementById("myBox").addEventListener("mouseleave", changeBoxColor);
document.getElementById("toggleButton").addEventListener("click", changeToggleButton);
Now, this code assumes that the toggleButton starts as on, which is why we automatically addEventListener when the script is loaded. The other change is that when you check the toggleButton.value, we add/remove the EventListener from the element.
Simple add the events when the button value is 'ON', otherwise remove the events
function changeBoxColor() {
let myBox = document.getElementById("myBox");
if (myBox.style.backgroundColor === "green") {
myBox.style.backgroundColor = "red";
} else {
myBox.style.backgroundColor = "green";
}
}
document.getElementById("myBox").addEventListener("mouseover", changeBoxColor);
document.getElementById("myBox").addEventListener("mouseleave", changeBoxColor);
var eventOver = ["mouseover",changeBoxColor];
var eventLeave = ["mouseleave",changeBoxColor];
function changeToggleButton() {
let toggleButton = document.getElementById("toggleButton");
if (toggleButton.value === "ON") {
toggleButton.value = "OFF";
document.getElementById("myBox").removeEventListener(...eventOver);
document.getElementById("myBox").removeEventListener(...eventLeave);
} else {
toggleButton.value = "ON";
document.getElementById("myBox").addEventListener(...eventOver);
document.getElementById("myBox").addEventListener(...eventLeave);
}
}
document.getElementById("toggleButton").addEventListener("click", changeToggleButton);
<input id="toggleButton" type="button" value="ON">
<div style="height: 400px; width: 400px; background-color: red;" id="myBox"></div>
FWIW, this can be done using HTML and CSS only, if you accept that your 'toggle button' can be a checkbox (a checkbox basically is a toggle button).
You can then use an attribute selector to find the checkbox, or simply select it using its class or id. Then, using + div and + div:hover, you can style the div after it.
The trick is in this selector:
input[type=checkbox]:checked + div:hover
Which basically says, target a hovered div, that is right after a checked input of type checkbox.
input[type=checkbox] + div {
height: 400px;
width: 400px;
background-color: red;
}
input[type=checkbox]:checked + div:hover {
background-color:green;
}
<input id="toggleButton" type="checkbox" value="">
<div id="myBox"></div>
Of course, you can style the checkbox to look more like the button you want, or hide it completely and use a <label for="toggleButton"></label>, which can take the place of the checkbox visually, and be styled however you like.
Or, you can even use a normal button, and just change the class of the button on click. You can then still use CSS to style the div.
This could be done using <input, but you'd have to set the value through JavaScript. For the sake of example, I used <button, which has content rather than a value, and so you can toggle the caption as well using CSS, if you would like that.
(function(element) {
element.addEventListener('click', function() {
if (element.classList.contains('on'))
element.classList.remove('on');
else
element.classList.add('on');
});
})(document.getElementById('toggleButton'));
button + div {
height: 400px;
width: 400px;
background-color: red;
}
button.on + div:hover {
background-color:green;
}
/* If you like, you can even set the button text in CSS, but
beware of accessibility issues. */
button:after {
content: "off";
}
button.on:after {
content: "on";
}
<button id="toggleButton" type="button"></button>
<div id="myBox"></div>
Related
I have a page on my site which has 3 separate 'hidden' divs. Each with it's own 'show/hide' button.
Currently... each div and button set functions independently.
Therefore... if all divs are shown (open) at the same time, they stack according to their respective order.
Instead of that, I would rather restrict the function a bit, so that only div can be shown (open) at a time.
Example: If Div 1 is shown, and the user then clicks the Div 2 (or Dive 3) button, Div 1 (or which ever div is open at the time, will close.
I am not sure how to adjust my code to make that all work together. I have tried a few ideas, but they were all duds. So I posted a generic 'independent' version below.
function show_Div_1() {
var div1 = document.getElementById("Div_1");
if (div1.style.display === "none") {
div1.style.display = "block";
} else {
div1.style.display = "none";
}
}
function show_Div_2() {
var div2 = document.getElementById("Div_2");
if (div2.style.display === "none") {
div2.style.display = "block";
} else {
div2.style.display = "none";
}
}
function show_Div_3() {
var div3 = document.getElementById("Div_3");
if (div3.style.display === "none") {
div3.style.display = "block";
} else {
div3.style.display = "none";
}
}
.div {
width: 270px;
height: 30px;
padding-left: 10px;
}
<button type="button" onclick="show_Div_1()">Div 1 - Red</button>
<button type="button" onclick="show_Div_2()" style="margin-left: 4px">Div 2 - Blue</button>
<button type="button" onclick="show_Div_3()" style="margin-left: 4px">Div 3 - Green</button>
<div id="Div_1" class="div" style="background-color:red; display: none;"></div>
<div id="Div_2" class="div" style="background-color:blue; display: none;"></div>
<div id="Div_3" class="div" style="background-color:green; display: none;"></div>
I would suggest using data attributes for a toggle. Why? you can use CSS for them and you can use more than just a toggle - multiple "values".
Here in this example I do your "click" but also added a double click on the button for a third value. Try some clicks and double clicks!
A bit of overkill perhaps but more than just "toggle" for example you could use this to show "states" of things like a stoplight or any number of things.
Use the grid display and move them by just adding a data attribute value and double click it to get it to go (using css) to some grid-area:, things like that.
const hideValues = {
hide: "hidden",
show: "showme",
double: "dblclick"
};
function dblClickHander(event) {
const targetSelecor = event.target.dataset.target;
const target = document.querySelector(targetSelecor);
const action = target.dataset.hideme == hideValues.double ? hideValues.hide : hideValues.double;
const toggleTargets = document.querySelectorAll('.toggle-target');
toggleTargets.forEach(el => {
el.dataset.hideme = hideValues.hide;
});
target.dataset.hideme = action;
}
function toggleEventHandler(event) {
const targetSelecor = event.target.dataset.target;
const target = document.querySelector(targetSelecor);
const showHide = target.dataset.hideme == hideValues.hide ? hideValues.show : hideValues.hide;
const toggleTargets = document.querySelectorAll('.toggle-target');
toggleTargets.forEach(el => {
el.dataset.hideme = hideValues.hide;
});
target.dataset.hideme = showHide;
}
/* set up event handlers on the buttons */
const options = {
capture: true
};
/* we do this first to prevent the click from happening */
const toggleButtons = document.querySelectorAll('.toggle-button');
toggleButtons.forEach(el => {
el.addEventListener('dblclick', dblClickHander, options);
});
toggleButtons.forEach(el => {
el.addEventListener('click', toggleEventHandler, options)
});
.toggle-target {
width: 270px;
height: 30px;
padding-left: 10px;
}
.toggle-target[data-hideme="hidden"] {
display: none;
}
.toggle-target[data-hideme="showme"] {
display: block;
}
.toggle-target[data-hideme="dblclick"] {
display: block;
border: solid 2px green;
padding: 1rem;
opacity: 0.50;
}
.red-block {
background-color: red;
}
.blue-block {
background-color: blue;
}
.green-block {
background-color: green;
}
<button type="button" class="toggle-button" data-target=".red-block">Div 1 - Red</button>
<button type="button" class="toggle-button" data-target=".blue-block">Div 2 - Blue</button>
<button type="button" class="toggle-button" data-target=".green-block">Div 3 - Green</button>
<div class="toggle-target red-block" data-hideme="hidden">red</div>
<div class="toggle-target blue-block" data-hideme="hidden">blue</div>
<div class="toggle-target green-block" data-hideme="hidden">green</div>
This can be done in many ways. I think the best approach in your case could be
BUTTONS
<button type="button" onclick="show_div('Div_1')">Div 1 - Red</button>
<button type="button" onclick="show_div('Div_2')" style="margin-left: 4px">Div 2 - Blue</button>
<button type="button" onclick="show_div('Div_3')" style="margin-left: 4px">Div 3 - Green</button>
SCRIPT
function show_div(div_id) {
var thisDiv = document.querySelector('#'+div_id);
var thisState = thisDiv.style.display;
// close all in any cases
document.querySelectorAll('.div').forEach(function(el) {
el.style.display = "none";
});
// open this div only if it was closed
if (thisState == "none" ){
thisDiv.style.display = "block";
}
}
Onclick button, I want to hide the numbers of this counter with background-color i.e.yellow). For example I want the yellow color in front of numbers, something like z-index 1.
If I click again I want to remove yellow color and show me the numbers of the counter again, something like z-index -1. Is it possible?
I have tried this.. Thanks
var countStep = 0;
function counter() {
document.getElementById("btnToggle").innerHTML = ++countStep;
}
function btnColor(btn, color) {
var property = document.getElementById(btn);
if (property.className !== 'toggled') {
property.style.backgroundColor = color;
property.className = 'toggled'
} else {
property.style.backgroundColor = "rgb(244,113,33)";
property.className = '';
}
}
#btnToggle {
background: #222;
color: lime;
}
<p id="btnToggle">OFF</p>
<button onClick="countNumbers = setInterval(counter, 1000)">Play</button>
<button onClick="clearInterval(countNumbers)">Stop</button>
<input type="button" id="btnToggle" value="Toggle" onclick="btnColor('btnToggle','rgb(255,242,0)');" />
This is to use rule z-index: -1 for the counter text relative to the tag p. It is necessary to wrap the counter in an additional span tag:
<p id="btnToggle"><span>OFF</span></p>
Using the querySelector():
var countContent = document.querySelector("#btnToggle span");
Further, in the very logic of js, inside the if { ... } condition, it is necessary to assign a negative value z-index:
countContent.style.zIndex = '-1';
Else, disable (default):
countContent.style.zIndex = '';
And most importantly, the span tag must be set absolute and #btnToggle relative. Add this to your css:
#btnToggle span {
position: absolute;
}
Also, your tag p and tag input have the same id. And this is incorrect, since the id is a unique attribute.
var countStep = 0;
var countContent = document.querySelector("#btnToggle span");
function counter() {
countContent.innerHTML = ++countStep;
}
function btnColor(btn, color) {
var property = document.getElementById(btn);
if (property.className !== "toggled") {
property.style.backgroundColor = color;
property.className = "toggled";
countContent.style.zIndex = '-1';
} else {
property.style.backgroundColor = "rgb(244,113,33)";
property.className = "";
countContent.style.zIndex = '';
}
}
#btnToggle {
background: #222;
color: lime;
position: relative;
height: 18px;
}
#btnToggle span {
position: absolute;
}
<p id="btnToggle"><span>OFF</span></p>
<button onClick="countNumbers = setInterval(counter, 1000)">Play</button>
<button onClick="clearInterval(countNumbers)">Stop</button>
<input type="button" id="btnToggle_two" value="Toggle" onclick="btnColor('btnToggle','rgb(255,242,0)');" />
First you will need to change the id of the p tag or inputs selector so they are unique. Then use the psuedo element for the p tag selector in CSS. Style its position to absolute and set left, top, width and height and display: var(--display) => the variable set from the root element. Then you can set the :root style with a css variable that affects the display of your p tags style --display: none to start.
Check the computed style window.getComputedStyle(document.querySelector('#btnToggle'), ':before').getPropertyValue, ':before').getPropertyValue('display') === 'none' in a conditional to see if it is set to display:none, if it is, then set the document.documentElement.style.setProperty('--display', 'block') to display block else => document.documentElement.style.setProperty('--display', 'none')
let countStep = 0,
btn = document.getElementById('btn'),
btnToggle = document.getElementById('btnToggle')
function counter() {
document.getElementById("btnToggle").innerHTML = ++countStep;
}
btn.addEventListener('click', function() {
window.getComputedStyle(document.querySelector('#btnToggle'), ':before').getPropertyValue('display') === 'none' ? document.documentElement.style.setProperty('--display', 'block') :
document.documentElement.style.setProperty('--display', 'none')
})
:root {
--display: none;
}
#btnToggle {
background: #222;
color: lime;
}
#btnToggle:before {
position: absolute;
background: yellow;
content: '';
width: 98vw;
height: 1.2em;
display: var(--display);
}
<p id="btnToggle">OFF</p>
<button onClick="countNumbers = setInterval(counter, 1000)">Play</button>
<button onClick="clearInterval(countNumbers)">Stop</button>
<input type="button" id="btn" value="Toggle" />
I have a button to show and hide certain part by calling CSS stylesheet change with onClick button. I want the same onclick to toggle in between hide and show. And it is hiding the content with .HeaderContainer {display:none;} but can I get help how to toggle it ?
I want same button if click again then it should override the .HeaderContainer with just {} ;
I have made the code like this to hide. I need how the same button can show this again.
<script type="text/javascript">
function loadToggleAction() {
var sheet = document.createElement('style')
sheet.innerHTML = ".HeaderContainer {display:none;}";
document.body.appendChild(sheet);
}
</script>
<form>
<input type="button" id="dxp" class="button" value="Hide top Pane" onclick='javascript: loadToggleAction();' />
</form>
You could do it like this:
var isHidden = false;
function loadToggleAction() {
var sheet = document.createElement('style')
if(!isHidden){
sheet.innerHTML = ".HeaderContainer {display:none;}";
}else{
sheet.innerHTML = ".HeaderContainer {display:block;}";
}
document.body.appendChild(sheet);
isHidden = !isHidden; //This will change the value to the opposite
}
Or like I would to it:
var isHidden = false;
function toggleVisibility() {
var div = document.getElementsByClassName("test")[0];
if(!isHidden){
div.style.display = "none";
}else{
div.style.display = "block";
}
isHidden = !isHidden;
}
.test {
display: block;
width: 100px;
height: 100px;
background: #ff0000;
}
<div class="test"></div>
<button onclick="toggleVisibility()">Click me</button>
My goal is to have #box2 appear when I click on #box1 but when you click on something other than #box2, it will display none and only #box1 will show.
Here are my 2 boxes, they are just 2 styled divs:
var condition;
$(document).click(function() {
if (condition === 'block') {
$(":not(#box2)").click(function() {
$("#box2").hide();
});
}
})
$('#box1').click(function(e) {
$('#box2').css('display', 'block');
condition = 'block';
});
$('#box2').click(function(e) {
$('#box2').css('display', 'none');
condition = 'none';
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="box1" style="width: 300px; height: 300px; background-color: red; margin-left: 100px; margin-bottom: 50px; position: absolute;">
</div>
<div id="box2" style="width: 300px; height: 300px; background-color: blue; margin-left: 150px; display: none; position: absolute;">
</div>
This current code works correctly the first time but after that, it wont run again. I am just wondering if there is a reset function or where I am going wrong?
Really what I want to do is make this work on an ipad so when the user clicks/taps away from the box, it will close. If there are better ways to do this on the Ipad tablet, please let me know!!
Any ideas?
Don't overcomplicate things. This is all the javascript you need, get rid of everything else:
$(document).click(function () {
$('#box2').hide();
});
$('#box1').click(function (e) {
e.stopPropagation();
$('#box2').show();
});
You could just filter event target at document level:
$(document).on('click', function(e) {
$('#box2').toggle(!!$(e.target).closest('#box1').length);
});
-jsFiddle-
You can listen to all click events of the document and then use the event.target to detect which element is being clicked. if the clicked element is box1 and box2 is not being shown then display it to the user. in any other condition we can hide the box2 if it's not the element being clicked. here is the vanilla JavaScript code to achieve this:
<html>
<body>
<div id='box1'>BOX ONE</div>
<div id='box2' style="display: none;">BOX TWO</div>
<script>
document.addEventListener('click', function(event) {
var secondBox = document.getElementById('box2')
if(event.target.id === 'box1' && secondBox.style.display === 'none'){
secondBox.style.display = 'block'
} else if (event.target.id !== 'box2') {
secondBox.style.display = 'none'
}
})
</script>
</body>
</html>
And if you are into DRY (Do not repeat yourself), you can define a function for this task. Take look at this modified version of the script:
function addOpenHandler(handler, target){
document.addEventListener('click', function(event) {
if(event.target === handler && target.style.display === 'none'){
target.style.display = 'block'
} else if (event.target !== target) {
target.style.display = 'none'
}
})
}
addOpenHandler( document.getElementById('box1'), document.getElementById('box2') )
$(document).click(function () {
if (condition === 'block')
{
$(":not(#box2)").click(function () {
$("#box2").hide();
});
}
})
The line $("#box2").hide(); is firing after every click
I'm trying to make two forms that aren't displayed at the same time. The first one stays visible when the page opens, but if the user select, the first one should be hidden and the second one might take it's place. So here is my CSS for this:
#switcher {
float: right;
font-size: 12px;
}
#web_upload {
visibility: hidden;
}
#local_upload {
visibility: visible;
}
Here is the HTML:
<form action="img_upload.php" id="local_upload" method="post" enctype="multipart/form-data">
<center>
<input type="file" name="file" id="file" />
<br />
<input type="image" name="submit" src="graphics/upload.png" />
</center>
</form>
<form action="url_upload.php" id="web_upload" method="post" method="post">
<center>
<input type="text" name="url" id="url" />
<br />
<input type="image" name="submit" src="graphics/upload.png" />
</center>
</form>
And here is my Javascript to do it:
function showHide(id, other)
{
if(document.getElementById(id)) {
if(document.getElementById(id).style.visibility != "hidden") {
document.getElementById(other).style.visibility = "hidden";
document.getElementById(id).style.visibility = "visible";
} else {
document.getElementById(id).style.visibility = "hidden";
document.getElementById(other).style.visibility = "visible";
}
}
}
So, I'm having three problems:
The second form has a reserved place on the page and I don't want this empty place
The second form is displaying on that reserved place instead of taking place over the first one
If the user select one of the options and try to select other after nothing happens
How I can solve this problems?
#Nathan Campos: I'd combine display and visibility like so --
CSS:
#web_upload {
display: none;
visibility: hidden;
}
#local_upload {
display: inline;
visibility: visible;
}
JavaScript:
function showHide(id, other)
{
var id1 = document.getElementById(id);
var id2 = document.getElementById(other);
if (id1.style.display == "none") {
id1.style.display = "inline";
id1.style.visibility = "visible";
id2.style.display = "none";
id2.style.visibility = "hidden";
} else if (id1.style.display == "" || id1.style.display == "inline") {
id1.style.display = "none";
id1.style.visibility = "hidden";
id2.style.display = "inline";
id2.style.visibility = "visible";
}
}
display: none/block; Show the form / Totally hide and clear the space
visibility: hidden; Hide the form, but keep the space preserved
The CSS visibility property is not the right choice here.
The 'visibility' property specifies whether the boxes generated by an element are rendered. Invisible boxes still affect layout (set the 'display' property to 'none' to suppress box generation altogether)
Reference: http://www.w3.org/TR/CSS21/visufx.html#visibility
Consider instead the CSS display property - display:none applied to an element will make it appear as if it is not present at all, it will be invisible and will not affect layout.
#switcher {
float: right;
font-size: 12px;
}
#web_upload {
display:none;
}
#local_upload {
display:block;
}
//
function showHide(id, other)
{
switch (document.getElementById(id).style.display) {
case 'block':
document.getElementById(id).style.display = 'none';
document.getElementById(other).style.display = 'block';
case 'none':
document.getElementById(id).style.display = 'block';
document.getElementById(other).style.display = 'none';
}
}