onclick trigger doesn't work first click - javascript

I'm confused why the onclick function doesn't register the first time it is clicked. Each div with the onclick trigger has to be clicked twice the first time.
function selected(elmnt) {
if (elmnt.style.backgroundColor == "transparent")
elmnt.style.backgroundColor = "#990000"
else
elmnt.style.backgroundColor = "transparent"
}
#container {
background-color: transparent;
height: 100px;
width: 100px;
}
<div id="container" onclick="selected(this)">click me</div>
Am I missing something here?

It is because your element style is not transparent. Only your element's computedStyle is. Try this:
function selected(elmnt) {
if (elmnt.style.backgroundColor == "transparent")
elmnt.style.backgroundColor = "#990000"
else
elmnt.style.backgroundColor = "transparent"
}
#container {
background-color: transparent;
height: 100px;
width: 100px;
}
<div id="container" onclick="selected(this)" style="background-color: transparent;">click me</div>
There's also the natural way:
function selected(elmnt) {
if (elmnt.style.backgroundColor == "")
elmnt.style.backgroundColor = "#990000"
else
elmnt.style.backgroundColor = ""
}
#container {
background-color: transparent;
height: 100px;
width: 100px;
}
<div id="container" onclick="selected(this)">click me</div>

The element doesn't start with a background-color of transparent so it always goes to the else. Changing the div to
<div id="container" onclick="selected(this)" style='background-color:transparent'>www</div>
will make it work. A css style sheet doesnt' append style to the DOM elements physically.

Both answers above absolutely agree initially style is not set.
Just to tell you for next time how to DEBUG it
us console.log() click F12 for developer tools then console tab
I am fan of short IFs when simple IF
<script>
function selected(elmnt) {
console.log(elmnt.style.backgroundColor)
var bG= elmnt.style.backgroundColor
elmnt.style.backgroundColor = ( bG == '' || bG == "transparent") ? "#990000" : "transparent";
}
</script>

Related

Hide an expanded menu when clicking outside of the container: how to use code snipet

I have a menu that open a sub-menu section onclick (let's name the container: "sub-menu").
I would like "sub-menu" to disapear if the user click outside of it / on the rest of the page.
It seems to be solved on How do I detect a click outside an element?
But I can't get how to use the code snipet from the second most popular answer:
export function hideOnClickOutside(selector) {
const outsideClickListener = (event) => {
const $target = $(event.target);
if (!$target.closest(selector).length && $(selector).is(':visible')) {
$(selector).hide();
removeClickListener();
}
}
const removeClickListener = () => {
document.removeEventListener('click', outsideClickListener)
}
document.addEventListener('click', outsideClickListener)
}
Could you please guide me on how to use it?
I edited, and included a basic example. -> I want sub menu to also close when clicking on the "white" space. But not on the parent "main menu" element.
document.getElementById("main-menu").addEventListener("click", function() {bouttonexpand('sub-menu-class')});
function bouttonexpand(id) {
var elemeacacher = document.getElementsByClassName(id);
if (elemeacacher[0].style.display != "none"){
for(var y=0;y<elemeacacher.length;y++)
elemeacacher[y].style.display = "none";
}
else {
for(var y=0;y<elemeacacher.length;y++)
elemeacacher[y].style.display = "block";
}
}
#main-menu {
display:inline-block;
height:20px;
width:100px;
background: blue;
padding: 5%;
}
#sub-menu {
display:inline-block;
height:50px;
width:50px;
background: red;
display: none;
}
<div><div id="main-menu">Main menu</div></div>
<div><div id="sub-menu" class="sub-menu-class">Sub menu</div></div>
Thanks
By using jQuery, you can bind to the document click event and hides the div container when the clicked element isn’t the container itself or descendant of the div element.
var container = $("#sub-menu");
if (!container.is(event.target) && !container.has(event.target).length) {
container.hide();
}
If you want to hide that container without being tested the container itself or descendant of the div element just remove the condition and simply use container.hide();.
Also, rather than setting display: none; on sub-menu in the CSS, set it manually so that you can toggle the sub-menu from the very first click.
Have a look at the snippet below:
var x = document.getElementById("sub-menu");
x.style.display = "none";
$(document).click(function (evt) {
if ($(evt.target).is('#main-menu')) { // control click event if it's main-menu
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
else {
var container = $("#sub-menu");
if (!container.is(event.target) && !container.has(event.target).length) { // if you don't want that remove the condition and write container.hide(); only
container.hide();
}
}
});
#main-menu {
display: inline-block;
height: 20px;
width: 100px;
background: blue;
padding: 5%;
}
#sub-menu {
display: inline-block;
height: 50px;
width: 50px;
background: red;
}
<script src="https://code.jquery.com/jquery-3.5.1.min.js"
integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<div id="main-menu">Main menu</div>
<div id="sub-menu" class="sub-menu-class">Sub menu</div>

