Jos
Jos

Reputation: 1089

Set onclick of <a> using JavaScript

I want to change all the links in a div such that they no longer refer to a page, but run a JavaScript function when being clicked. To do so, I wrote this function:

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;
}

calling this function:

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

Now, when I run buildPageInDiv, 'string' is printed on the console, all the "href" are changed to "#" and for every <a> within the div the console prints the element:

 <a href="#">

No sign of the onclick here, and clicking on the link does not show anything on the console.

What am I missing here?

Edit:

I was seeking in the wrong place. The problem was that I was running toJavascriptLinks(element) before attaching the innerHTML to targetDiv. That was no problem for the href attribute, but it was for the onclick attribute. Solution is simply to put it in targetDiv first and than run toJavascriptLinks(element) on targetDiv :

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)});
}

Although the problem was not in the code I originally posted, the comprehensive answers below led me to the solution.

Upvotes: 3

Views: 10025

Answers (5)

GitaarLAB
GitaarLAB

Reputation: 14645

First: All type of selectors in jQuery, start with the dollar sign and parentheses: $()
Secondly: you need to close your statements with ;
Lastly: it is good practice to define your functions BEFORE you call them, instead of relying on javascript to hoist them to the top for you. This will also make jslint validate, whereas the other way round wouldn't!

So your code without your errors would look like:

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

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

See this fiddle for a working demo.

Good Luck!!


ABOUT YOUR UPDATED QUESTION:
That's quite an update to your question.

You don't see your onclick in console.log because you set the onclick event in the dom. If you wanted to see the onclick in console.log, you would add the function STRING using:
element.setAttribute('onclick', 'your function string');

Suppose in your html you have:

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

And you have this 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);

Then console.log will contain:

<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>

See this fiddle for a live example of this explanation.

I also think you are already using some form of jQuery (without you knowing it) because of your use of .children("div#myDiv"). To my knowledge this no plain vanilla javascript. And I think both plain vanilla javascript and jQuery would not select those divs with id 'myDiv' out of a plain html-string, so the code in your update would not do the job.

Finally, to adjust my answer to your updated question and expectation of the onclick-event being visible in the parsed html-source:

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;

See this updated fiddle to see it in action.

That leaves the question: why on earth are you placing 'ninja' $-signs front of your variable names?

Upvotes: 6

sQVe
sQVe

Reputation: 2015

I would really use jQuery for this, it's quite simple.

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

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

See the following jsfiddle for it in action: http://jsfiddle.net/SsXtt/1/

Upvotes: 1

RoToRa
RoToRa

Reputation: 38390

That's just the way the debugger displays an HTML element. It doesn't show all attributes - especially since you are setting the DOM property onclick to a function reference, which can't be displayed as the HTML attribute onclick which takes a string (which AFAIK can't be set with JavaScript see Luc's comment).

Try console.log(element.onclick); instead, it should display something like function() {...}.

Or doesn't the event handle work?

BTW, any reason you don't use jQuery to set the href and the handler?

$div.children("a").attr('href', '#').click(function(){console.log('Yeah!')});

One more thing: In most consoles you can click on <a href="#"> and it will display the DOM properties, which should include the event handler.

Upvotes: 2

Luc
Luc

Reputation: 6016

Are you sure the element is correct? This works for me.

<a id="mylink">Test</a>
<script>
    document.getElementById("mylink").onclick = function() {
        alert("Works");
    };
</script>

Upvotes: 0

ddoor
ddoor

Reputation: 5963

Function needs to be inside a string, try adding quotes?

Upvotes: -1

Related Questions