示例代码:
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<script language="javascript" type="text/javascript">
function init() {
var nodeList = document.getElementsByTagName("a");
var nodeArr = [];
for( var i = 0; i < nodeList.length; i++) // Copy NodeList to Array
nodeArr.push(nodeList[i]);
for( var i = 0; i < nodeArr.length; i++) // Loop over array
if( nodeArr[i].className == "clickLink" )
nodeArr[i].onclick = clickLink2; // Attach event function
}
window.onload = init; //Attach event function
function clickLink2() {
console.log("this: " + this); //Prints window URL in href
console.dir( this ); //show attributes of anchor
console.log( this.name ); // Prints name attribute
}
function clickLink( elem ) {
console.log( "this: " + this ); //Prints [object Window]
console.dir( this ); // Shows attributes, etc. al of [object Window]
console.log( "name: " + elem.name );
}
</script>
</head>
<body>
<!-- inline -->
<a href="#" name="blah1" onclick="clickLink(this); return false;">Test 1</a>
<a href="#" name="blah2" onclick="clickLink(this); return false;">Test 2</a>
<a href="#" name="blah3" onclick="clickLink(this); return false;">Test 3</a>
<a href="#" name="blah4" onclick="clickLink(this); return false;">Test 4</a>
<hr/>
<!-- not inline -->
<a href="#" name="blah5" class="clickLink">Test 5</a>
<a href="#?t" name="blah6" class="clickLink">Test 6</a>
<a href="#" name="blah7" class="clickLink">Test 7</a>
<a href="#" name="blah8" class="clickLink">Test 8</a>
</body>
</html>
我在firefox中进行了测试,用firebug查看控制台输出.
现在我想知道:
>为什么在clickLink中这会引用窗口对象?
>为什么clickLink2中的这个打印到控制台作为链接的href的值?
>有没有更好的方法将此传递给这样一个不引人注目的附件?你怎么能确定这是指什么?
好的,所以我从这里的答案中得到了一些内容,发现这在某些浏览器中有点古怪.另外,为onclick分配函数与附加不同(但遗憾的是并非所有IE版本都支持参见addEventListener vs attachEvent).由于某些原因,旧的IE也使得在事件触发器函数体内仍然引用窗口对象而不是调用者.所以我使用了event.srcElement.这是一些新的示例代码:
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<script language="javascript" type="text/javascript">
function init() {
var nodeList = document.getElementsByTagName("a");
var nodeArr = [];
for( var i = 0; i < nodeList.length; i++) // Copy NodeList to Array
nodeArr.push(nodeList[i]);
for( var i = 0; i < nodeArr.length; i++) // Loop over array
if( nodeArr[i].className == "clickLink" ) {
var a = nodeArr[i];
if (a.addEventListener) { //IE9, other browsers
a.addEventListener('click', clickLink2); // Attach event function
} else if (a.attachEvent) { //IE6,7,8, etc.
a.attachEvent('onclick', clickLink2 ); // Legacy IE Attach event function
}
a.onclick = function() { return false }; // override default onclick behavior for these anchors so URL is not followed
}
}
window.onload = init; //Attach event function
function clickLink2() {
if( typeof(event) != 'undefined' ) {
elem = event.srcElement; //IE < 8 keeps this as window object
} else {
elem = this;
}
alert( elem.name );
}
function clickLink( elem ) {
alert( elem.name );
}
</script>
</head>
<body>
<!-- inline -->
<a href="#" name="blah1" onclick="clickLink(this); return false;">Test 1</a>
<a href="#" name="blah2" onclick="clickLink(this); return false;">Test 2</a>
<a href="#" name="blah3" onclick="clickLink(this); return false;">Test 3</a>
<a href="#" name="blah4" onclick="clickLink(this); return false;">Test 4</a>
<hr/>
<!-- not inline -->
<a href="#" name="blah5" class="clickLink">Test 5</a>
<a href="#?t" name="blah6" class="clickLink">Test 6</a>
<a href="#" name="blah7" class="clickLink">Test 7</a>
<a href="#" name="blah8" class="clickLink">Test 8</a>
</body>
</html>
解决方法:
1)为什么clickLink会引用窗口对象?
简单地说:clickLink不是事件处理程序,通过向元素添加属性onclick,您将使用本机onclick方法作为调用函数的处理程序.此函数在主范围内声明,因此这指向窗口对象.
要明确:行为类似于:
<p onclick='function(){window.clickLink(this);}'>
使实际的事件处理程序成为匿名函数,而不是clickLink.这就是为什么这将指向窗口:匿名函数也在全局范围内声明,因此clickLink的调用者是窗口.
2)为什么clickLink2中的这个打印到控制台作为链接的href的值?
想想这句话’Javascript允许你操纵DOM,DOM树,所有事件和行为.’在init函数中,操作元素onclick行为. onclick的默认方法被否决,并由clickLink2方法替换为nodeArr [i] .onclick = clickLink2;.
看看它是这样的:所有元素都有一个原型onclick方法,它接受一个参数.在第一种情况下,此参数是一个字符串,其值为clickLink函数的调用.然而,第二种情况是,具有特定类的实例具有其自己的onclick方法,从而推翻了原型的onclick.
我希望这能为你解决一些问题.一旦你掌握了事件,处理程序,方法,原型等背后的基本理念,并且克服了JS的怪癖,这很容易.
3)有没有更好的方法将这个传递给这样一个不引人注目的附件?你怎么能确定这是指什么?
好吧,有点回答上面的问题,不是吗?但无论如何:如果你自己定义一个元素或对象的方法,一般来说,这将指向所有者对象/元素.如果您依赖于html和默认行为,JS将主要关注它自己的业务,这将指向窗口.
我不知道这是否是一个选项,但也许你可以尝试这样的事情:
<a onclick='clickLink'>
这应该是-in理论 – 与init函数做同样的事情
编辑:
上述的替代工作:
<p onclick='clickLink.call(this)'>
Call将p元素定义为clickLink的调用者,使其指向调用该函数的元素.
标签:javascript,this,firebug 来源: https://codeday.me/bug/20190609/1208117.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。