I am a newbie in javascript, so be aware. I already searched on this website for a solution of this issue but I was not able to find the working solution. The problem is on my development website: https://famnabuurs.nl (it is on the homepage). I use Wordpress with DIVI and now some javascript. The three columns I created have a similar setup. The columns all have an id so I can manage the behaviour. When you hover over a column some changes should be initiated: background-color of the column should switch to black, stripe background should change from blue to black and the image in the background should grow. That all works for for an individual column. But now I have 3 columns it only works at the last one. What I saw form other issues on this website it will have to do with the definition of my variables, but no idea where to update my script.
My html looks like this, the same for every column except for the id:
<div id='research'>
<div class='textblock'>
.. my text ...
</div>
<div class='myimage koek-achtergrond'>
.. my background image ...
</div>
<div class='myimage koek-stripe'>
.. my other image ...
</div>
</div>
Here is my generic code:
<script>
function mouseover() {
console.log('mouse over this column: ',this.id);
var column = document.getElementById(this.id);
column.style.backgroundColor = 'black';
var stripe = document.getElementById(this.id).getElementsByClassName('koek-stripe')[0];
stripe.classList.add('koek-stripe-hovered');
var background = document.getElementById(this.id).getElementsByClassName('koek-achtergrond')[0];
background.classList.add('koek-transform');
}
function mouseleave() {
console.log('mouse leaves this column: ',this.id);
var column = document.getElementById(this.id);
column.style.backgroundColor = 'var(--primary-blue-color)';
var stripe = document.getElementById(this.id).getElementsByClassName('koek-stripe')[0];
stripe.classList.remove('koek-stripe-hovered');
var background = document.getElementById(this.id).getElementsByClassName('koek-achtergrond')[0];
background.classList.remove('koek-transform');
console.log('classList after leaving: ',background.classList);
}
</script>
In every column I add a short script, where only the columname is changed, in line with the name in the html:
<script>
var columnname = 'research';
columnElement = document.getElementById(columnname);
columnElement.onmouseover = function() {
columnElement.addEventListener('mouseover', mouseover);
}
columnElement.onmouseleave = function() {
columnElement.addEventListener('mouseleave', mouseleave);
}
console.log('kolomdetails: ',columnElement);
</script>
In my opinion it is not relevant to show the css in this case, since the issue refers to the javascript. The problem is that the classes that should be added in the generic script only are applied in the last column. The question is: why do they not remain in de first two columns? I saw some remarks in other threads indicating it is the classical error in Javascript. So I hope this can help me understand variables in a better way.
CodePudding user response:
Consider using event delegation. Here's a minimal reproducable example to work with:
[`mouseover`, `mouseout`].forEach(h => document.addEventListener(h, handle));
function handle(evt) {
const el2Handle = evt.target.closest(
[`.textblock`, `.koek-achtergrond`, `.koek-stripe`]
.find(c => evt.target.closest(c)) );
if (el2Handle) {
el2Handle.style.color = evt.type === `mouseover` ? `red` : ``;
}
}
#research div {
cursor: pointer;
}
<div id='research'>
<div class='textblock'>
.. my text ...
</div>
<div class='myimage koek-achtergrond'>
.. my background image ...
</div>
<div class='myimage koek-stripe'>
.. my other image ...
</div>
</div>
CodePudding user response:
Yeesssss, this works fine. I took the answer as pointed out below and tailored it to my final solution:
<script>
document.addEventListener(`mouseover`, handle);
document.addEventListener(`mouseout`, handle);
function handle(evt) {
const origin = evt.target;
if ([`.koek-textblock`, `.koek-achtergrond`, `.koek-stripe`].find( c => origin.closest('.koek-kolom'))) {
kolom = origin.closest('.koek-kolom');
kolom.style.backgroundColor = evt.type === `mouseover` ? 'black' : ``;
stripe = kolom.getElementsByClassName('koek-stripe')[0];
stripe.style.backgroundImage = evt.type === `mouseover` ? "url('https://famnabuurs.nl/wp-content/uploads/2022/10/stripe_zwart.png')": ``;
backgroundimage = kolom.getElementsByClassName('koek-achtergrond')[0];
backgroundimage.style.transform = evt.type === `mouseover` ? "scale(1.2) translate(-80px, 40px)" : ``;
}
}
</script>
I also added the class 'koek-kolom' to the column so I am sure I find the right parent. If you want you can see the result on https://famnabuurs.nl/afbeelding-hoveren-improved/