var btn1 = document.getElementById('btn1');
var btn2 = document.getElementById('btn2');
btn.addEventListener('click', say('hello'));
btn2.addEventListener('click', shout('yo'));
function say(word) {
var saying = word;
var container = document.getElementById('result1');
return function handleEvent() {
var text = document.createTextNode(saying);
container.innerHTML = '';
container.appendChild(text);
};
}
function shout(word) {
var saying = word.toUpperCase();
var container = document.getElementById('result2');
return function handleEvent() {
var text = document.createTextNode(saying);
container.innerHTML = '';
container.appendChild(text);
};
}
Uppon clicking on btn1 , "hello" is displayed in result1 .
Uppon clicking on btn2 , "YO" is displayed in result2 .
Now, as you may have noticed, the two handleEvent functions are exactly the same. What I want to achieve is something like.
function say(word) {
var saying = word;
var container = document.getElementById('result1');
return handleEvent;
}
function shout(word) {
var saying = word.toUpperCase();
var container = document.getElementById('result2');
return handleEvent;
}
function handleEvent() {
var text = document.createTextNode(saying);
container.innerHTML = '';
container.appendChild(text);
}
But that of course will not work as the handleEvent function is not declared inside the say and shout functions; thus, saying and container will not be defined.
I have tried playing around with bind() and declare saying and container on this inside the say and shout functions :
function say(word) {
this.saying = word;
this.container = document.getElementById('result1');
return handleEvent.bind(this);
}
function shout(word) {
this.saying = word.toUpperCase();
this.container = document.getElementById('result2');
return handleEvent.bind(this);
}
function handleEvent() {
var text = document.createTextNode(this.saying);
this.container.innerHTML = '';
this.container.appendChild(text);
}
But that didn't work either.
Thank you!
You cannot reuse a closure in a different context, because by definition in javascript a closure is an inner function which is bound to the context of its parent.
You can however extract your function body in order to reuse it in different contexts:
var btn1 = document.getElementById('btn1');
var btn2 = document.getElementById('btn2');
btn.addEventListener('click', say('hello'));
btn2.addEventListener('click', shout('yo'));
function saySomething(context, saying) {
var text = document.createTextNode(saying);
container.innerHTML = '';
container.appendChild(text);
};
function say(word) {
var saying = word;
var container = document.getElementById('result1');
return function handleEvent() {
saySomething(context, saying);
};
}
function shout(word) {
var saying = word.toUpperCase();
var container = document.getElementById('result2');
return function handleEvent() {
saySomething(context, saying);
};
}
Or if you want to use bind:
var btn1 = document.getElementById('btn1');
var btn2 = document.getElementById('btn2');
btn.addEventListener('click', say('hello'));
btn2.addEventListener('click', shout('yo'));
function saySomething(context, saying) {
var text = document.createTextNode(saying);
container.innerHTML = '';
container.appendChild(text);
};
function say(word) {
var saying = word;
var container = document.getElementById('result1');
return saySomething.bind(undefined, context, saying);
}
function shout(word) {
var saying = word.toUpperCase();
var container = document.getElementById('result2');
return saySomething.bind(undefined, context, saying);
}
Binding should have worked if you had created new objects to be bound to, instead of using this
:
function say(word) {
return handleEvent.bind({
saying: word,
container: document.getElementById('result1')
});
}
function shout(word) {
return handleEvent.bind({
saying: word.toUpperCase(),
container: document.getElementById('result2')
});
}
However, you still can solve this with a normal closure:
function say(word) {
return makeHandleEvent(word, 'result1');
}
function shout(word) {
return makeHandleEvent(word.toUpperCase(), 'result2');
}
function makeHandleEvent(saying, id) {
var container = document.getElementById(id);
return function handleEvent() {
var text = document.createTextNode(saying);
container.innerHTML = '';
container.appendChild(text);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.