Ell*_*lle 10 html javascript firefox google-chrome
变量username
和password
不保留其原始值(如脚本标签定义)或不能从onclick事件访问,但是做一个函数调用输出变量一样.似乎变量在该范围内被重新定义,因为即使我没有定义变量,它们也不是未定义的.
它似乎是由于变量被命名,username
并且password
如下面的代码示例所示(usr
并按passwd
预期工作).
有理由相信这种行为已被引入最新版本的浏览器,因为较旧的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>
Run Code Online (Sandbox Code Playgroud)
使用jQuery是可选的,常规JS也是如此.
点击第二个链接打印出来usr
,并passwd
如预期,但username
和password
空白.奇怪的是,它在Internet Explorer中按预期工作(打印所有字段).
这里发生了什么?
这是一个细分为什么你看不到username
和password
属性
首先,<a>
tag能够解析url
in href
属性并将解析后的值转换为自己的属性.
注意 URL语法<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"
Run Code Online (Sandbox Code Playgroud)
就是这样,你的内联onclick
是针对a
已经同时具有属性username
和password
属性定义的范围执行的(带有""值)
+----------------+
| window.username| <-- your "Administrator"
| |
| +------------+ |
| | a.username | | <-- empty by default ""
| +------------+ |
+----------------+
Run Code Online (Sandbox Code Playgroud)
编辑:如果你想看到Chrome的源代码,它定义了用户名/密码界面和实现
界面:https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/core/dom/DOMURLUtils.h&l=47&rcl=1391416355
实施:https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/core/dom/DOMURLUtils.cpp&l=48&rcl=1391416355
说明:当我回答这个问题时,我假设每个人都已经知道关于事件和javascript中的this
关键字,但看起来不够清楚(我的不好).onclick
Scope
这条线"is being executed against <a>'s scope"
意味着,
onclick="alert(username)" === onclick="alert(this.username)"
Run Code Online (Sandbox Code Playgroud)
也就是说,你可以想到任何东西onclick
都是一个匿名函数,它必须<a>
标记为
onclick = function() {
log(this); // 1. bound to `<a>` not `window`
log(username); // 2. implies `this.username` unless you explicitly declare 'var username`
}
Run Code Online (Sandbox Code Playgroud)
Javascript范围的工作原理是,如果它username
在本地范围内找不到该变量(),它将查看它的外部范围window.username
.
希望能让它更清晰.
这实际上被定义为HTML5 标准的一部分。该<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;
Run Code Online (Sandbox Code Playgroud)
URLUtils
实际上取自 URL 标准,其中定义了其行为。这就是这些属性的实际来源:
[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;
};
Run Code Online (Sandbox Code Playgroud)
这些 DOM 属性被定义为 getter 和 setter,它们解析并返回相关值(在获取时),并href
在设置有效值时更改该值。例如,protocol
简单地定义为:
协议属性必须运行以下步骤:
- 如果 url 为 null,则返回“
:
”。- 返回方案和“
:
”连接。
这些部分(例如“方案”)取自href
值,该值被解析为有效的 URL。
请注意,描述接口的方式称为Web IDL,它可以被视为一种伪代码形式,尽管它实际上是在其自己的规范下明确指定的。
因为它是一个新标准,所以最近才实现(这可能解释了为什么这个问题之前不相关)——仅由 Firefox 在版本 26 中实现。
归档时间: |
|
查看次数: |
1015 次 |
最近记录: |