如何在没有localStorage的情况下重构
How to refactor w/o localStorage?
我写了一个脚本,每天向网站的访问者显示不同的随机图像。我是一个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,你将如何重构它?
Javascript在这里被用作客户端脚本语言。因此,无论您使用什么客户端(浏览器),您的代码都将依赖于此。您可以尝试cookie、localStorage等,但所有这些都将取决于打开JS代码的浏览器。任何其他浏览器,或者同一个处于私人浏览(隐姓埋名)模式的浏览器,都将无法保持状态。
若在所有浏览器中显示一天相同的图像对您来说很重要,那个么您应该使用一些服务器端语言并维护服务器上的状态。(PHP甚至node.js)
首先,行上的重新分解代码中还有另一个问题
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,但如果你想存储与特定个人而不是特定浏览器相关的信息,你需要某种服务器端解决方案来存储用户的数据,并在需要时加载(例如,在请求登录后)。
要每天获得一个随机图像-所有访客都一样-为什么不忘记本地存储/cookie,只使用一组图像名称?在用javascript编写数组时,只需随机化一次即可。若要获取当天的图像,请使用当前日期递增数组索引。使阵列足够长,如果你再次穿过,你的访客不会注意到当索引达到数组的最大值时,例如使用模
尝试
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"))
}
});
jsfiddlehttp://jsfiddle.net/guest271314/zv9sh7kq/
- 如何在未直接触发的情况下停止事件
- 在不使用JQuery的情况下隐藏DOM中的选定元素
- 在不使用jquery的情况下查找页面中的所有锚点并附加函数
- 在不打开聊天屏幕的情况下制作Zopim-ding代理
- 在不阻止默认行为的情况下检测IE10中的缩放
- 如何在不传递此信息的情况下查找被调用的元素
- 如何在不刷新页面的情况下更新显示框
- 有没有一种方法可以在控制台关闭的情况下让console.log()在IE中记录消息
- JavaScript-在手机上不工作的情况下,在外部单击时隐藏元素
- 在我的情况下,如何进行http请求
- 在不知道深度或父属性的情况下从对象中删除属性
- 在不破坏未定义函数的情况下,对多个视图使用单个js文件
- ROR:如何在不重新加载浏览器的情况下从控制器获取参数
- 如何在不影响其他元素的情况下扩展DIV
- 如何在内联依赖项并将图像转换为dataURI的情况下完全提取网页
- 在不移动内部文本的情况下缩放元素的效果
- 在不设置协议的情况下,使用javascript/jquery更改iframe-src
- 默认情况下折叠和展开嵌套列表
- 在不重构Mongo数据库的情况下,更新嵌入数组中的具有给定ID的对象
- 如何在没有localStorage的情况下重构