Rouge
Rouge

Reputation: 4239

How to pass a parameter when user clicks a link

I have a quick question regarding the parameter in onclick

I have

function testPro(){
   codes....
   codes....

    var test = 'init';  //the test can only be init here...

    link.href         = '#';
    link.innerHTML   += 'test value';
    link.onclick      = onClick;
    link.onmouseover  = onHover;
    link.onmouseout   = hoverOut;  
   codes....
}

function onHover(){
   alert(test);
}

I want to pass test variable when user clicks the button. I can't use onHover(test) becasue it gave me errors. How do I solve this issue?

Thanks so much

Upvotes: 1

Views: 126

Answers (5)

Vadim
Vadim

Reputation: 8779

Your test variable defined in scope of testPro function and can't be used directly by onHover function called in global scope. You have several options to solve this issue:

Add test variable to the closure of event handler

function testPro() {
    ...
    var test = 'init';
    ...
    link.onmouseover = function() { return onHover(test); };
    ...
}

function onHover(test) {
    alert(test);
}

or put test variable to some globally accessible namespace

var globals = { test: null };

function testPro() {
    ...
    globals.test = 'init';
    ...
    link.onmouseover  = onHover;
    ...
}

function onHover() {
    alert(globals.test);
}

or bind callback execution to some object containing test

function testPro() {
    ...
    var scope = { test: 'init' };
    ...
    link.onmouseover  = onHover.bind(scope);
    ...
}

function onHover() {
    alert(this.test);
}

or add custom data attribute to DOM element

function testPro() {
    ...
    link.setAttribute('data-test','init');
    ...
    link.onmouseover  = onHover;
    ...
}

function onHover() {
    alert(this.getAttribute('data-test'));
}

Upvotes: 1

dandavis
dandavis

Reputation: 16726

you can reevaluate the function in the scope of execution to grab the closures, but i would recommend using a different methods, as eval() is not without caveats.

so, even though i'd try to talk you out of it, this DOES do what you asked for with minimal re-factoring:

function testPro(){

    var test = 'init';  //the test can only be init here...

    link.href         = '#';
    link.innerHTML   += 'test value';
    link.onclick      = eval( "0||"+ onClick);

}

function onClick(){
   alert(test);
}

link={};
testPro();
link.onclick(); //shows "init"...

Upvotes: 0

numbers1311407
numbers1311407

Reputation: 34072

Perhaps something like:

function makeClickHandler(arg) {
  return function (event) {
    alert(arg);
  }
}

link1.onclick = makeClickHandler('arg1');
link2.onclick = makeClickHandler('arg2');
// ...

To increment a variable for that button, you could write a handler something like this:

function makeClickHandler() {
  var i = 0;
  return function (event) {
    alert(++i);
  }
}

Upvotes: 2

adeneo
adeneo

Reputation: 318182

You can attach random properties to DOM elements :

function testPro(){
    var test = 'init'; 

    link.href         = '#';
    link.innerHTML   += 'test value';
    link.onclick      = onClick;
    link.onmouseover  = onHover;
    link.onmouseout   = hoverOut;  
    link.test         = test;
}

function onHover(){
    alert(this.test);
}

FIDDLE

Upvotes: 1

Bergi
Bergi

Reputation: 664346

Use a small function expression that takes the event argument and passes it together with the test value to onHover:

var test = …;
link.onclick = function(event) {
    return onHover(test, event);
};

// somewhere else (on a higher scope than `test`)
function onHover(arg) {
    alert(arg);
}

Upvotes: 3

Related Questions