Reputation: 23
I tried this but it doesn't work. Each text element should change the corresponding image.
In the browser console city_name
appears as html collections
let city_name = document.getElementsByClassName("city_name");
let city_img = document.getElementsByClassName("city_img");
for (let i = 0; i < city_name.length; i++) {
city_name[i].addEventListener("mouseover", blur(i))
}
function blur(i) {
city_img[i].style.filter = "blur(4px)"
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css">
<script src="API.js"></script>
<title>WeatherLike</title>
</head>
<body>
<div class="top_city">
<div class="city">
<img src="milano.jpg" class="city_img">
<h1 class="city_name">Milano</h1>
</div>
<div class="city">
<img src="torino.jpg" class="city_img">
<h1 class="city_name">Torino</h1>
</div>
<div class="city">
<img src="bologna.jpg" class="city_img">
<h1 class="city_name">Bologna</h1>
</div>
<div class="city">
<img src="firenze.jpg" class="city_img">
<h1 class="city_name">Firenze</h1>
</div>
<div class="city">
<img src="roma.jpg" class="city_img">
<h1 class="city_name">Roma</h1>
</div>
<div class="city">
<img src="napoli.jpg" class="city_img">
<h1 class="city_name">Napoli</h1>
</div>
<div class="city">
<img src="palermo.jpg" class="city_img">
<h1 class="city_name">Palermo</h1>
</div>
</div>
</body>
</html>
Thanks.
@ChrisG @Adyson yes, ChrisG is right. But "hover the name and the image gets blurry" doesn't work in my HTML page. Maybe for the CSS?
@import url('https://fonts.googleapis.com/css2?family=Bitter:wght@700&display=swap');
*{
margin: 0;
padding: 0;
}
body{
height: 100vh;
}
.top_city{
display: flex;
flex-direction: row;
height: 20vh;
}
.city_img{
background-size: cover;
border: 1px solid lightgrey;
height: 20vh;
}
.city_name{
color: white;
text-align: center;
position: absolute;
width: 14.2%;
margin-top: 55px;
font-family: 'Bitter', serif ;
border: 1px solid rgb(255, 255, 255);
text-shadow: 1px 1px 1px black;
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0, 0.2); /* Black w/opacity/see-through */
}
.city{
overflow: hidden;
display: flex;
width: 16.66%;
}
Upvotes: 1
Views: 101
Reputation: 53
I assume your js script is in the API.js
file, that you have imported in the <head>
section of your HTML file. The problem is that the script is imported and executed during the loading of the page, so it can't see the HTML elements (called by document.getElementsByClassName
function) yet.
You can fix it in many ways:
Import your API.js
script after the HTML elements you need to call:
<div class="top_city">
<div class="city">
<img src="milano.jpg" class="city_img">
<h1 class="city_name">Milano</h1>
</div>
...
</div>
<script src="API.js"></script>
<!-- other code here -->
</body>
Add the async
tag:
<script src="API.js" async></script>
Execute your code during the loading of the page. I think this the best practice:
window.onload = function(){
let city_name = document.querySelectorAll(".city_name");
let city_img = document.querySelectorAll(".city_img");
for (let i = 0; i < city_name.length; i++) {
city_name[i].addEventListener("mouseover", (e)=>{blur(e)})
}
function blur(e) {
e.target.previousElementSibling.style.filter = "blur(4px)"
}
}
See this answer for more details.
Upvotes: 0
Reputation: 66
If you place the name (<h1>
tags) before the image (<img>
), you can reach your event listener only with css and you don't need any javascript code :
h1:hover + img{
filter:blur(4px);
}
Upvotes: 0
Reputation: 66
You have several problems in your code :
let city_name = document.querySelectorAll(".city_name");
let city_img = document.querySelectorAll(".city_img");
for (let i = 0; i < city_name.length; i++) {
city_name[i].addEventListener("mouseover", (e)=>{blur(e)})
}
function blur(e) {
e.target.previousElementSibling.style.filter = "blur(4px)"
}
Upvotes: 2
Reputation: 1107
You need to create a function callback, because now it assume the blur function return a function callback.
Replace the blur(i) with function(){ blur(i); }
let city_name = document.getElementsByClassName("city_name");
let city_img = document.getElementsByClassName("city_img");
for (let i = 0; i < city_name.length; i++) {
city_name[i].addEventListener("mouseover", function(){ blur(i); });
}
function blur(i) {
city_img[i].style.filter = "blur(4px)";
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>WeatherLike</title>
</head>
<body>
<div class="top_city">
<div class="city">
<img style="height:45px;" src="https://s3.amazonaws.com/pix.iemoji.com/images/emoji/apple/ios-12/256/united-states.png" class="city_img">
<h1 class="city_name">Milano</h1>
</div>
<div class="city">
<img style="height:45px;" src="https://s3.amazonaws.com/pix.iemoji.com/images/emoji/apple/ios-12/256/uruguay.png" class="city_img">
<h1 class="city_name">Torino</h1>
</div>
<div class="city">
<img src="bologna.jpg" class="city_img">
<h1 class="city_name">Bologna</h1>
</div>
<div class="city">
<img src="firenze.jpg" class="city_img">
<h1 class="city_name">Firenze</h1>
</div>
<div class="city">
<img src="roma.jpg" class="city_img">
<h1 class="city_name">Roma</h1>
</div>
<div class="city">
<img src="napoli.jpg" class="city_img">
<h1 class="city_name">Napoli</h1>
</div>
<div class="city">
<img src="palermo.jpg" class="city_img">
<h1 class="city_name">Palermo</h1>
</div>
</div>
</body>
</html>
Upvotes: 1
Reputation: 1870
you likely need an 'id' tag on each image and then reference it in your blur() function.
by the way have you considered using a more structured framework like angular? this entire page could be written like this:
<div class="city" *ngFor="let city of cityList">
<img id="{{city.id}}" src="{{city.img}}" class="city_img">
<h1 class="city_name" (blur)="blurCity(city)">{{city.name}}</h1>
</div>
Upvotes: -2