Display value shoe false in console [duplicate]

This question already has answers here:
why javascript this.style[property] return an empty string? [duplicate]
(2 answers)
Closed 2 years ago.
i have a div and button i click the button fist time no response and click again and show
function banne() {
var ban = document.getElementById("content");
//consloe.log(ban.style.display === "none");
if (ban.style.display === "none") {
ban.style.display = "block";
} else {
ban.style.display = "none";
}
}
.banner-content {
display: none;
height: 100px;
color: #fff;
background: #1b1b1b;
}
<button class="banner" onclick="banne()"> know </button>
<div class="banner-content" id="content">
Some Data
</div>
here the console value show false value but i write the style inline style="display:none" in div class banner-content it working, why the style sheet value not taken ,any idea?
Javascript can't access the style mentioned in the CSS file with the ban.style.display. You have to use getComputedStyle() method.
window.getComputedStyle(ban, null).getPropertyValue("display");
But in your case I think it is better use a class based toggle maybe like,
CSS
.banner-content {
display: none;
height: 100px;
color: #fff;
background: #1b1b1b;
}
.banner-content.active {
display: block;
}
JS
function banne() {
var ban = document.getElementById("content");
ban.classList.toggle("active");
}
While style doesn't register the stylesheet properties, you can check if the style does not equal to "block" and then set it to block, otherwise none. Also see the difference between getComputedStyle and style: https://developer.mozilla.org/en/DOM/window.getComputedStyle
function banne() {
var ban = document.getElementById("content");
//consloe.log(ban.style.display === "none");
if (ban.style.display !== "block") {
ban.style.display = "block";
} else {
ban.style.display = "none";
}
}
.banner-content {
display: none;
height: 100px;
color: #fff;
background: #1b1b1b;
}
<button class="banner" onclick="banne()"> know </button>
<div class="banner-content" id="content">
Some Data
</div>
It's generally not a good idea to use inline event handlers.
Add a listener to the document. To toggle display, use a separate css class (.visible in the snippet) and toggle that. It makes your life so much easier.
document.addEventListener("click", banne);
function banne(evt) {
if (evt.target.classList.contains("banner")) {
document.querySelector("#content").classList.toggle("visible");
}
}
.banner-content {
display: none;
height: 100px;
color: #fff;
background: #1b1b1b;
}
.banner-content.visible {
display: block;
}
<button class="banner"> know </button>
<div class="banner-content" id="content">
Some Data
</div>

fadeToggle on body click

I have this div which shows/hides with display:none/block by clicking on an id #cart. The div opens and closes by clicking on element with the id but I want to close the div on body click too. How can I do it please?
Code I am using is below:
jQuery("#cart").on("click", function() {
jQuery(".shopping-cart").fadeToggle( "fast");
});
jQuery("#cart, body").on("click", function() {
jQuery(".shopping-cart").fadeToggle("fast");
});
What you can do is add a listener to the entire window and check for clicks. When there is a click, we check which element has been clicked and check on whether it's the element. We repeat this for the parent element as well.
<!DOCTYPE html>
<html>
<head>
<script>
function checkClickOutsiteElement(clickedElement, elementToCheck){
var iterator = clickedElement;
while(true){
// The click was in the element.
if( iterator === elementToCheck )
return;
// Go to the parent.
if( !iterator.parentElement ){
alert('outside menu');
return;
}
iterator = iterator.parentElement;
}
}
window.addEventListener('click', function(event){
checkClickOutsiteElement(event.target, document.getElementById('menu'));
});
</script>
</head>
<body>
<div class="wrapper">
<div id="menu" style="width: 100px; height: 100px; background-color: red;"></div>
</div>
<div class="wrapper">
<div id="not_menu" style="width: 100px; height: 100px; background-color: green;"></div>
</div>
</body>
</html>
You probably want two separate functions, since your cart button should toggle both ways, but the body click handler should only toggle out.
Protip: on() isn't doing anything for you that click() wouldn't, the way you're using it. The latter is a bit cleaner.
jQuery("#cart").click(function() {
jQuery(".shopping-cart").fadeToggle("fast");
});
jQuery("body").click(function() {
jQuery(".shopping-cart").fadeOut("fast");
});
Protip 2: Easily and safely alias jQuery to $ like so:
jQuery(function($) { // document ready with dollar alias
$("#cart").click(function() {
...
});
I have this div which shows/hides with display:none/block by clicking
on an id #cart. The div opens and closes by clicking on element with
the id but I want to close the div on body click too.
In vanilla javascript, you can:
write a function to show / hide the div
add a click event listener to #cart
add a click event listener to body
Working Example:
// Grab #cart
const cart = document.getElementById('cart');
// Grab .myDiv
const myDiv = document.getElementsByClassName('div')[0];
// Function to toggle .myDiv
const toggleMyDiv = (e) => {
if (e.target === e.currentTarget) {
myDiv.dataset.display = (myDiv.dataset.display === 'show') ? 'hide' : 'show';
}
}
// Add Click Event Listener to #cart
cart.addEventListener('click', toggleMyDiv, false);
document.body.addEventListener('click', toggleMyDiv, false);
body,
#cart {
cursor: pointer;
}
div {
display: inline-block;
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
font-weight: bold;
}
#cart {
color: rgb(255, 255, 255);
background-color: rgb(255, 0, 0);
}
.div {
color: rgb(255, 0, 0);
background-color: rgb(255, 255, 0);
}
.div[data-display="show"] {
opacity: 1;
}
.div[data-display="hide"] {
opacity: 0;
}
<div id="cart">Cart</div>
<div class="div show" data-display="show">myDiv</div>

