javascriptw3c-validationname-attribute

Not sure how to adapt ancient image switcher code from using name="foo" to id="foo"


About 19 years ago, I needed a script that changes images using the onmouseover event. The script used name="foo" which, of course, can no longer be supported by the <img> tag. I've literally forgotten how the script works and I need some help adapting it to use id="foo".

This is the script that lives in my <head>:

<script>
function newImage(arg) {
  if (document.images) {
    rslt = new Image();
    rslt.src = arg;
    return rslt;
  }
}

function changeImages() {
  if (document.images && (preloadFlag == true)) {
    for (var i=0; i<changeImages.arguments.length; i+=2) {
      document[changeImages.arguments[i]].src = changeImages.arguments[i+1];
    }
  }
}

var preloadFlag = false;

function preloadImages() {
  if (document.images) {
    archives_over = newImage("/images/index/menu/archives_over.jpg");
    bio_over = newImage("/images/index/menu/bio_over.jpg");
    poetry_over = newImage("/images/index/menu/poetry_over.jpg");
    preloadFlag = true;
  }
}
</script>

...and this is the HTML that lives in my <body>:

<a href='https://www.foo.com/index.php?page=news'
   onmouseover='changeImages("poetry", "/images/index/menu/poetry_over_static.jpg"); return true;'
   onmouseout='changeImages("poetry", "/images/index/menu/poetry_over_static.jpg"); return true;'
   onmousedown='changeImages("poetry", "/images/index/menu/poetry_over_static.jpg"); return true;'
   onmouseup='changeImages("poetry", "/images/index/menu/poetry_over_static.jpg"); return true;'>
  <img name="poetry" src="/images/index/menu/poetry_over_static.jpg">
</a>

If I change <img name="poetry" to <img id="poetry", the whole thing stops working.


Solution

  • Your

    document[changeImages.arguments[i]]
    

    when the first argument is poetry, accesses document.poetry. Use getElementById instead, to select an element with a particular id:

    function changeImages(id, newSrc) {
      document.getElementById(id).src = newSrc;
    }
    

    You also might consider attaching listeners properly using addEventListener, rather than inline handlers:

    const a = <select your <a> tag here>
    const img = document.getElementById('poetry');
    const fn = () => {
      img.src = '/images/index/menu/poetry_over_static.jpg';
    }
    ['mouseover', 'mouseout', 'mousedown', 'mouseup'].forEach((eventType) => {
      a.addEventListener(eventType, fn);
    });
    

    If you're doing this sort of thing for multiple images on the page, then you can make the code even better by dynamically selecting the <a>'s nextElementSibling, allowing you to avoid IDs entirely:

    const fn = ({ target }) => {
      const img = target.nextElementSibling;
      img.src = '/images/index/menu/poetry_over_static.jpg';
    }
    ['mouseover', 'mouseout', 'mousedown', 'mouseup'].forEach((eventType) => {
      a.addEventListener(eventType, fn);
    });