Can't change clip-path property on an element - javascript

So I have a button with a box shadow, and when I click on it, I want to hide one side of the box shadow. When I change the initial CSS, everything works fine and the box shadow can be changed, but when I use javascript, none of the changes I make to the box shadow work.
HTML:
<button class = "ShowWeather" id = "ShowWeather" onclick = "ShowWeather()"></button>
javascript:
function ShowWeather(){
const Forecast = Get("Forecast"); //get just gets an element by id
const Button = Get("ShowWeather");
const slider = Get('forecast_slider');
if(slider.style.height == "0px"){
slider.style.border = "none";
slider.style.height = `${Forecast.getBoundingClientRect().height}px`;
Button.style.borderRadius = "0vw 0vw 0vw 0vw";
Button.style.borderBottom = "none";
Button.style.clipPath = "inset(-1vh -1vh 0vh -1vh);"; //THIS IS THE PROBLEMATIC LINE
}
else{
slider.style.height = "0px";
Button.style.clipPath = "inset(-1vh -1vh -1vh -1vh);"; //another problematic line
setTimeout(closeWeather, 300);
}
}
CSS:
.ShowWeather{
width: 16.15vw;
background: white;
border-top: none;
padding-top: 1vh;
position: relative;
bottom: 0.8vh;
border-radius: 0vw 0vw 1vw 1vw;
border: none;
box-shadow: 0vh 0.5vh 1vh gray;
clip-path: inset(-1vh -1vh 0vh -1vh);;
}
Everything besides the two problematic lines work perfectly, only changing the clip-path does not work. I probably made some tiny mistake but I have been trying to debug this 1 line of code for multiple hours aaaAAAA

you can try to remove the semicolon at the end:
Button.style.clipPath = "inset(-1vh -1vh -1vh -1vh)";

Related

My button does not move to the upper right corner from the left side via javascript DOM

I have button in html that is on the middle left of the screen, that button is styled such as:
.openbtn {
font-size: 20px;
border-radius: 0 5px 5px 0;
cursor: pointer;
position: fixed;
Top: 50%;
left: 0px;
background-color: #181A1B;
color: white;
padding: 10px 15px;
border: none;
z-index: 1;
transition: 0.5s;
}
now when i click this button i want it to transfer to the upper right and when i click again it should go back to its original position. In Javascript the button is handled as so:
var lastState = false;
function sideButtonClicked() {
if(!lastState){
//open
lastState=true
document.getElementById("Button").style.left = "";
document.getElementById("Button").style.right = "0";
document.getElementById("Button").style.top = "0";
}
else{
//close
lastState=false
document.getElementById("Button").style.left = "0px";
document.getElementById("Button").style.right = "";
document.getElementById("Button").style.top = "50%";
}
I find this tricking because if i want to play that button on the upper right corner is when i declare it on css i dont place the left property but since its initial position is in the left i have to declare it. I tried setting it to "" but it does not work. What i know works is the button moves up/down upon clicking the button,
}
This is a simple example of how to toggle classes in vanilla JS. Then, you just do your styling via CSS.
// Cache the DOM element for continued use
var btn = document.getElementById("btn");
// Attach event listener to button for 'click' event
btn.addEventListener("click", () =>
{
// Where we see if it has the class or not
// Is it inactive?
if (!btn.classList.contains("active"))
{
console.log("Added");
btn.classList.add("active");
} else // If it *is* currently active
{
console.log("Removed");
btn.classList.remove("active");
}
});
.btn {
padding: 1rem;
width: 200px;
transition: all 300ms ease-in-out;
}
.btn.active {
padding: 2rem;
width: 400px;
}
<button class="btn" id="btn">Click Me</button>
Essentially, you're using a CSS class as a target for the different styling and just using JS to turn the class on/off. That way, you can just edit the 'toggle' class in CSS to whatever you want and the code will always work. This is usually what we use for sticky navbars, etc. You just add/remove another class, and that overrides the default styling.

