react classname is not picking inline style - javascript

I am using dynamic content in my react app. The content is loading fine. I am trying to change the style of the paragraph tag on the basis of a dynamic value. The style also changes on click event of the paragraph tag. When I click the paragraph the text is changing but the previous selected styles remains in effect and does not change with the dynamic value. Code which is changing the style is
if(ans){
return ans.map((a, index) => {
return(
<div className="options-container" key={index}>
<p onClick={this.handleOptionClick} className={a.IsChecked ? 'option-selected' : 'option'}>{a.Awnser}</p>
</div>
)}
);
}
the style for this is
.options-container {
display: inline-block;
width: 30%;
}
.option {
background-color: $blue;
border-radius: $button-radius;
color: $white;
cursor: pointer;
margin: $md auto;
padding: $normal;
transition: 0.3s linear all;
text-align: center;
width: 90%;
}
.option-selected {
background-color: $green;
border-radius: $button-radius;
color: $white;
cursor: pointer;
margin: $md auto;
padding: $normal;
transition: 0.3s linear all;
text-align: center;
width: 90%;
}

Problem seems to be with a.IsChecked, rest of the code looks correct. Confirm whether its value is updating in the component.

here what I did. I think you are missing something. please take a look if you find some idea.
handleOptionClick = () => {
this.setState({ answer: "here is your new value", IsChecked: true });
};
render() {
return (
<div>
<p
onClick={this.handleOptionClick}
className={this.state.IsChecked ? "option-selected" : "option"}
>
{this.state.answer}
</p>
</div>
);
}

Related

Why a few this same components works differently in react?

