JS DOM zmianą sciezki do pliku w funkcji

0

Próbuje się nauczyć JS DOM i zrobić na stronie pojawienie się jakiś obrazków w zależności od wciśniętego buttona
mniej więcej wygląda to tak:

<h1>Co wyswietlic : </h1>
				<center>
				  <input type="button" onclick="getCar(audi)" value="audi">
                                 <input type="button" onclick="getCar(bmw)" value="bmw">
                                  ......

i wtedy w js wygląda to tak:

var i=1;
function getCar(where){
	
    var x = document.createElement("IMG");
    x.setAttribute("src", "img/"+where+"/"+i+".jpg");
    x.setAttribute("width", "200");
    x.setAttribute("width", "150");

    photos.appendChild(x);
	if(i<=4)
		i++;
	else
		i=1;
	
}

i wtedy np. w folderze jest /img/audi/1.jpg, pozniej 2.jpg itd

I problem pojawia się gdy chcę użyć jednej funkcji do "obsługi" kilku buttonów, czyli gdzie chcę, aby w zależności od buttona, funkcja wykorzystywała inną ścieżkę do zdjęć

4

Nie używaj atrybutów on*. Zamiast tego używaj addEventListener.

Dlaczego nie zapakujesz twoich ścieżek do jakiegoś obiektu?

JSFiddle

const carImages = {
  audi: [
    'img/audi/1',
    'img/audi/2',
    'img/audi/smieszne_audi'
  ],

  bmw: [
    'img/bmw/1',
    'bmw/2016/2',
    'img/bmw/smieszne_bmw'
  ]
};

// W ES6 dostępne są funkcje zwane generatorami
// Zachęcam do poczytania, bo super ficzer
// Ta funkcja robi dokładnie to samo, co twój kodzik:
// var i = 0;
// if(i<=4)
//  i++;
// else
//  i=1;

const carImagesGenerator = function* (brand) {
  let i = 0;
  while(true) {
    yield carImages[brand][i];
    i = i === carImages[brand].length - 1 ? 0 : i + 1;
  }
};

// pobieramy wszystie buttony
// querySelectorAll akceptuje jako parametr selektory CSSowe
// wiec oczwiście mozesz to dowolnie zmienić, np. jakąś klasę
const buttons = document.querySelectorAll('[type=button]');

// iterujemy po wszystkich znalezionych buttonach, żeby dodać
// do nich handler zdarzenia click
buttons.forEach(button => {
  // tworzymy nasz generator obrazków, w zależności od marki jaką trzyma guzik
  // button.value to będzie w Twoim przypadku audi lub bmw
  const generator = carImagesGenerator(button.value);

  button.addEventListener('click', () => {
    // wywołując generator.next() dostaniemy
    // kolejne ścieżki do obrazków
    // a jak dojedziemy do końca tablicy to lecimy od początku :)
    const {value} = generator.next();

    // tutaj możesz dodać logikę dodawania obrazka gdzie tam chcesz
    console.log(value);
  });
});

Zachowując Twój obecny kod możesz go przerobić tak:

const carImages = {
  audi: [
    'img/audi/1',
    'img/audi/2',
    'img/audi/smieszne_audi'
  ],

  bmw: [
    'img/bmw/1',
    'bmw/2016/2',
    'img/bmw/smieszne_bmw'
  ]
};

var i=1;
function getCar(where){
 
    var x = document.createElement("IMG");
   // tutaj zmiana
    x.setAttribute("src", carImages[where][i]);
    x.setAttribute("width", "200");
    x.setAttribute("width", "150");
 
    photos.appendChild(x);
    if(i<=4)
        i++;
    else
        i=1;
 
}
2

@Desu
Pobawiłem się trochę Twoim kodem i wyszło mi coś takiego: https://jsfiddle.net/ma8nrpho/

Co zmieniłem?

  • event bubbling zamiast przypisania listenerów w pętli - prostszy kod, zadziała nawet dla dynamicznie dodawanych butonów,
  • generator operuje tylko na własnych parametrach, dzięki temu jest uniwersalny i łatwy w testowaniu - pure function,
  • iteratory są tworzone w osobnej funkcji, znowu - łatwo przetestować - pure function (kod trochę brzydki, przez to, że JS nie ma niestety metody .map() dla literałów obiektowych),
  • pobieranie elementu display (u Ciebie src) odbywa się raz,
  • dodałem blok dla kodu by uniknąć globalnego scope'a,
  • zamieniłem function expressions na function statements by skorzystać z (chyba jedynej) zalety hoistingu i przerzucić szczegóły implementacyjne na koniec,
  • dodałem dla sportu sztuczkę z modulo w kodzie generatora ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1