Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Web Development
  3. JavaScript
  4. Why doesn't this script work as expected?

Why doesn't this script work as expected?

Scheduled Pinned Locked Moved JavaScript
dockertoolsquestionlounge
7 Posts 4 Posters 10 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    DSB Audio David Sweeney Bear
    wrote on last edited by
    #1

    I'm trying to change the position of a background element on a web page in random increments each time any link on the page is clicked:

    const backgroundElement = document.querySelector('.container');
    const positionXY = [100, 25, 50, 75];

    function randomX(positionXY) {
    return positionXY[Math.floor(Math.random() * positionXY.length)]
    }
    function randomY(positionXY) {
    return positionXY[Math.floor(Math.random() * positionXY.length)]
    }

    document.querySelectorAll("a").forEach(a =>
    a.addEventListener("click", () => {

    backgroundElement.style.cssText = `background-position: ${randomX}% ${randomY}%;`
    alert("x position:" + randomX(positionXY));
    alert("y position:" + randomY(positionXY));
    }
    )
    )

    the alerts show me that the values are being generated correctly, but the background position does not change on click. Any tips? Do I need to create a toggle-state?

    D J C 3 Replies Last reply
    0
    • D DSB Audio David Sweeney Bear

      I'm trying to change the position of a background element on a web page in random increments each time any link on the page is clicked:

      const backgroundElement = document.querySelector('.container');
      const positionXY = [100, 25, 50, 75];

      function randomX(positionXY) {
      return positionXY[Math.floor(Math.random() * positionXY.length)]
      }
      function randomY(positionXY) {
      return positionXY[Math.floor(Math.random() * positionXY.length)]
      }

      document.querySelectorAll("a").forEach(a =>
      a.addEventListener("click", () => {

      backgroundElement.style.cssText = `background-position: ${randomX}% ${randomY}%;`
      alert("x position:" + randomX(positionXY));
      alert("y position:" + randomY(positionXY));
      }
      )
      )

      the alerts show me that the values are being generated correctly, but the background position does not change on click. Any tips? Do I need to create a toggle-state?

      D Offline
      D Offline
      DSB Audio David Sweeney Bear
      wrote on last edited by
      #2

      Silly mistake really... I needed to include the const with the function (as I did in the alerts)...

      backgroundElement.style.cssText = `background-position: ${randomX(positionXY)}% ${randomY(positionXY)}%;`

      This now works, but leads me on to two further questions: 1. what if the two random values are the same as the last two? the, the element would not appear to shift at all. I guess I'd need some kind of conditional setup for that 2. what if there are certain links on my page I do not want to trigger a background shift, what can I do to those links to make sure they are not included in the querySelectorAll Node List ?

      Richard DeemingR 1 Reply Last reply
      0
      • D DSB Audio David Sweeney Bear

        Silly mistake really... I needed to include the const with the function (as I did in the alerts)...

        backgroundElement.style.cssText = `background-position: ${randomX(positionXY)}% ${randomY(positionXY)}%;`

        This now works, but leads me on to two further questions: 1. what if the two random values are the same as the last two? the, the element would not appear to shift at all. I guess I'd need some kind of conditional setup for that 2. what if there are certain links on my page I do not want to trigger a background shift, what can I do to those links to make sure they are not included in the querySelectorAll Node List ?

        Richard DeemingR Offline
        Richard DeemingR Offline
        Richard Deeming
        wrote on last edited by
        #3

        DSB Audio (David Sweeney-Bear) wrote:

        1. what if the two random values are the same as the last two? the, the element would not appear to shift at all. I guess I'd need some kind of conditional setup for that

        If you want to reduce the randomness by preventing it from returning the same values twice in a row, you will indeed need to keep track of the previous values.

        const backgroundElement = document.querySelector('.container');
        const positionXY = [100, 25, 50, 75];
        const currentPosition = { x: 0, y: 0 }; // TODO: Set your initial position

        const randomPosition = (positions) => {
        const result = { };
        do {
        result.x = positions[Math.floor(Math.random() * positions.length)];
        resuly.y = positions[Math.floor(Math.random() * positions.length)];
        } while (result.x === currentPosition.x && result.y === currentPosition.y);

        return result;
        

        };

        const changePosition = (el, positions) => {
        const newPosition = randomPosition(positions);
        el.style.backgroundPosition = `${newPosition.x}% ${newPosition.y}%`;
        console.debug("New position", newPosition, el);
        };

        // Event delegation: https://javascript.info/event-delegation
        document.addEventListener("click", e => {
        let a = e.target;
        if (a.tagName !== 'A') {
        a = e.target.closest("a");
        if (!a) { return; } // The click was not on an element.
        }

        console.debug("Link clicked", a);
        changePosition(backgroundElement, positionXY);
        

        });

        DSB Audio (David Sweeney-Bear) wrote:

        2. what if there are certain links on my page I do not want to trigger a background shift, what can I do to those links to make sure they are not included in the querySelectorAll Node List ?

        You'll need to find some way to identify those links, and exclude them from the event. For example, by using a CSS class:

        document.addEventListener("click", e => {
        let a = e.target;
        if (a.tagName !== 'A') {
        a = e.target.closest("a");
        if (!a) { return; } // The click was not on an element.
        }
        if (a.matches(".class-to-exclude")) {
        return; // The element should be excluded.
        }

        console.debug("Link clicked", a);
        changePosition(backgroundElement, positionXY);
        

        });


        "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

        D 1 Reply Last reply
        0
        • Richard DeemingR Richard Deeming

          DSB Audio (David Sweeney-Bear) wrote:

          1. what if the two random values are the same as the last two? the, the element would not appear to shift at all. I guess I'd need some kind of conditional setup for that

          If you want to reduce the randomness by preventing it from returning the same values twice in a row, you will indeed need to keep track of the previous values.

          const backgroundElement = document.querySelector('.container');
          const positionXY = [100, 25, 50, 75];
          const currentPosition = { x: 0, y: 0 }; // TODO: Set your initial position

          const randomPosition = (positions) => {
          const result = { };
          do {
          result.x = positions[Math.floor(Math.random() * positions.length)];
          resuly.y = positions[Math.floor(Math.random() * positions.length)];
          } while (result.x === currentPosition.x && result.y === currentPosition.y);

          return result;
          

          };

          const changePosition = (el, positions) => {
          const newPosition = randomPosition(positions);
          el.style.backgroundPosition = `${newPosition.x}% ${newPosition.y}%`;
          console.debug("New position", newPosition, el);
          };

          // Event delegation: https://javascript.info/event-delegation
          document.addEventListener("click", e => {
          let a = e.target;
          if (a.tagName !== 'A') {
          a = e.target.closest("a");
          if (!a) { return; } // The click was not on an element.
          }

          console.debug("Link clicked", a);
          changePosition(backgroundElement, positionXY);
          

          });

          DSB Audio (David Sweeney-Bear) wrote:

          2. what if there are certain links on my page I do not want to trigger a background shift, what can I do to those links to make sure they are not included in the querySelectorAll Node List ?

          You'll need to find some way to identify those links, and exclude them from the event. For example, by using a CSS class:

          document.addEventListener("click", e => {
          let a = e.target;
          if (a.tagName !== 'A') {
          a = e.target.closest("a");
          if (!a) { return; } // The click was not on an element.
          }
          if (a.matches(".class-to-exclude")) {
          return; // The element should be excluded.
          }

          console.debug("Link clicked", a);
          changePosition(backgroundElement, positionXY);
          

          });


          D Offline
          D Offline
          DSB Audio David Sweeney Bear
          wrote on last edited by
          #4

          Thanks, I got there in the end, although I had to modify things quite a bit to implement it in my Wordpress site:

          let backgroundElement = document.querySelector('.site-container');
          const positionXY = [16, 32, 48, 64, 80, 99, 66.6, 33.3, 1, 15, 30, 50, 75];
          let storedXY = sessionStorage.getItem('writeXY'); let lastXY = JSON.parse(storedXY);
          if (storedXY == null) {
          let randomX = positionXY[Math.floor(Math.random() * positionXY.length)];
          let randomY = positionXY[Math.floor(Math.random() * positionXY.length)];
          document.querySelector('.site-container').style.cssText = `background-position: ${randomX}% ${randomY}%; background-size: auto;`
          let randomXY = [randomX, randomY]
          sessionStorage.setItem('writeXY', JSON.stringify(randomXY));
          }
          else if (storedXY !== null) {
          let randomX = positionXY[Math.floor(Math.random() * positionXY.length)];
          let randomY = positionXY[Math.floor(Math.random() * positionXY.length)];
          let testX = Math.abs(randomX-lastXY[0]);
          let testY = Math.abs(randomY-lastXY[1]);
          let randomXY = [randomX, randomY]
          sessionStorage.setItem('writeXY', JSON.stringify(randomXY));
          while (testX < 16 || testY < 16) {
          randomX = positionXY[Math.floor(Math.random() * positionXY.length)];
          randomY = positionXY[Math.floor(Math.random() * positionXY.length)];
          testX = Math.abs(randomX-lastXY[0]);
          testY = Math.abs(randomY-lastXY[1]);
          }
          document.querySelector('.site-container').style.cssText = `background-position: ${randomX}% ${randomY}%; background-size: auto;`
          randomXY = [randomX, randomY]
          sessionStorage.setItem('writeXY', JSON.stringify(randomXY));

          I dispensed with the onClick event in favour of pageLoad since within the WP structure, each link is a new page. Therefore, didn't need to exclude certain anchor links, but did find that using 'a: not(".class-name")' worked to exclude links that I assigned a particular classname to.

          D 1 Reply Last reply
          0
          • D DSB Audio David Sweeney Bear

            Thanks, I got there in the end, although I had to modify things quite a bit to implement it in my Wordpress site:

            let backgroundElement = document.querySelector('.site-container');
            const positionXY = [16, 32, 48, 64, 80, 99, 66.6, 33.3, 1, 15, 30, 50, 75];
            let storedXY = sessionStorage.getItem('writeXY'); let lastXY = JSON.parse(storedXY);
            if (storedXY == null) {
            let randomX = positionXY[Math.floor(Math.random() * positionXY.length)];
            let randomY = positionXY[Math.floor(Math.random() * positionXY.length)];
            document.querySelector('.site-container').style.cssText = `background-position: ${randomX}% ${randomY}%; background-size: auto;`
            let randomXY = [randomX, randomY]
            sessionStorage.setItem('writeXY', JSON.stringify(randomXY));
            }
            else if (storedXY !== null) {
            let randomX = positionXY[Math.floor(Math.random() * positionXY.length)];
            let randomY = positionXY[Math.floor(Math.random() * positionXY.length)];
            let testX = Math.abs(randomX-lastXY[0]);
            let testY = Math.abs(randomY-lastXY[1]);
            let randomXY = [randomX, randomY]
            sessionStorage.setItem('writeXY', JSON.stringify(randomXY));
            while (testX < 16 || testY < 16) {
            randomX = positionXY[Math.floor(Math.random() * positionXY.length)];
            randomY = positionXY[Math.floor(Math.random() * positionXY.length)];
            testX = Math.abs(randomX-lastXY[0]);
            testY = Math.abs(randomY-lastXY[1]);
            }
            document.querySelector('.site-container').style.cssText = `background-position: ${randomX}% ${randomY}%; background-size: auto;`
            randomXY = [randomX, randomY]
            sessionStorage.setItem('writeXY', JSON.stringify(randomXY));

            I dispensed with the onClick event in favour of pageLoad since within the WP structure, each link is a new page. Therefore, didn't need to exclude certain anchor links, but did find that using 'a: not(".class-name")' worked to exclude links that I assigned a particular classname to.

            D Offline
            D Offline
            DSB Audio David Sweeney Bear
            wrote on last edited by
            #5

            correction: no pageLoad as script fires every time page loads anyway!

            1 Reply Last reply
            0
            • D DSB Audio David Sweeney Bear

              I'm trying to change the position of a background element on a web page in random increments each time any link on the page is clicked:

              const backgroundElement = document.querySelector('.container');
              const positionXY = [100, 25, 50, 75];

              function randomX(positionXY) {
              return positionXY[Math.floor(Math.random() * positionXY.length)]
              }
              function randomY(positionXY) {
              return positionXY[Math.floor(Math.random() * positionXY.length)]
              }

              document.querySelectorAll("a").forEach(a =>
              a.addEventListener("click", () => {

              backgroundElement.style.cssText = `background-position: ${randomX}% ${randomY}%;`
              alert("x position:" + randomX(positionXY));
              alert("y position:" + randomY(positionXY));
              }
              )
              )

              the alerts show me that the values are being generated correctly, but the background position does not change on click. Any tips? Do I need to create a toggle-state?

              J Offline
              J Offline
              Jeremy Falcon
              wrote on last edited by
              #6

              DSB Audio (David Sweeney-Bear) wrote:

              const positionXY = [100, 25, 50, 75];

              Aside from what was already said, in the interest of readability, you'd be better off using a object (or array of objects) to act as a hash map here.

              const position = { left: 100, top: 25, right: 50, bottom: 75 };
              // used as such
              console.log(position.left);

              const positions = [{ x: 100, y: 25}, { x: 50, y: 75 }];
              // used as such
              console.log(positions[0].x);

              Jeremy Falcon

              1 Reply Last reply
              0
              • D DSB Audio David Sweeney Bear

                I'm trying to change the position of a background element on a web page in random increments each time any link on the page is clicked:

                const backgroundElement = document.querySelector('.container');
                const positionXY = [100, 25, 50, 75];

                function randomX(positionXY) {
                return positionXY[Math.floor(Math.random() * positionXY.length)]
                }
                function randomY(positionXY) {
                return positionXY[Math.floor(Math.random() * positionXY.length)]
                }

                document.querySelectorAll("a").forEach(a =>
                a.addEventListener("click", () => {

                backgroundElement.style.cssText = `background-position: ${randomX}% ${randomY}%;`
                alert("x position:" + randomX(positionXY));
                alert("y position:" + randomY(positionXY));
                }
                )
                )

                the alerts show me that the values are being generated correctly, but the background position does not change on click. Any tips? Do I need to create a toggle-state?

                C Offline
                C Offline
                cat exotica
                wrote on last edited by
                #7

                Script Errors are errors that the browser sends to the onerror callback when they originate from a third-party script. It usually happens when the third-party scripts are from a different origin(different domain, port, or protocol).

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups