使用JavaScript设置<a>的onclick

3

我想修改一个div中的所有链接,使它们不再指向一个页面,而是在被点击时运行一个JavaScript函数。为此,我编写了以下函数:

function buildPageInDiv(htmlString){
    console.log(typeof htmlString);
    $div = $(htmlString).children("div#myDiv");
    $div.children("a").each(function(i, element){toJavascriptLinks(element)});
    document.getElementById("targetDiv").innerHTML = $div[0].innerHTML;
}

调用此函数:

function toJavascriptLinks(element){
    element.href="#";
    element.onclick     = function(){console.log('Yeah!')};
    console.log(element);
}

现在,当我运行 buildPageInDiv 时,在控制台上会打印出 'string',所有的“href”都被更改为“#”,并且对于
中的每个<a>元素,控制台都会打印该元素。
 <a href="#">

这里没有任何 onclick 的迹象,点击链接并不会在控制台上显示任何内容。

我错过了什么吗?

编辑:

我找错地方了。问题是我在将 innerHTML 附加到 targetDiv 之前运行了 toJavascriptLinks(element)。对于 href 属性来说,这不是问题,但对于 onclick 属性来说是个问题。解决方案很简单,先把它放在 targetDiv 中,然后在 targetDiv 上运行 toJavascriptLinks(element)

function buildPageInDiv(htmlString){
    console.log(typeof htmlString);
    var content = $(htmlString).children("div#myDiv")[0].innerHTML;
    document.getElementById("targetDiv").innerHTML = content;
    $("div#targetDiv").children("a").each(function(i, element) toJavascriptLinks(element)});
}

尽管我最初发布的代码没有问题,但下面详细的回答使我找到了解决方案。
5个回答

6

首先:jQuery中所有类型的选择器都以美元符号和括号开头:$()
其次:您需要使用;来结束语句。
最后:最好在调用函数之前定义它们,而不是依赖javascript将它们提升到顶部。这也将使jslint验证通过,而反过来则不行!

因此,您没有错误的代码应该如下:

function toJavascriptLinks(element){
    element.href="#";
    element.onclick     = function(){alert('Yeah!');};
    console.log(element);
}

$('div').children("a").each(function(i, element){toJavascriptLinks(element);});

请参见此示例,了解运行演示。

祝好运!


关于您更新的问题:
您的问题更新得很全面。

您在控制台中看不到onclick事件,因为您在dom中设置了onclick事件。如果您想在控制台中看到onclick事件,您需要使用以下方式添加函数字符串:
element.setAttribute('onclick', 'your function string');

假设您的html代码如下:

<a id="link_a" href="http://www.google.com">link 1</a>
<a id="link_b" href="http://www.duckduckgo.com">link 2</a>

您有以下 JavaScript 代码:

var lnkA=document.getElementById("link_a");
var lnkB=document.getElementById("link_b");

lnkA.onclick=function(){alert(this.innerHTML);};
lnkB.setAttribute('onclick','alert(this.innerHTML);');

console.log(lnkA.outerHTML);
console.log(lnkB.outerHTML);

然后 console.log 将包含:

<a id="link_a" href="http://www.google.com">link 1</a>
<a onclick="alert(this.innerHTML);" id="link_b" href="http://www.duckduckgo.com">link 2</a>

请参考此处的实时示例(点击)。我认为您可能已经在使用某种形式的jQuery(即使您不知道),因为您使用了.children("div#myDiv")。据我所知,这不是纯粹的JavaScript。我认为无论是普通的JavaScript还是jQuery都不会从HTML字符串中选择具有id“myDiv”的那些div元素,因此您更新后的代码将无法完成任务。最后,要调整我的答案以满足您对onclick事件在解析的HTML源中可见的更新问题和期望:
var htmlString='<div id="myDiv"><a href="http://www.google.com">link 1</a><a href="http://www.duckduckgo.com">link 2</a></div><div id="otherDiv"><a href="http://www.asdf.com">link 3</a><a href="http://www.yahoo.com">link 4</a></div>';

function toJavascriptLinks(element){
    element.href="#";
    element.setAttribute('onclick','console.log("Yeah!");');
    console.log(element.outerHTML);
}

//no innerHTML on documentFragment allowed, yet on it's children it's allowed
var frag = document.createDocumentFragment().appendChild( document.createElement('div') );
frag.innerHTML=htmlString;

var $div = $(frag).children('div#myDiv');

$($div).children("a").each(function(i, element){toJavascriptLinks(element);});


var outp=document.getElementById("output");
outp.innerHTML=frag.innerHTML;

请查看这个更新的范例了解实际效果。

这引出了一个问题:你为什么要在变量名前面放置“忍者”美元符号?


谢谢你的回答,但是我还是不太清楚。在 $div 之前,有一行代码:var $div = $(htmlResponse).children("div#idOfDiv"); 这里的 htmlResponse 是一个包含 HTML 的变量需要进行解析。我会更新问题的描述。 - Jos
你根本不需要在语句结尾处加分号。 - jocap
@jocap:完全不使用“结束”语句是一个过于笼统的说法,因此是错误的!实际上,“这取决于情况”(对于新手来说太难了)。想一想:功能名称“自动分号插入”已经暗示了(至少有些)分号应该首先存在。有许多例子表明,此功能会失败!同样适用于“编译器”/翻译器:在您想要的内容方面要明确无误,不要让它猜测。还请阅读https://dev59.com/aXRB5IYBdhLWcg3w-8Lo - GitaarLAB
@GitaarLAB:只有一种情况需要使用分号,那就是当你以括号开头的时候。其他情况下,分号完全没有任何变化。对于新手来说并不太难。 - jocap
我同意“at all”这个词很令人困惑。我的意思是要反驳你。 - jocap
显示剩余8条评论

2
那只是调试器显示HTML元素的方式。它不显示所有属性 - 特别是因为您将DOM属性onclick设置为函数引用,无法显示为HTML属性onclick,后者需要一个字符串(如Luc的评论所述)。请尝试使用console.log(element.onclick)代替,它应该显示类似于function() {...}的东西。或者事件处理程序不起作用吗?顺便问一下,您为什么不使用jQuery设置href和处理程序呢?
$div.children("a").attr('href', '#').click(function(){console.log('Yeah!')});

还有一件事:在大多数控制台中,您可以单击<a href="#">,它将显示DOM属性,其中应该包括事件处理程序。

1
element.setAttribute("onclick", "alert('WFM');");(而且据我所知,这不能用JavaScript设置) - Luc
感谢您的回答。我没有使用JQuery的原因是我不是专家,也不知道该怎么做。谢谢您的教导。遗憾的是,您提出的两个方案都没有为我带来解决方案。 - Jos

1

我会真的用 jQuery 来做这个,它非常简单。

​$(function() {
    $("div > a ").attr("href", "#").click(function(e) {
        e.preventDefault();
        doSomething();
    });
});

var doSomething = function() {
    alert("Woah, it works!");
}

请查看以下 jsfiddle 进行实际操作:http://jsfiddle.net/SsXtt/1/

0
你确定元素是正确的吗?这对我来说有效。
<a id="mylink">Test</a>
<script>
    document.getElementById("mylink").onclick = function() {
        alert("Works");
    };
</script>

感谢您的回复。元素看起来是正确的:<a href="#">还没有账户?</a> - Jos

-1

函数需要在字符串内部,尝试添加引号?


匿名函数也可以完成这项工作。此外,仅分配字符串只适用于element.setAttribute()。 - Luc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接