I have the following component named Card:
<article className={styles.card_container}>
<input type="checkbox" className={styles.checkbox} onClick={setCheckbox}/>
<div className={styles.text_container} id="txt_container">
<span>
{props.number}
</span>
</div>
</article>
Which should display checkbox, without the tick - container to check or not, with background colors, depends on this checkbox is checked or not.
For example, when unchecked this should has red color, but when checked - black.
For this, I decided to use state:
const [isChecked, setChecked] = useState(false);
const setCheckbox = (e) => {
if (isChecked===true){
setChecked(false);
document.getElementById("txt_container").style.backgroundColor="#a81616";
}else {
setChecked(true);
document.getElementById("txt_container").style.backgroundColor="#000";
}
}
I wanted to create a few this type of components so I decided to map this with information from array:
{data.map(element=>
<Card number={element.option} key={element.option}/>)
}
(Where data is an array with object with numbers, Card is created components with code above).
The problem is that, when I "check" other components, it change color only at first.
Why did it happen? I appreciate for any help.
And there some css code:
.card_container {
position: relative;
width: 60px;
height: 45px;
margin: 5px;
float: left;
border: 2px solid #50bcf2;
box-sizing: border-box;
}
.text_container {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
line-height: 25px;
transition: .5s ease;
}
.checkbox {
position: absolute;
top: 0;
left: 0;
width: 60px;
height: 45px;
opacity: 1;
cursor: pointer;
}
I would like to do this by js, is there other way to do this (not by css)? Or maybe can I inject background color provided by props from for example an array to Card component?
You can use style attribute on react component
<div className={styles.text_container} style={{backgroundColor: isChecked? #a81616 : #000}}>
your code doesnt work, because ID is supposed to be unique and you are only selecting first occurence... if you want to work with DOM in react, dont use getElementByID and use useRef() from react. Its more "reactish" way how to do it.

How can I add interactive semantics to a pseudo element with CSS or JavaScript?

I have a small carousel that plays automatically on page load, using HTML, CSS and JavaScript and definitely no jQuery.
To add a pause/play option there is a span with role="checkbox" followed by a label.
The label itself is hidden and has no content. The span has two pseudo elements. On first showing, the pseudo element shows the ⏸ character, controlled by a CSS ::after class. When clicked, the span has the class "is-clicked" added, at which point the ▶ character is displayed, controlled by another ::after class
It is focusable and can be activated with the keyboard by hitting the Enter key, but when I check with Lighthouse, I keep getting the "Focusable elements should have interactive semantics".
Why is this?
Here is the code:
/* detect keyboard users */
function handleFirstTab(e) {
if (e.key === 'Tab') { // the 'I am a keyboard user' key
document.body.classList.add('user-is-tabbing');
window.removeEventListener('keydown', handleFirstTab);
}
}
let checkboxEl = document.getElementById('checkbox');
let labelEl = document.getElementById('checkboxLabel');
labelEl.onclick = function handleLabelClick() {
checkboxEl.focus();
toggleCheckbox();
}
function toggleCheckbox() {
let isChecked = checkboxEl.classList.contains('is-checked');
checkboxEl.classList.toggle('is-checked', !isChecked);
checkboxEl.setAttribute('aria-checked', !isChecked);
}
checkboxEl.onclick = function handleClick() {
toggleCheckbox();
}
checkboxEl.onkeypress = function handleKeyPress(event) {
let isEnterOrSpace = event.keyCode === 32 || event.keyCode === 13;
if(isEnterOrSpace) {
toggleCheckbox();
}
}
.link {
height: auto;
border: 1px solid #000;
margin-bottom: 1rem;
width: 80%;
display: block;
}
#carousel-checkbox {
margin-bottom: 1rem;
height: 50px;
width: 100px;
display: inline-block;
}
#carousel-checkbox input {
display: none;
}
#carousel-checkbox label {
display: inline-block;
vertical-align: middle;
}
#carousel-checkbox #checkbox {
position: relative;
top: 0;
left: 30px;
padding: 0.5rem 1rem;
background: rgba(255,255,255, 0.5);
}
#carousel-checkbox #checkbox:hover {
cursor: pointer;
}
#carousel-checkbox #checkbox:focus {
border: 1px dotted var(--medium-grey);
}
#carousel-checkbox #checkbox::after {
content: "⏸";
font-size: 1.5rem;
color: var(--theme-dark);
}
#carousel-checkbox #checkbox.is-checked::after {
content: "▶";
}
<div class="link">A bit of text with a dummy link to demonstrate the keyboard tabbing navigation. </div>
<div id="carousel-checkbox"><span id="checkbox" tabindex="0" role="checkbox" aria-checked="false" aria-labelledby="checkboxLabel"></span><label id="checkboxLabel"></label></div>
<div class="link">Another link to another dummy link</div>
Why is this? Is it because the pseudo elements don't have a name attribute or something like that?
I have tried a different way, by dropping the pseudo elements and trying to change the span innerHTML depending on whether the class 'is-clicked' exists or not, but although I can get the pause character to display initially, it won't change the innerHTML to the play character when the span is clicked again.
Short Answer
This is a warning rather than an error, it is telling you to check that the item actually is interactive.
Now you have got the interactivity on the element so you can ignore that issue.
Long answer
Why not just use a <input type="checkbox"> and save yourself an awful lot of extra work?
You can hide a checkbox with a visually hidden class.
This then allows you to do the same trick with a pseudo element as the visual representation of the state.
I have made several changes to your example that mean you don't have to worry about capturing keypresses etc. and can just use a click handler so your JS is far simpler.
Notice the trick with the label where I add some visually hidden text within it so the label is still visible (so we can still use psuedo elements!).
I then use #checkbox1 ~ label to access the label with CSS so we can change the state.
The final thing to notice is how I changed the content property slightly. This is because some screen readers will try and read out pseudo elements so I added alt text that was blank. Support isn't great at just over 70%, but it is worth adding for browsers that do support it.
Example
The below hopefully illustrates a way of achieving what you want with a checkbox.
There may be a few errors as I just adapted your code so please do not just copy and paste!
note: a checkbox should not work with Enter, only with Space. If you want it to work with both it should instead be a toggle switch etc. so that would be a completely different pattern.
let checkboxEl = document.getElementById('checkbox1');
let labelEl = document.querySelector('#checkboxLabel');
function toggleCheckbox() {
let isChecked = checkboxEl.classList.contains('is-checked');
checkboxEl.classList.toggle('is-checked', !isChecked);
checkboxEl.setAttribute('aria-checked', !isChecked);
}
checkboxEl.onclick = function handleClick() {
toggleCheckbox();
}
.link {
height: auto;
border: 1px solid #000;
margin-bottom: 1rem;
width: 80%;
display: block;
}
#carousel-checkbox {
margin-bottom: 1rem;
height: 50px;
width: 100px;
display: inline-block;
}
.visually-hidden {
border: 0;
padding: 0;
margin: 0;
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 - a 0 height clip, off to the bottom right of the visible 1px box */
clip: rect(1px, 1px, 1px, 1px); /*maybe deprecated but we need to support legacy browsers */
clip-path: inset(50%); /*modern browsers, clip-path works inwards from each corner*/
white-space: nowrap; /* added line to stop words getting smushed together (as they go onto seperate lines and some screen readers do not understand line feeds as a space */
}
#carousel-checkbox label {
display: inline-block;
vertical-align: middle;
}
#carousel-checkbox #checkbox1 {
position: relative;
top: 0;
left: 30px;
padding: 0.5rem 1rem;
background: rgba(255,255,255, 0.5);
}
#carousel-checkbox #checkbox1 ~label:hover {
cursor: pointer;
}
#carousel-checkbox #checkbox1:focus ~ label {
border: 1px dotted #333;
}
#carousel-checkbox #checkbox1 ~label::after {
content: "⏸" / "";
font-size: 1.5rem;
color: #000;
}
#carousel-checkbox #checkbox1.is-checked ~label::after {
content: "▶" / "";
}
<div class="link">A bit of text with a dummy link to demonstrate the keyboard tabbing navigation. </div>
<div id="carousel-checkbox">
<input type="checkbox" id="checkbox1" class="visually-hidden">
<label for="checkbox1" id="checkboxLabel">
<span class="visually-hidden">Pause animations</span>
</label>
</div>
<div class="link">Another link to another dummy link</div>
In the end, I gave up on using a checkbox, due to the difficulties with iPad/iOS not responding to checkbox events. Whilst it worked in codepen on iOS it wouldn't work on the actual site. So I switched to a button.
Here is the code, which is fully accessible with no 'interactive semantics' warnings, shown with some dummy slides. The animation is based on having only three slides. If you wanted more or less, then the timings would have to be adjusted accordingly. All I need now is to style the pause button.
let element = document.getElementById("pause");
function toggleButton() {
element.classList.toggle("paused");
if (element.innerHTML === "⏸") {
element.innerHTML = "▶";
}
else {
element.innerHTML = "⏸";
}
}
element.onclick = function handleClick() {
toggleButton();
}
#carousel {
height: auto;
max-width: 1040px;
position: relative;
margin: 4rem auto 0;
}
#carousel > * {
animation: 12s autoplay6 infinite linear;
position: absolute;
top: 0;
left: 0;
opacity: 0.0;
}
#carousel .one {
position: relative;
}
.homeSlides {
height: 150px;
width: 400px;
background-color: #ff0000;
}
.homeSlides.two {
background-color: #0fff00;
}
.homeSlides.three {
background-color: #e7e7e7;
}
#keyframes autoplay6 {
0% {opacity: 0.0}
4% {opacity: 1.0}
33.33% {opacity: 1.0}
37.33% {opacity: 0.0}
100% {opacity: 0.0}
}
#carousel > *:nth-child(1) {
animation-delay: 0s;
}
#carousel > *:nth-child(2) {
animation-delay: 4s;
}
#carousel > *:nth-child(3) {
animation-delay: 8s;
}
#carousel-button {
position: relative;
height: 100%;
width: auto;
}
#carousel-button button {
position: absolute;
top: -3.5rem;
right: 5rem;
padding: 0 0.5rem 0.25rem;;
background: #fff;
z-index: 98;
font-size: 2rem;
cursor: pointer;
}
body.user-is-tabbing #carousel-button button:focus {
outline: 1px dotted #333;
}
body:not(.user-is-tabbing) #carousel-button button:focus {
outline: none;
}
#carousel-button button:hover {
cursor: pointer;
}
#carousel-button ~ #carousel * {
animation-play-state: running;
}
#carousel-button button.paused ~ #carousel * {
animation-play-state: paused;
}
<div id="carousel-button"><button id="pause" class="">⏸</button>
<div id="carousel">
<div class="homeSlides one">This is div one</div>
<div class="homeSlides two">This is div two</div>
<div class="homeSlides three">This is div three</div>
</div>
</div>

