如何每周对列表进行混洗并使其在所有设备上保持一致



我想创建一个HTML列表,它将每周洗牌一次,任何访问该网站的人都将查看相同的洗牌列表。搅乱的JavaScript与投票率最高的问题相同,所以我不会在这里发布。

这样做的问题是,打乱的列表在设备之间不一致。我曾试图设置一个计时器来控制脚本何时激活,您可以在此处查看:

var ul = document.querySelector("ul"), // get the list
temp = ul.cloneNode(true); // clone the list
// shuffle the cloned list (better performance)
for (var i = temp.children.length + 1; i--; )
temp.appendChild(temp.children[Math.random() * i |0] );
var weekInMilliseconds = 60*1000; // == 604800000 ms
var lastInfo = parseInt(localStorage.getItem('info'), 10); // either NaN or timestamp
if(isNaN(lastInfo))
lastInfo = 0; // 1970, mind you
// if last info showed earlier than one week ago:
if(lastInfo < (Date.now() - weekInMilliseconds)){
localStorage.setItem('info',Date.now()); // set info date now
ul.parentNode.replaceChild(temp, ul); // copy shuffled back to 'ul' // display your information
}

我的问题是,列表再次不一致,尽管它确实成功地阻止了脚本的激活,直到足够的时间过去,因为HTML没有实际的更改,但如果在间隔之前进行刷新,页面将按照原始HTML中写入的默认、未加掩饰的列表顺序加载。

我对网页设计还很陌生,所以我不确定下一步该做什么,而且我对W3的浏览一直没有结果。任何帮助都将不胜感激,谢谢!

所以随机洗牌是不一致的,因为每次重新加载页面时都会有所不同。为了一致地进行shuffle,您可以尝试创建一个伪随机shuffle逻辑,因此避免在此处使用Math.random()

解释

我们需要创建一个种子,在这种情况下,我们计算日历周指数,并将这个特定的数字与当前年份连接起来,以避免每年重复相同的洗牌行为。

const seed = Math.ceil((new Date().getDay() + 1 + Math.floor((new Date() - new Date(new Date().getFullYear(), 0, 1)) / (24 * 60 * 60 * 1000))) / 7) + new Date().getFullYear();

或更小:

const seed = Math.ceil(((new Date() - new Date(new Date().getFullYear(), 0, 1)) / 86400000 + new Date(new Date().getFullYear(), 0, 1).getDay() + 1) / 7);

我们需要一个";随机的"-类似于这种简单方法的生成器:

const getRandom = () => {
const val = seed / (2 ** 32);
seed = (1664525 * seed + 1013904223) % (2 ** 32);
return val;
}

现在,我们可以开始使用这个问题的链接答案来清除列表中的条目:

for (var i = list.children.length; i >= 0; i--)
list.appendChild(list.children[getRandom() * i | 0]);

代码段

看看这个工作片段,注意列表的顺序每周都会改变:

// create seed that changes every new week and will not repeat since we concat it with the current year
let seed = Math.ceil(((new Date() - new Date(new Date().getFullYear(), 0, 1)) / 86400000 + new Date(new Date().getFullYear(), 0, 1).getDay() + 1) / 7);
// create pseudo random numbers
const getRandom = () => {
const val = seed / (2 ** 32);
seed = (1664525 * seed + 1013904223) % (2 ** 32);
return val;
}
// pseudo shuffel list
const list = document.querySelector('ol');
for (let i = list.children.length; i >= 0; i--)
list.appendChild(list.children[getRandom() * i | 0]);
<ol>
<li>Al Pacino</li>
<li>Bill Gates</li>
<li>Carsten Stahl</li>
<li>David Beckham</li>
<li>Elon Musk</li>
<li>Frank Ocean</li>
</ol>

相关内容

  • 没有找到相关文章

最新更新