0

finally started with JS and I have a question.

Why doesn't this code work (I have two images with fir and sec Ids in HTML)

function swap() {
  let x = document.getElementById("fir").src
  let y = document.getElementById("sec").src

  let z = x
  x = y
  y = z
}

But this one does

function swap() {
  let x = document.getElementById("fir")
  let y = document.getElementById("sec")

  let z = x.src

  x.src = y.src
  y.src = z
}
Orochi
  • 1
  • 1
  • 1
    just a tip: `[x.src, y.src] = [y.src, x.src]` – Endless Dec 01 '20 at 15:26
  • Is that a way to swap two variables without using a third one? – Orochi Dec 01 '20 at 15:33
  • 1
    The first code create a new src variable and change the string value without affecting the element, but the second code create a reference of the element and directly affect the src attribute. – user2258152 Dec 01 '20 at 15:33
  • @Orochi yes it is, you can do it for more than two also `[a,b,c] = [c,b,a]` it's called [Destructuring assignment](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) – Endless Dec 01 '20 at 15:39
  • this is relevant to all those *"[illegal invocations](https://stackoverflow.com/questions/10743596/why-are-certain-function-calls-termed-illegal-invocations-in-javascript)"* you sometimes get... – Endless Dec 01 '20 at 15:42
  • Used this method instead of mine, but it only works when I define the variables outside of the function. – Orochi Dec 01 '20 at 15:49

2 Answers2

2

It's because document.getElementById("fir").src returns the path of the image (string) whereas in the second case you are manipulating the DOM (reference). you can console log or apply break point the output in both cases and check what's happening.

0

The reason the first one doesn't work is that while you have swapped the elements that your variables point to, you haven't changed the elements themselves. There are a couple of ways of swapping the elements (one of which you already posted and test)

  1. Swap source fields
  2. Swap outerHTML (z = x.outerHTML; x = y.outerHTML; y = z.outerHtML)
  3. Move the actual elements (z = x.nextSibling; y.parentNode.insertBefore(x,y); z.parentNode.insertBefore(y,z);

Example 3 actually is incomplete: You'd also need to handle the case where there's no nextSibling. But hopefully this gives you more perspective of what attempt 1 and 2 are doing as well as how to change and manipulate elements

ControlAltDel
  • 33,923
  • 10
  • 53
  • 80