How to use color variable in css file on before/after pseudo selectors?

I'm getting a background-color from an API, variable name settings.brand_color.
I want to use that variable in html element. I cant use style attribute becuase I'm using :before selector in my app.
I want to pass that API variable in my css file and use it in my :before pseudo selector.
JSX
<>
<input
type="radio"
name="language-select"
className="focus:ring-0 mr-5 my-18p default-style radio__input"
/>
<div className="radio__radio"></div>
</>;
CSS
.radio__radio {
width: 24px;
height: 24px;
background-color: #d8d8d8;
border-radius: 50%;
box-sizing: border-box;
padding: 6px;
margin-right: 20px;
z-index: 1;
}
.radio__radio::after {
content: "";
width: 100%;
height: 100%;
display: block;
background: #f28b46;
border-radius: 50%;
transform: scale(0);
z-index: 9;
}
Update
Another solution for this issue is to just use before & after from tailwinds
Pseudo-elements
While you cannot directly set the styling of a pseudo element in JS you can set a CSS variable and this can be picked up by the class setting for the pseudo element.
.radio__radio {
width: 24px;
height: 24px;
background-color: #d8d8d8;
border-radius: 50%;
box-sizing: border-box;
padding: 6px;
margin-right: 20px;
z-index: 1;
--bg: #f28b46; /* ADDED for initial condition */
}
.radio__radio::after {
content: "";
width: 100%;
height: 100%;
display: block;
background: var(--bg);
border-radius: 50%;
transform: scale(0);
z-index: 9;
}
Then in your Javascript when you get a new background color:
document.querySelector('.radio__radio').style.setProperty('--bg', newvalue);
or of course select all such radio buttons and change for each one if that is what is required.
You can use CSS Custom Properties as variables for the colors, using the :root class:
:root {
--brand-color: #f28b46;
}
.radio__radio {
width: 24px;
height: 24px;
background-color: #d8d8d8;
border-radius: 50%;
box-sizing: border-box;
padding: 6px;
margin-right: 20px;
z-index: 1;
}
.radio__radio::after {
content: "";
width: 100%;
height: 100%;
display: block;
background: var(--brand-color);
border-radius: 50%;
// transform: scale(0);
z-index: 9;
}
<div class="radio__radio"></div>
And when fetching the brand color from the API, create a style tag and update the :root brand color.
Note: the last :root variable will override any previous :root variable, so you need to make sure you create the <style> with the brand color after your initial CSS file.
:root {
--brand-color: yellow; // will be overridden
}
:root {
--brand-color: red; // that's the color that will show
}
I got the idea that you're using react, so you can do this like this:
const [brandColor, setBrandColor] = useState();
useEffect( () => {
fetchBrandColorFromAPI().then(brandColor => setBrandColor(brandColor));
}, [])
And then in the renderer:
{brandColor && <style dangerouslySetInnerHTML={{ __html: ` :root {
--brand-color: ${brandColor}
}`}} /> }
The best & easiest possible way is to add style in JSX code.
<input
id={languageLabel}
type="radio"
name="language-select"
value={languageLabel}
// defaultChecked={index === 0}
onChange={() => {
onLanguageChange(language, languageLabel);
}}
className="focus:ring-0 mr-5 my-18p default-style radio__input"
/>
Just add this part to your JSX File
<style>
{`
.radio__radio::before {
background-color: ${settings.brand_color}
}
`}
</style>
The issue is that you can't manipulate pseudo-elements in javascript; however, there are still a couple of options to manipulate them by knock-on effect.
Option 1: As A Haworth suggested, use a CSS variable.
Option 2: If you know there's only going to be a few different colours; then you could just toggle a class indicating which colour it should be. For instance, if you set the CSS up in a similar structure to this:
.radio__radio {
width: 24px;
height: 24px;
background-color: #d8d8d8;
border-radius: 50%;
box-sizing: border-box;
padding: 6px;
margin-right: 20px;
z-index: 1;
}
.radio__radio::after {
content: "";
width: 100%;
height: 100%;
display: block;
border-radius: 50%;
transform: scale(0);
z-index: 9;
}
.radio__radio.green::after{
background-color: #000066 /* Silly colour as an example */
}
.radio__radio.blue::after{
background-color: #006600 /* Silly colour as an example */
}
.radio__radio.red::after{
background-color: #660000 /* Silly colour as an example */
}
Then your javascript
var d = document.getElementsByClassName("radio__radio"); /* This way supports older browsers */
d.className += " otherclass";
Or if usimg jQuery
$('.radio__radio').addClass('green').removeClass('red').removeClass('blue');
There is no way I know of for you to directly inject a runtime variable from your API without using the javascript as a middle-man - there may be a way to do it with Blazor, but I haven't yet come across it.
<!DOCTYPE html>
<html>
<head>
<title>
How to define colors as variables in CSS?
</title>
<style>
:root {
--primary-color: rgb(15, 157, 88);
--secondary-color: rgb(255, 255, 255);
}
.first {
width: 50%;
padding: 40px 0px;
margin: 10px 0px;
text-align: center;
/* Apply color using CSS var */
background-color: var(--primary-color);
color: var(--secondary-color);
}
.second {
width: 50%;
padding: 40px 0px;
text-align: center;
/* Apply color using CSS var */
background-color: var(--primary-color);
color: var(--secondary-color);
}
</style>
</head>
<body>
<div class="first">
<h1>Stackoverflow</h1>
</div>
<div class="second">
<h1>gyan-js</h1>
</div>
</body>
</html>
I'm new to React so, I'll provide the answer with Vannila JS.
The color change can be done in the following steps:
Set a root css variable :root{ --myColor: #545454; }
Set the DOM element's color to the css variable declared in the root like color: var(--myColor);
Since, you mentioned that the element is not loaded yet so there is not point in what color this myColor has because it has not effect except the variable itself because we will use it in JS to change it.
In JS, Get the Color from the API response and store it in a variable
Use document.documentElement to set the color of the css variable myColor with the color we get from the API
All the elements with the color of the CSS variable will also change.
The Element which gets loaded will have the color by then.
// I couldn't find a fake API response giving a Color, so this function mocks the API which gives the color string after 2 seconds.
let getColorFromAPI = new Promise((resolve) => {
setTimeout(function() {
resolve('#FFFFFF')
}, 2000)
});
async function main() {
console.log("The Existing Color is: ", getComputedStyle(document.documentElement).getPropertyValue('--mainColor'))
console.log('Getting the Color from the API... ')
let newColor = await getColorFromAPI // Get the color from API
console.log('The New Color is: ', newColor)
document.documentElement.style.setProperty('--mainColor', newColor) // Changing the color of the CSS variable
}
main()
:root {
--mainColor: #545454;
}
.buttonElement {
background-color: var(--mainColor);
}
<button class="buttonElement">See the Color of this button</button>
To Wrap things up:
The function gets the color from the API and we set the color using document.documentElement.style.setProperty
You can also create a dummy class with just the background-color and append it to the element since, Browser computes the style with the latest CSS style declaration.
Hope this helps.
I had a similar problem one time that I actually solved by using another div element instead of the pseudo element. I apologize if that doesn't work for your specific use case, since you said you wanted to use the pseudo element. However, since it seems like you have access to the JS, JSX, and CSS, it might be something you could consider.
The before and after pseudo elements are almost equivalent to div elements placed as the first or last child of the parent element so adding another div like this
<div className="radio__radio">
<div
className="radio__radio__after"
style={{ backgroundColor: apiColor || '#f28b46' }}
></div>
</div>
and changing your second CSS selector like this
.radio__radio__after {
content: "";
width: 100%;
height: 100%;
display: block;
border-radius: 50%;
transform: scale(0);
z-index: 9;
}
to allow the background color to be controlled by the style prop should work - although you might need to make some slight adjustments to the CSS or JSX.

Is there a way to make the transition property work for a javascript selected item?

Is there a way to have a smooth transition between two states of an element if javascript is selector is used? For example, I have an element with the class of click__box and the id of clickBox. I can set the opacity from 0 to 1 when the button is clicked by using JS. The problem is that transition property has no effect at all. I know that it can be used something like the checkbox hack with pure css but i would like to know if there is a way of doing this with JavaScript.
//CSS
.click__box {
width:100%;
height:100%;
opacity:0;
transition:all .5s;
}
//JS
const collectionButton = document.querySelector("#collectionButton")
var clickBoxStyle = document.getElementById("clickBox").style
collectionButton.addEventListener('click', (e) => {
clickBoxStyle.opacity = "1"
})
It works well.
const collectionButton = document.querySelector("#collectionButton")
var clickBoxStyle = document.getElementById("clickBox").style
collectionButton.addEventListener('click', (e) => {
clickBoxStyle.opacity = "1"
})
.click__box {
width: 100%;
height: 100%;
opacity: 0;
transition: all .5s;
background-color: GREEN;
}
#collectionButton {
width: 150px;
height: 50px;
background-color: red;
cursor: pointer;
}
.container {
position: relative;
width: 150px;
height: 200px;
background-color: blue;
cursor: pointer;
}
<div id="collectionButton">
collectionButton click me
</div>
<div class="container">
Click Box Container
<div id="clickBox" class="click__box">
Click Box
</div>
</div>
Demo for you pal https://codepen.io/init1/pen/mddKgyw

