变量username
和password
不保留其原始值(如脚本标记中所定义)或无法从onclick事件访问,但是进行输出变量的函数调用。似乎变量在该范围内被重新定义,因为即使我没有定义变量,它们也不会被定义。
这似乎是由于变量名为username
和password
,如下面的代码示例所示(usr
和passwd
按预期工作。)< / p>
有理由相信这种行为已被引入最新版本的浏览器,因为较旧的Firefox没有展示它。
以下是可重现的代码示例(在Google Chrome 32 / Firefox 26中测试过 - 但有些用户报告说它不适合他们):
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
var username = "Administrator";
var password = "AdminPass";
var usr = "Jordan";
var passwd = "JordanPass";
function printCredentials() {
$("#out").append("username is: " + username + "<br/>");
$("#out").append("password is: " + password + "<br/>");
$("#out").append("usr is: " + usr + "<br/>");
$("#out").append("passwd is: " + passwd + "<br/>");
}
</script>
</head>
<body>
<a href="#" onclick="printCredentials()">This works</a><br/>
<a href="#" onclick="$('#out').append('username is: ' + username + '<br/>'); $('#out').append('password is: ' + password + '<br/>'); $('#out').append('usr is: ' + usr + '<br/>'); $('#out').append('passwd is: ' + passwd + '<br/>');">But this doesn't (properly)</a><br/>
<div id="out" style="background: yellow"></div>
</body>
</html>
使用jQuery是可选的,常规JS也是如此。
点击第二个链接会按预期打印出usr
和passwd
,但username
和password
为空。奇怪的是,它在Internet Explorer中按预期工作(打印所有字段)。
这里发生了什么?
答案 0 :(得分:5)
以下是您无法看到username
和password
属性的原因
首先,<a>
标记能够解析url
属性中的href
并将解析后的值转换为自己的属性。
注意网址语法<protocol>://<user>:<password>@<host>:<port>/<url-path>
var a = document.createElement('a');
a.setAttribute('href', 'http://john:doe@google.com');
// Do you get the idea now?
a.username // prints "john"
a.password // prints "doe"
就是这样,您的内联onclick
正在针对a
的范围执行,该范围已经定义了username
和password
属性(带有“”值)
+----------------+
| window.username| <-- your "Administrator"
| |
| +------------+ |
| | a.username | | <-- empty by default ""
| +------------+ |
+----------------+
编辑:如果您想查看Chrome的源代码,请在其中定义用户名/密码界面&amp;实施
说明:当我回答这个问题时,我认为每个人都已经知道this
事件中的onclick
关键字和javascript中的Scope
,但看起来像是不够清楚(我的坏)。
此行"is being executed against <a>'s scope"
表示
onclick="alert(username)" === onclick="alert(this.username)"
也就是说,你可以想到onclick
中的任何内容都是一个绑定到<a>
标签的匿名函数,所以
onclick = function() {
log(this); // 1. bound to `<a>` not `window`
log(username); // 2. implies `this.username` unless you explicitly declare 'var username`
}
Javascript范围如何工作,如果它在本地范围内找不到该变量(username
),它将查看它的外部范围window.username
。
希望能让它更清晰。
答案 1 :(得分:3)
这实际上是the HTML5 standard的一部分。指定<a>
元素具有以下DOM接口:
interface HTMLAnchorElement : HTMLElement {
attribute DOMString target;
attribute DOMString download;
attribute DOMString rel;
readonly attribute DOMTokenList relList;
attribute DOMString hreflang;
attribute DOMString type;
attribute DOMString text;
};
HTMLAnchorElement implements URLUtils;
URLUtils
实际上是taken from the URL standard,其行为已定义。这是这些属性实际来自的地方:
[NoInterfaceObject]
interface URLUtils {
stringifier attribute [EnsureUTF16] DOMString href;
readonly attribute DOMString origin;
attribute [EnsureUTF16] DOMString protocol;
attribute [EnsureUTF16] DOMString username;
attribute [EnsureUTF16] DOMString password;
attribute [EnsureUTF16] DOMString host;
attribute [EnsureUTF16] DOMString hostname;
attribute [EnsureUTF16] DOMString port;
attribute [EnsureUTF16] DOMString pathname;
attribute [EnsureUTF16] DOMString search;
attribute URLSearchParams? searchParams;
attribute [EnsureUTF16] DOMString hash;
};
这些DOM属性被定义为getters和setter,它们解析并返回相关值(获取时),并在设置有效值时更改href
值。例如,protocol
简单地定义为:
协议属性必须执行以下步骤:
- 如果网址为空,请返回“
:
”。- 返回方案并且“
醇>:
”连接在一起。
部分(例如“scheme”)取自href
值,该值被解析为有效的URL。
请注意,描述接口的方式称为Web IDL,可以将其视为一种伪代码形式,尽管它实际上已经明确指定under its own specification。
因为它是一个新标准,它最近才实现(这可能解释了为什么这个问题之前没有相关性) - 这只是由Firefox在版本26中实现的。
答案 2 :(得分:1)
虽然我不确定其背后的确切原因,但问题在于您的变量名称'username'和'password'。
如果您更改了变量名称,则一切正常。
除了上述保留字之外,您最好避免使用以下标识符作为JavaScript变量的名称。这些是依赖于实现的JavaScript对象,方法或属性的预定义名称(可以说,有些应该是保留字):... password ... http://www.javascripter.net/faq/reserved.htm
答案 3 :(得分:0)
这是我的小提琴,它起作用:http://jsfiddle.net/kP2EU/2/
我没有允许使用var username和var password,而是将用户名和密码分配为窗口对象window.username
和window.password
的属性,然后在锚标记的onClick事件中使用这些引用。这两种情况都很好。
<强> JS 强>:
window.username = "Administrator";
window.password = "AdminPass";
var usr = "Jordan";
var passwd = "JordanPass";
function printCredentials() {
$("#out").append("username is: " + window.username + "<br/>");
$("#out").append("password is: " + window.password + "<br/>");
$("#out").append("usr is: " + usr + "<br/>");
$("#out").append("passwd is: " + passwd + "<br/>");
}
<强> HTML 强>:
<a href="#" onclick="printCredentials()">This works</a>
<br/> <a href="#" onclick="$('#out').append('username is: ' + window.username + '<br/>'); $('#out').append('password is: ' + window.password + '<br/>'); $('#out').append('usr is: ' + usr + '<br/>'); $('#out').append('passwd is: ' + passwd + '<br/>');">But this doesn't (properly)</a>
<br/>
<div id="out" style="background: yellow"></div>
我仍然找不到任何对chrome环境中任何内容的引用,这些引用说明你不能在锚标记的onClick事件中使用变量名用户名和密码。
更新:http://jsfiddle.net/kP2EU/3/
而不是分配给window.username
和window.password
,它仍使用var username
和var password
,但锚标记引用window.username
和window.password
更新2 : 我正在使用chrome中的开发人员工具并且能够返回到onClick事件堆栈,并且发现用户名和密码是我猜测chrome定义的锚标记的属性。我正在努力弄清楚它的定义在哪里提供链接或更多信息。