TL;DR 要完成你正在做的事情,你有三个选择:
- 将事件的reference存储在一个全局值中(这是大多数教程 - 例如您引用的 youtube 视频 - 会建议您这样做)。这要求事件在与您存储引用时相同的上下文(即网页)中运行
- 当您将事件的引用存储在 localStorage 中(例如通过名称或键/值查找)时,在要执行事件的页面/上下文中,确保在执行事件之前加载适当的函数和库
- [强烈不推荐] 将 javascript 源代码存储在您的存储中,稍后 eval() [再次重申,请不要这样做]
正如@Josh 和@SaurabhRajpal 所提到的,严格来说,您所要求的在JavaScript 中是不可能的。正如MDN documentation for JSON.stringify 所说,您对JSON.stringify(e) 所做的操作可能会返回undefined 或null:
如果在转换过程中遇到未定义、函数或符号,则将其省略(当在对象中找到时)或审查为 null(当在数组中找到时)。 JSON.stringify 也可以在传递“纯”值时返回 undefined,例如 JSON.stringify(function(){}) 或 JSON.stringify(undefined)。
简而言之,无法将单个函数存储到 localStorage(或任何其他离线存储)中。要解释为什么这是不可能的,请看这个例子:
function foo() {
console.log("a")
}
function bar() {
return foo()
}
如何存储bar() 以供以后使用?为了存储 bar,您还必须存储 foo()。当您考虑引用一个位于或使用大型库(如 jQuery、下划线、D3、图表库等)的函数时,这会变得更加复杂。请记住您的计算机已经将源代码解析为二进制,因此不容易知道如何为每个可能的 if、for 和 switch 语句读取函数以确保所有可能的相关函数和库被保存。
如果您真的想要这样做,您将不得不编写自己的 javascript 解析器,而您真的不想这样做!
那么你有什么选择?首先,在同一页面上执行所有操作,并将对事件的引用存储在全局值中(您在评论中链接到的 youtube 视频使用此方法)。
您的第二个选择是使用事件的引用(而不是事件本身),并确保以后使用该引用的源代码。对于(html)示例:
// on page #1
<script src="path/to/my/js/library.js"></script>
...
<script>
window.addEventListener('beforeinstallprompt', (e) => {
e.preventDefault()
localStorage.setItem('stashed-event', 'before-install')
})
</script>
// later, on page #2:
<script src="path/to/my/js/library.js"></script>
...
<script>
var evt = localStorage.setItem('stashed-event', 'before-install')
if(evt == 'before-install') {
dosomething() // which would be a function in path/to/my/js/library.js
}
// another option here would be to define window listeners for all possible events
// in your library.js file, and then simply build and trigger the event here. for
// more about this, see: this link:
// https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
</script>
最后,您可以存储 javascript 源代码,然后再对其进行 eval()。请,请,请不要这样做。这是不好的做法,可能会导致非常邪恶的事情。但是,如果你坚持:
// on page #1
window.addEventListener('beforeinstallprompt', (e) => {
e.preventDefault()
SomeAjaxFunction("path/to/my/js/library.js", function(responseText) {
localStorage.setItem('stashed-event', {
name: 'before-install',
call: 'beforeInstallFunction()',
src: responseText
})
})
})
// later, on page #2:
var evt = localStorage.setItem('stashed-event', 'before-install')
if(evt) {
console.log("triggering event " + evt.name)
eval(evt.src)
eval(evt.call)
}
就像我说的,这是一个非常糟糕的主意,但它是一种选择。
恕我直言,我认为您试图避免在以后的页面/应用程序/任何内容中包含库或源代码,而 javascript 就是无法以这种方式工作。最好在内存中传递引用,并且只对名称使用键/值存储。其他一切都是一种编码体操,以避免将源代码简单地包含在不需要包含的地方。