How to undo an addEventListener?

I want to create an effect where if I hover over a certain element a paragraph element will be gradually displayed and vice versa (If the cursor is no longer hovering on the element the paragraph should gradually fade). I've already created the effect using pure CSS, but it was a bit cumbersome and it will only work if the paragraph is a direct child of the element I'm hovering on (which made it even more cumbersome). But here's how I created using CSS:
* {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent;
}
body {
overflow: hidden;
}
.FlexContainerRow {
display: flex;
flex-direction: row;
justify-content: center;
z-index: 1;
}
.FlixItem_Images {
width: 50rem;
}
#CheiftianTwo {
-webkit-transform: scaleX(-1);
transform: scaleX(-1);
}
#welcome {
position: absolute;
z-index: 2;
font-family: Calibri;
font-weight: bold;
font-size: 2em;
text-align: center;
transition: background-color color linear;
transition-duration: 1s;
color: transparent;
background-color: transparent;
margin-left: 13.75em;
margin-top: 6.4em;
padding: 0.2em;
border-radius: 0.4em;
}
#divForLayers {
position: absolute;
z-index: 1;
}
#divForhover {
height: 33.5em;
width: 100rem;
position: absolute;
z-index: 3;
}
#divForhover:hover #welcome {
transition: background-color color linear;
color: white;
background-color: black;
transition-duration: 1s;
}
<header>
<div id="divForhover">
<div id="divForLayers">
<div id="HeaderImagesContainer" class="FlexContainerRow">
<div>
<img src="https://www.nexusindustrialmemory.com/wp-content/uploads/2017/04/OriginalTank.jpg" class="FlixItem_Images" id="CheiftianOne" />
</div>
<div>
<img src="https://www.nexusindustrialmemory.com/wp-content/uploads/2017/04/OriginalTank.jpg" class="FlixItem_Images" id="CheiftianTwo" />
</div>
</div>
</div>
<p id="welcome">Welcome to te Cheftian Mk.2 Main Battle Tank guide!</p>
</div>
</header>
<nav></nav>
<footer></footer>
But I've just learned that you can do the same thing with JavaScript and it will be much much simpler:
addEventListner('mouseover', function(evt) {
document.body.querySelector( /*ID_of_the_element*/ ).style.property = 'value';
})
The problem is that I only know how to to display the paragraph when the user hovers on the element, and that's it. If the cursor is no longer on the element, the paragraph will still be displayed. I don't know how to undo the addEventListener. I tried to do it with removeEventListener, but apparently I have the syntax wrong. Please tell me how to do it.
Here's the version with the JavaScript:
document.querySelector("#welcome").style.visibility = "hidden";
var imgOne = document.body.querySelector("#CheiftianOne");
imgOne.addEventListener('mouseover', function(evt) {
var textBox = document.querySelector("#welcome");
textBox.style.visibility = "visible";
});
imgOne.removeEventListener('mouseover', function(evt) {
var textBox = document.querySelector("#welcome");
textBox.style.visibility = "hidden";
});
* {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent;
}
body {
overflow: hidden;
}
.FlexContainerRow {
display: flex;
flex-direction: row;
justify-content: center;
z-index: 1;
}
.FlixItem_Images {
width: 50rem;
}
#CheiftianTwo {
-webkit-transform: scaleX(-1);
transform: scaleX(-1);
}
#welcome {
position: absolute;
z-index: 2;
font-family: Calibri;
font-weight: bold;
font-size: 2em;
text-align: center;
transition: background-color color linear;
transition-duration: 1s;
color: white;
background-color: black;
margin-left: 13.75em;
margin-top: 6.4em;
padding: 0.2em;
border-radius: 0.4em;
}
#divForLayers {
position: absolute;
z-index: 1;
}
<header>
<div id="divForhover">
<div id="divForLayers">
<div id="HeaderImagesContainer" class="FlexContainerRow">
<div>
<img src="https://www.nexusindustrialmemory.com/wp-content/uploads/2017/04/OriginalTank.jpg" class="FlixItem_Images" id="CheiftianOne" />
</div>
<div>
<img src="https://www.nexusindustrialmemory.com/wp-content/uploads/2017/04/OriginalTank.jpg" class="FlixItem_Images" id="CheiftianTwo" />
</div>
</div>
</div>
<p id="welcome">Welcome to te Cheftian Mk.2 Main Battle Tank guide!</p>
</div>
</header>
<nav></nav>
<footer></footer>
Assign the event handler function to a variable, or give it a proper name. Then add and remove that.
Your removeEventListener call is failing because you're passing it a unique function.
Also, you actually don't want to undo the event listener to achieve the effect you want. Instead, listen to separate events: mouseover and mouseout. For example:
var btn = document.getElementById('btn');
var par = document.getElementById('par');
btn.addEventListener('mouseover', function (e) {
par.style.visibility = 'visible';
});
btn.addEventListener('mouseout', function (e) {
par.style.visibility = 'hidden';
});
<button id="btn">Hover over me</button>
<p id="par" style="visibility: hidden;">This shows when hovering over the button</p>
The mouseover event occurs when the mouse hovers over an element, and conversely the mouseout event occurs when the mouse leaves the element.
When you call removeEventListener, you have to pass it the same function you passed addEventListener, not a different-but-equivalent one. This will never remove a listener:
imgOne.removeEventListener('mouseover', function (evt) { /* ... */ });
...because by definition, that exact function wasn't ever added previously.
Remember the one you used when adding, and use that same one when removing.
Separately: Adding the handler and then immediately removing it doesn't make a lot of sense. Nothing can happen that will trigger the handler between the calls to addEventListener and removeEventListener in your code. (Edit: Ah, rossipedia has picked up on why you did that, and his answer tells you want to do instead.)
Thanks, everyone. I figured out how to do it without a removeEventListener. (I used two addEventListener).
Thanks, again!

Categories