img CSS will not update onclick via jQuery

I have been banging my head against this for a few hours and am no closer to a solution than I was before. I am dynamically generating <img> tags, each with their own unique ID, via an AJAX call and JavaScript and giving them certain border colors upon generation (marking whether they are 'good' or 'bad`).
// the div that the screenshots go in
<div id ="screenshots_holder"> </div>
// the JS that is generating the screenshots
var screenshots_holder = document.getElementById("screenshots_holder");
var x = "";
for(i in data.screenshots) {
var image_name = data.screenshots[i].split("/")
x += '<img id="' + image_name[2] +'"src="/static/';
x += data.screenshots[i];
x += '" style = "height: auto; border-style: solid; border-width: 5px; border-color: #1ebe1e; max-width: 10%; margin-right: 10px; margin-bottom: 10px; "';
x += 'onclick="blueifyScreenshot(this.id)" >'; <-- the problem is here!!
}
screenshots_holder.innerHTML = x;
This above code worked just fine... minus the very last part where I add the onclick attribute!
I am trying to make it so that when I click on a screenshot, its border changes color, it scales just a bit, and adds a box-shadow, all of which is done through a JavaScript function called blueifyScreenshot(id) which takes the unique id of the image as a parameter so it can be grabbed through jQuery.
Right now, I can get the screenshot to do that when I hover over it but that's not permanent. Unfortunately, I cannot get any of my CSS changes to go through.
Right now I am grabbing each image element by a jQuery id selector. I know that this is working and updated_id is what it should be because I've verified it through HTML/JS breakpoints in the debugger and matched it to the screenshot that I want to change the border of. blueifyScreenshot IS being called, but none of the CSS is changing no matter what I do.
I have tried using the .css method, which I know only works on existing elements, which my screenshots are.
function blueifyScreenshot(id) {
console.log("#" + id);
var updated_id = "#" + id;
// this isn't changing anything
$(updated_id).css({
"border-color": "#0614d1 !important",
"cursor" : "pointer" ,
"transform": "scale(1.1)",
"box-shadow": "0 0 12px #0614d1" });
}
I have tried adding a class with .addClass() and defining it in my .css sheet.
function blueifyScreenshot(id) {
console.log("#" + id);
var updated_id = "#" + id;
// this isn't changing anything either..
$(updated_id).addClass('selected_screenshot');
}
/* CSS */
.selected_screenshot {
border-color: #0614d1 !important;
cursor : pointer;
transform: scale(1.1);
box-shadow: 0 0 12px #0614d1;
}
I have even tried updating the style attribute of the image with the .attr() method.
function blueifyScreenshot(id) {
console.log("#" + id);
var updated_id = "#" + id;
// and THIS wont change anything.
$(updated_id).attr('style', "height: auto; border-style: solid; border-width: 5px; border-color: #0614d1; max-width: 10%; margin-right: 10px; margin-bottom: 10px;");
}
None of this has worked and my screenshots do not change when I click on them. I've tried browsing through StackOverflow to see if other people had this issue and it looks like everyone was able to resolve their problems through the methods I've tried.
Anyone able to assist, or maybe spot something I have not?
Just reference the element
onclick="blueifyScreenshot(this)"
and toggle a class
function blueifyScreenshot(elem) {
elem.classList.toggle('active')
}
Personally I would just use a dom method
var images = [
'http://placekitten.com/100/300',
'http://placekitten.com/200/200',
'http://placekitten.com/200/300',
'http://placekitten.com/100/200'
]
var outElem = document.getElementById('out')
images.forEach(function(src) {
var img = document.createElement('img');
img.className = 'example'
img.src = src
img.addEventListener('click', function() {
this.classList.toggle('selected')
})
outElem.appendChild(img)
})
img.example {
height: auto;
border-style: solid;
border-width: 5px;
border-color: #1ebe1e;
max-width: 10%;
margin-right: 10px;
margin-bottom: 10px;
}
img.example.selected {
border-color: #0614d1 !important;
cursor: pointer;
transform: scale(1.1);
box-shadow: 0 0 12px #0614d1;
}
<div id="out"></div>

Transition the height of a div to fit its contents

I have a div that is used to display any info message to the user.
Initial height of this div is zero and display is none. When there's any message to display to the user, i display it using javascript.
I transition the height of this div from 0 to 48px which gives the effect of this div sliding down slowly.
problem
As the height of this is set to 48px, if message inside is long, it doesn't increases it's height to prevent the overflow of text.
Message displayed in full size browser window
Same message displayed in small browser window
question
How can i set the height of this div in javascript so that its height adjusts to fit its contents.
HTML
<!--used for displaying error or success message-->
<p id="info-message-block">
<span></span>
</p>
CSS
.error-msg-block,
.success-msg-block {
display: none;
background: #dc3545;
color: #fff;
border-radius: 2px;
height: 0;
font-weight: 400;
margin: 8px 0 0;
transition: height 0.6s ease-in;
overflow: hidden;
font-size: 85%;
}
.error-msg-block span,
.success-msg-block span {
display: inline-block;
padding: 12px 0 0 20px;
}
javascript function to display this info message
let displayInfoMessage = function (message, messageType) {
'use strict';
let messageBlock = document.querySelector('#info-message-block');
messageBlock.style.display = 'block';
messageBlock.firstElementChild.textContent = message;
if (messageType === 'error') {
messageBlock.className = 'error-msg-block';
} else {
messageBlock.className = 'success-msg-block';
}
setTimeout(function () {
messageBlock.style.height = '48px';
}, 10);
};
As commented above here is the idea using max-height instead of height
let displayInfoMessage = function(message, messageType) {
'use strict';
let messageBlock = document.querySelector('#info-message-block');
messageBlock.style.display = 'block';
messageBlock.firstElementChild.textContent = message;
if (messageType === 'error') {
messageBlock.className = 'error-msg-block';
} else {
messageBlock.className = 'success-msg-block';
}
setTimeout(function() {
messageBlock.style.maxHeight = '120px'; /*Make this value big enough to cover the worst case*/
}, 10);
};
displayInfoMessage("this is a very loooong loooong loooong loooong message for test")
body {
max-width:200px;
}
.error-msg-block,
.success-msg-block {
display: none;
background: #dc3545;
color: #fff;
border-radius: 2px;
max-height: 0;
font-weight: 400;
margin: 8px 0 0;
transition: max-height 0.6s ease-in;
overflow: hidden;
font-size: 85%;
}
.error-msg-block span,
.success-msg-block span {
display: inline-block;
padding: 12px 20px;
}
<p id="info-message-block">
<span></span>
</p>
Simply say messageBlock.style.height = 'auto' instead of setting a fixed value.
If the auto height is wrong, adjust it using padding.
If you want to limit the possible height, set max-height in the stylesheet.
Adding this answer as it seems like possibility of using auto is the real missing piece here, and using max-height is just working this lack of knowledge around.

Highlight HTML element just like the Chrome Dev Tools in Javascript

WolfPack!
I want to highlight any element I hover over just like the Chrome Dev Tools does it.
Picture of Chrome Dev Tools
Notice how the entire element is drenched in a blue tint? This is not as simple as adding a background color or linear-gradient because the insides of input elements are still white.
I've tried using the different filter methods like hue rotate, contrast w/brightness, and even THIS MONSTER, but nothing seems to work.
The closest I've been is just a nice looking box-shadow around the elements for highlighting.
Javascript: element.classList.add('anotherClass')
CSS: box-shadow: 0 0 5px #3fd290, 0 0 10px #36A9F7, 0 0 15px #36A9F7, 0 0 20px #36A9F7 !important;
Help me make my dreams come true
If anyone cares what I did to solve it, here is my code (thanks to the help of Roope):
onMouseEnter:
highlightElement(event){
const hoverableElements = document.querySelectorAll('[data-attr]');
for(let elm of hoverableElements){
const styles = elm.getBoundingClientRect()
if(event.currentTarget.textContent === elm.dataset.dataAttr) {
let div = document.createElement('div');
div.className = 'anotherClass';
div.style.position = 'absolute';
div.style.content = '';
div.style.height = `${styles.height}px`;
div.style.width = `${styles.width}px`;
div.style.top = `${styles.top}px`;
div.style.right = `${styles.right}px`;
div.style.bottom = `${styles.bottom}px`;
div.style.left = `${styles.left}px`;
div.style.background = '#05f';
div.style.opacity = '0.25';
document.body.appendChild(div);
}
}
}
onMouseLeave:
onLeave(event){
const anotherClass = document.getElementsByClassName("anotherClass");
for (let elm of anotherClass) {
document.body.removeChild(elm)
}
}
After looping through the querySelectorAll (to get the desired elements), I used element.getBoundingClientRect() to get the exact height, width, top, right, bottom, left of the element.. That way, the new div created will take the exact size and location of the element.
CSS didn't quite cut it because other stylesheets would override/mess the styling up.
If all you want is the blue transparent highlight, just add a pseudo element over the hovered element. Positioning may of course be absolute of fixed for the element as well.
.element {
float: left;
position: relative;
width: 100px;
height: 100px;
margin: 10px;
border: 1px solid #000;
text-align: center;
line-height: 100px;
}
.element:hover::after {
position: absolute;
display: block;
content: '';
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #05f;
opacity: 0.25;
}
.tall {
height: 200px;
}
<div class="element">Element</div>
<div class="element tall">Element</div>
<div class="element">Element</div>

Retain CSS :hover when changing CSS styles with Javascript

I have a div (acting as a button) which has certain CSS that activates when hovered on:
#btn{
width: 80%;
height: 125px;
border: 1px solid #9676E8;
border-radius: 10px;
transition: background-color 0.25s ease;
background-color: #B299F2;
color: white;
}
#btn:hover{
background-color: #9676E8;
}
Note: #9676E8 is a darker shade of #B299F2, both blue.
This button has a toggle function, where the desired effect is that clicking it will toggle its background to become red instead of blue. The relevant JavaScript is here:
var btn = document.getElementById("btn");
btn.addEventListener("click",function(){
if(!toggle){
toggle = true;
btn.style.border = "1px solid #FF0000";
btn.style.backgroundColor = "#AA3030";
} else {
toggle = false;
btn.style.border = "1px solid #9676E8";
btn.style.backgroundColor = "#B299F2";
}
});
Note: #AA3030 and #FF0000 are shades of red.
My problem is that after clicking the button the first time, the button turns red (as desired). However, when clicking it so it changes back to blue, there is no more hover effect afterward. Hovering over it doesn't do anything but clicking it still works.
I do not need the button to have a hover effect while it is red, but I want to retain the hover effect while it is blue. Is there any way of doing so?
JsFiddle Here
This is because the inline rule set by JS overrides any CSS rules (unless they have the !important declaration). Instead of setting the color back to the same value, set it to empty to reset it:
else {
toggle = false;
btn.style.border = "";
btn.style.backgroundColor = "";
}
If you use classes instead of setting CSS properties in you JS it can be achieved by changing classes on toggle.
<!-- html -->
<div id="btn" class="blue"></div>
/* Javascript */
var toggle = false;
var btn = document.getElementById("btn");
btn.addEventListener("click",function(){
if(!toggle){
toggle = true;
btn.className = "red";
} else {
toggle = false;
btn.className = "blue";
}
});
/* style */
#btn{
width: 80%;
height: 125px;
border-radius: 10px;
transition: background-color 0.25s ease;
color: white;
}
.blue {
border: 1px solid #9676E8;
background-color: #B299F2;
}
.red {
border: 1px solid #FF0000;
background-color: #AA3030;
}
.blue:hover{
background-color: #9676E8;
}

Categories