У меня есть массив, содержащий список машин и URL-адрес изображения.
На странице у меня есть список много автомобилей. Я хочу зациклиться на всех автомобилях на странице, и если он находится внутри массива автомобилей, я хочу поменять его образ на новый.
Какой был бы лучший способ сделать это?
<!-- example of on page list of cars -->
<li class="car" data-id="car1">
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car12">
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car2">
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car7">
<img src="https://imageurl.com/currentImage" alt="">
</li>
-
const cars = [
{
"id": "car1"
"newImage": "imageaddress1"
},
{
"id": "car2"
"newImage": "imageaddress2"
},
{
"id": "car3"
"newImage": "imageaddress3"
},
]
const allCarsNodeList = document.querySelectorAll('.car');
const allCars = Array.from(allProductsNodeList);
Первые соображения состоят в том, чтобы использовать фильтр, чтобы уменьшить количество отображаемых на машинах страниц только тех, которые были показаны, но я теряюсь на том, как сделать сравнение, поскольку ни в массиве, ни в атрибуте данных на странице прямо нет.
Я в основном смущен! Любые точки в правильном направлении были бы весьма полезны.
Перейдите по результатам в списке узлов и сравните идентификатор данных с идентификатором массива автомобилей. Если он совпадает - замените атрибут src на newImage.
Я также обновляю атрибут alt, чтобы вы могли видеть, что src имеет изменения (поскольку у меня нет ваших изображений)
const cars = [
{
"id": "car1",
"newImage": "imageaddress1"
},
{
"id": "car2",
"newImage": "imageaddress2"
},
{
"id": "car3",
"newImage": "imageaddress3"
},
]
const allCarsNodeList = document.querySelectorAll('.car');
allCarsNodeList.forEach(function(car, index){
var id = car.getAttribute('data-id');
var image = car.querySelector('img');
cars.forEach(function(carItem){
if(carItem.id == id) {
image.setAttribute('src', carItem.newImage);
image.setAttribute('alt', carItem.newImage) ;
}
})
})
<ul>
<li class="car" data-id="car1">
<img src="https://imageurl.com/currentImage" alt="currentImage">
</li>
<li class="car" data-id="car12">
<img src="https://imageurl.com/currentImage" alt="currentImage">
</li>
<li class="car" data-id="car2">
<img src="https://imageurl.com/currentImage" alt="currentImage">
</li>
<li class="car" data-id="car7">
<img src="https://imageurl.com/currentImage" alt="currentImage">
</li>
</ul>
Вы можете попробовать следующее
cars
с id
качестве ключа и URL-адресом изображения как значениеsrc
соответствующего img
const cars = [{"id": "car1","newImage": "imageaddress1"},{"id": "car2","newImage": "imageaddress2"},{"id": "car3","newImage": "imageaddress3"}];
// Create a map of id and newImage
const obj = cars.reduce((a,c) => Object.assign(a, {[c.id] : c.newImage}), {});
// Get all cars
const allCars = Array.from(document.querySelectorAll('.car'));
// Iterate over cars
allCars.forEach(c => {
//if entry exists in the object, update corresponding image
if(obj[c.dataset.id]) c.querySelector("img").src = obj[c.dataset.id];
});
<li class="car" data-id="car1">
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car12">
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car2">
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car7">
<img src="https://imageurl.com/currentImage" alt="">
</li>
Эта работа для меня:
const allCarsNodeList = document.querySelectorAll('.car');
const allCars = Array.from(allCarsNodeList);
console.log(allCars)
allCars.forEach(car => {
carId = car.dataset.id
correspondingCar = cars.filter(each => each.id === carId)[0]
console.log(correspondingCar);
if (correspondingCar !== undefined) {
car.children[0].src = correspondingCar.newImage
}
})
Вам необходимо выполнить следующие действия:
car
data-id
данных для каждого элементаdata-id
чтобы найти соответствующий объект в массиве cars
src
этого образа, который находится внутри .car
элемента, с newImage
значением newImage
объекта.
const cars = [{
"id": "car1",
"newImage": "imageaddress1"
},
{
"id": "car2",
"newImage": "imageaddress2"
},
{
"id": "car3",
"newImage": "imageaddress3"
}
]
const allCarsNodeList = document.querySelectorAll('.car');
for (var i = 0; i < allCarsNodeList.length; i++) {
var carId = allCarsNodeList[i].dataset.id;
var matchCar = cars.find(({id}) => carId === id);
if (matchCar) {
allCarsNodeList[i].querySelector('img').src = matchCar.newImage;
}
}
<li class="car" data-id="car1">1
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car12">2
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car2">3
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car7">4
<img src="https://imageurl.com/currentImage" alt="">
</li>
Используйте
inspect element
на выходе, чтобы проверить, что атрибутsrc
фактически изменен значениемnewImage
Поскольку ваши автомобили хранятся в массиве с уникальным идентификатором, я бы рекомендовал сначала преобразовать этот массив автомобилей в словарь (это увеличит производительность):
const cars = [
{
"id": "car1",
"newImage": "imageaddress1"
},
{
"id": "car2",
"newImage": "imageaddress2"
},
{
"id": "car3",
"newImage": "imageaddress3"
}
]
// create cars dictionary from carsList
const carsDictionary = cars.reduce((r, car) => {
r[car.id] = car;
return r;
}, {});
// iterate over nodes with car class
const carNodesDict = Array.from(document.querySelectorAll('.car'))
.forEach((node) => {
const car = carsDictionary[node.dataset.id];
if (car != null) {
node.querySelector('img').src = car.newImage;
}
});
<!-- example of on page list of cars -->
<li class="car" data-id="car1">
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car12">
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car2">
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car7">
<img src="https://imageurl.com/currentImage" alt="">
</li>