JavaScript and CSS hover issue

When changing a color of a paragraph element, CSS hover stops working.
I made a demo to explain: https://jsfiddle.net/woan6b64/
After I change <p>'s color, the hover selector stops working.
My question is:
How can I change the hover effect with JavaScript?
How can I get hovering to work after a color change?
JSFiddle code:
var shift = 0;
function change() {
if (shift === 0) {
document.getElementById("box").style.backgroundColor = "black";
document.getElementById("text").style.color = "white";
document.getElementById("text").innerHTML = 'Good! Now click the box again.';
shift = 1;
} else {
document.getElementById("box").style.backgroundColor = "white";
document.getElementById("text").style.color = "black";
document.getElementById("text").innerHTML = 'Hover effect is now broken :(';
}
}
#box {
height: 100px;
width: 200px;
background-color: white;
}
p:hover {
color: green;
}
<div id='box' onclick='change()'>
<p id='text'>
Click me for this box to change color. (Notice how I turn green when hovered)
</p>
</div>
Stop it! Don't use !important if not necessary... your problem is that you set the color to black.
document.getElementById("text").style.color = "";
This will make the color inherit the right style.
How ever, this ain't the right solution either. You should add class to the box and then do:
#box {
height: 100px;
width: 200px;
background-color: white;
}
p:hover {
color: green;
}
#box.altered {
color: white;
background-color: black;
}
.altered p:hover {
color: red;
}
<div id="box" onclick="this.classList.toggle('altered')">
<p id='text'>
Click me for this box to change color. (Notice how I turn green when hovered)
</p>
</div>
Add a new class
// document.getElementById("box").style.backgroundColor = "black";
// document.getElementById("text").style.color = "white";
document.getElementById("text").classList.add("purple");
.purple {
color: purple;
}
If you want to do it with pure JS you need to listen for onmouseover event and onmouseout event, check the code that I made
var textElement = document.getElementById("text");
var defaultColor = textElement.style.color;
textElement.onmouseover = function(event) {
var currentElement = event.target;
currentElement.style.color = "red";
}
textElement.onmouseout = function(event) {
var currentElement = event.target;
currentElement.style.color = defaultColor;
}
<div id="parent">
<p id="text">
I am a text that change its text color :D
</p>
</div>
It's an issue with specificity, so you'll need to use !important on the color property to force it.
fiddle
NB: This isn't best practice. Depending on your intent, adding a class or simply unsetting the color may be the best option.
After setting the color, the hover is overridden. Use !important to force it:
p:hover{
color: green !important;
}

after scrolling, detect when element returns to original position

I am trying to, sort of, emulate the effect here. Essentially, during scrolling, change the css (drop shadow), and when the element comes back to original position (remove shadow).
I am able to detect scroll, but not able to figure out how to detect the return to the original un-scrolled state.
HTML
<div id="container">
<ul>
<li id="one">el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li>
</ul>
</div>
CSS
html, body {
margin: 0;
padding: 0;
height: 100%;
}
#container {
height: 100px;
width: 500px;
border: 1px solid #000000;
overflow: scroll;
}
JS (with jquery)
var p = $('#one');
var position0 = p.position().top;
$('#container').scroll(function () {
if (p.position().top != position0) {
console.log('p.position: ' + p.position().top);
$('#container').css('background-color', 'pink');
}
});
JSFIDDLE: http://jsfiddle.net/nrao89m3/
PS: From console.log it doesn't seem to return to its original value at all.
Just add an else block:
var p = $('#one');
var position0 = p.position().top;
$('#container').scroll(function () {
if (p.position().top != position0) {
console.log('p.position: ' + p.position().top);
$('#container').css('background-color', 'pink');
} else {
$('#container').css('background-color', 'white');
}
});
http://jsfiddle.net/vyjbwne2/

Categories

Resources