Why doesn't this script work as expected?
-
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?
-
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?
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 ?
-
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 ?
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 positionconst 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);
});
-
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 positionconst 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);
});
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.
-
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.
correction: no pageLoad as script fires every time page loads anyway!
-
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?
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
-
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?
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).