我写了一个脚本,每天向网站的访问者显示不同的随机图像。我是一个Javascript noob,所以当我开始工作时,我感到非常自豪。但是,我使用localStorage保存随机变量,因此如果您在同一天访问该页面,您将看到相同的图像。现在我意识到,因为如果您打开不同的浏览器(或不同的计算机),您可以在同一天获得不同的图像。我想让所有用户在一天内看到相同的图片。
但是,每次我重写脚本以摆脱localStorage随机,我的代码中断,我无法弄清楚原因。就像我说的那样,我正在学习Javascript,所以我想我只是缺少一些对于更高级的人来说可能很明显的基本知识。任何人都可以帮助我吗?
以下是可行的代码,但取决于localStorage:
var now = new Date();
var day = now.getDay();
var checkDay = localStorage.getItem('day');
var checkRandom = localStorage.getItem('random');
function Random(){
var random = [Math.floor(Math.random()*846+1)];
localStorage.setItem('random', JSON.stringify(random));
}
//If user has never visited before, define random.
if (checkRandom === null) {
Random();
}
(function() {
//If user has never visited before or if it's a different day,
//remove old random, reroll, append to div, set localStorage day.
if ( checkDay === null || checkDay != day) {
(function() {
localStorage.removeItem('random');
Random();
var today = JSON.parse(localStorage.getItem('random'));
image = '<img src=\"' + today + '.png\">';
$(image).appendTo($('#result'));
localStorage.removeItem('day');
localStorage.setItem('day', JSON.stringify(day));
})();
} else {
//Else will fire if user visits on the same day.
//Retrieve previous random and append to div.
var today = JSON.parse(localStorage.getItem('random'));
image = '<img src=\"' + today + '.png\">';
$(image).appendTo($('#result'));
}
})();
这是我尝试重构代码以完成相同的操作但是随机避免localStorage。但是,这仍然告诉我的var random在else语句中是未定义的。我无法弄清楚为什么它看起来与原版基本相同。
var now = new Date();
var day = now.getDay();
var checkDay = localStorage.getItem('day');
var setDay = localStorage.setItem('day', JSON.stringify(day));
function Random(){
var random = [Math.floor(Math.random()*846+1)];
}
if (checkDay === null) {
Random();
}
(function() {
if ( checkDay != day) {
(function() {
Random();
image = '<img src=\"' + random + '.png\">';
$(image).appendTo($('#result'));
localStorage.removeItem('day');
setDay;
})();
} else {
image = '<img src=\"' + random + '.png\">';
$(image).appendTo($('#result'));
}
})();
我做错了什么,如果没有localStorage,你会如何重构这个?
答案 0 :(得分:1)
这里的Javascript被用作客户端脚本语言。因此,无论您使用哪种客户端(浏览器),您的代码都将依赖于此。您可以尝试使用cookies,localStorage等,但所有这些都依赖于打开JS代码的浏览器。任何其他浏览器或隐私浏览(隐身)模式下的同一个浏览器都无法维持状态。
如果在所有浏览器中显示相同图像一天对您来说很重要,则应使用某种服务器端语言并在服务器上维护状态。 (PHP甚至node.js)
答案 1 :(得分:0)
首先,您的重新分解代码中存在另一个问题
var setDay = localStorage.setItem('day', JSON.stringify(day));
这不会神奇地创建对该代码的引用,因此您可以稍后(通过实际尝试)在if语句中通过其名称调用它来运行它,而是存储该函数调用的返回值。您也不需要对其进行字符串化,因为Date().getDay()
将返回一个数字,并且在添加到localStorage
时默认情况下会转换为字符串。只需将该行包装在一个函数中并像这样调用它:
var setDay = function(){ localStorage.setItem('day', day) };
setDay();
至于问题的第二部分(random
是undefined
),问题与JS中的作用域方式有关。通过在该函数中定义random
,您只允许函数内部的东西使用它。如果您希望在函数外部访问它,请在它之外定义它。哦,顺便说一句,您可以在使用var
:
var now = new Date(),
day = now.getDay(),
checkDay = localStorage.getItem('day'),
setDay = function(){ localStorage.setItem('day', day) },
random;
这将在代码的主范围中定义random
变量,允许您在整个脚本中使用它。只需从将随机数分配给变量的函数内部删除var
即可。最后,不要在数字周围使用[]
(方括号),因为这会创建一个数组。它之前工作的唯一原因是,如果数组看起来像"a,b,c,d"
,那么当字符串化时,数组会变为["a","b","c","d"]
。具有单个元素的数组不会在其中包含逗号,这使得您以前的代码可以正常工作,尽管它不正确。
function Random(){
random = Math.floor(Math.random()*846+1);
}
需要注意的是,您无法在所有已自动安装的浏览器上识别用户。尝试执行此操作,例如evercookie,但如果您要存储与特定人员相关的信息而不是特定浏览器,则您需要某种服务器端解决方案来存储用户和#39; s数据并在需要时加载(例如,在请求登录之后)。
答案 2 :(得分:0)
要获取每日随机图像 - 所有访问者都一样 - 为什么不忘记本地存储/ cookie并只使用一组图像名称? 在javascript中编写数组时,您只需随机化一次。 要获取当天的图像,请使用当前日期递增数组索引。 使阵列足够长,如果再次运行,访问者将不会注意到它 当索引达到阵列的最大值时 - 例如使用modulo
答案 3 :(得分:0)
尝试
var images = [{
"01": "image1.png"
}, {
"02": "image2.png"
}, {
"03": "image3.png"
}, {
"04": "image4.png"
}, {
"05": "image5.png"
}, {
"06": "image6.png"
}, {
"07": "image7.png"
}, {
"08": "image8.png"
}, {
"09": "image9.png"
}, {
"10": "image10.png"
}, {
"11": "image11.png"
}, {
"12": "image12.png"
}, {
"13": "image13.png"
}, {
"14": "image14.png"
}, {
"15": "image15.png"
}, {
"16": "image16.png"
}, {
"17": "image17.png"
}, {
"18": "image18.png"
}, {
"19": "image19.png"
}, {
"20": "image20.png"
}, {
"21": "image21.png"
}, {
"22": "image22.png"
}, {
"23": "image23.png"
}, {
"24": "image24.png"
}, {
"25": "image25.png"
}, {
"26": "image26.png"
}, {
"27": "image27.png"
}, {
"28": "image27.png"
}, {
"29": "image29.png"
}, {
"30": "image30.png"
}, {
"31": "image31.png"
}];
// day of month / today
var now = new Date().toJSON().split("-").slice(-1)[0].slice(0, 2);
$.each(images, function (k, v) {
if (now in v) {
$("<img>", {
"src": v[now]
})
.appendTo($("#result"))
}
});