自从我在没有jQuery的情况下编写Javascript以来已经有一段时间了,所以请耐心等待。我假设我只是在做一些愚蠢的事情。我有这个函数将链接URL转换为我用我编写的路由器使用的内部表示。
Templater.prototype.replace_links = function() {
this.links = document.getElementsByTagName("a");
for (i = 0; i < this.links.length; i++) {
if (!(this.links[i].getAttribute("href") === this.VOID && this.links[i].getAttribute(this.HREF))) {
this.links[i].setAttribute(this.HREF, this.links[i].getAttribute("href"));
this.links[i].setAttribute("href", this.VOID);
this.links[i].onClick = function(self, link) {
return function() { self.router.go(link.getAttribute(self.HREF)); };
}(this, this.links[i]);
}
}
}
初始化Templater时第一次调用此函数。它第一次正常工作。但是,在我将一些html附加到文档正文后,我第二次运行它。我再次运行它,以防附加的html中也包含链接:
<body>
<!-- arbitrary new html is loaded in here -->
<a href="login">Login</a> <!-- becomes <a href="javascript:void(0)" lite-href="login">Login</a> correctly -->
<a href="home">Home</a> <!-- becomes <a href="javascript:void(0)" lite-href="home">Home</a> correctly -->
</body>
当我在运行该函数但仍然在Templater函数中的console.log(this.links [0],this.links [0] .onClick)之后,我得到了正确的html然后undefined
对于onClick事件:
<a href="javascript:void(0)" lite-href="discover">Discover</a> undefined
当我将相同的内容记录到replace_links范围内的值时,我得到了我期待的内容。即功能显示:
<a href="javascript:void(0)" lite-href="Discover">Discover</a> function () { self.router.go(link.getAttribute(self.HREF)); }
我正在玩它,并尝试了这种方式并得到了同样的东西。
Templater.prototype.replace_links = function() {
this.links = document.getElementsByTagName("a");
for (i = 0; i < this.links.length; i++) {
if (!(this.links[i].getAttribute("href") === this.VOID && this.links[i].getAttribute(this.HREF))) {
(function(self, link) {
link.setAttribute(self.HREF, link.getAttribute("href"));
link.setAttribute("href", self.VOID);
link.onClick = function() { self.router.go(link.getAttribute(self.HREF)); };
})(this, this.links[i]);
}
}
}
在replace_link范围像之前一样结束之后我控制台.log这次我仍然得到:
<a href="javascript:void(0)" lite-href="discover">Discover</a> undefined
我非常感谢任何帮助和/或建议!如果我遗漏了任何有用的信息,请告诉我。
答案 0 :(得分:2)
这里的关键点被视为次要细节。
我将一些html附加到文档正文中
和
this.links [i] .onClick = function(self,link){
我的观点是,如果你改变innerHTML
,我认为这是你“将一些html附加到文档正文中的方式”,浏览器会将DOM对象序列化为HTML,进行字符串连接,然后再次解析它。这会导致新对象不再具有expandos,例如onClick
。 onClick
是自定义属性;无论如何,你可能意味着onclick
。
但是,您的一些更改将被成功序列化和解析,即setAttribute
操作。因此,当您在HTML追加后运行replace_links
时,
if (!(this.links[i].getAttribute("href") === this.VOID && this.links[i].getAttribute(this.HREF)))
check会将链接视为已替换,并且不会再次分配onClick
。
这是一个小提琴,显示了这一点。 http://jsfiddle.net/k9d7b2ds/
答案 1 :(得分:0)
更新:做了一些额外的更改。 onclick事件的默认this
对象始终引用窗口对象。你需要通过关闭。
点击此处查看示例代码: http://jsfiddle.net/y0443fz6/
Templater.prototype.replace_links = function() {
var that = this;
this.links = document.getElementsByTagName("a");
for (i = 0; i < this.links.length; i++) {
if (!(this.links[i].getAttribute("href") === this.VOID && this.links[i].getAttribute(this.HREF))) {
this.links[i].setAttribute(this.HREF, this.links[i].getAttribute("href"));
this.links[i].setAttribute("href", this.VOID);
this.links[i].onclick = function(self, link) {
return function() {
self.router.go(link.getAttribute(self.HREF));
};
}(that, this.links[i]);
}
console.log(this.links[i], this.links[i].onclick);
}
}
希望有所帮助。 GL