How can I get the function bound to an onclick attribute? - javascript

I've got a function bound to the onclick event in the html, like so:
<script>
function f1(){ alert('hello world'); };
</script>
<a onclick="f1()">test</a>
I'd like to do something with that function, like bind it to another event. I tried this in jQuery:
var defaultFunction = $('a').attr('onclick');
but defaultFunction is defined as a string rather than the function itself. I can evaluate it with eval(defaultFunction), but that makes me feel dirty. Is there a way I can access the function itself, rather than the string?
i.e. I'd like to be able to call defaultFunction() and do whatever the default onclick behavior bound to the a element is. (In this case, call f1()).
Here's a fiddle that tries to do that, but fails.

see this document.getElementById("id_of_your_element").onclick if that help you, it will return click handler, and you can call that, but its not right to raise events manually

Something like this:
Example
var defaultFunction = $('a').attr('onclick');
var defaultFunctionName = defaultFunction.substring(0, defaultFunction.indexOf('('));
$('div').on('click', function(){
if(typeof window[defaultFunctionName] ==="function")
{
window[defaultFunctionName]();
}
alert('Hello universe!');
});

It's just onclick attribute, no jQuery required:
<script>
function f1(){ alert('hello world'); };
</script>
<a onclick="f1()" id="aa">test</a>
<a id="bb">test2</a>
<script>
bb.onclick = aa.onclick;
// or
bb.onclick = function (){ alert('hello bb'); };
</script>

Use this:
function f1() {
alert('hello world');
};
$('a').on('click', f1);
Here is your fiddle with the fix: http://jsfiddle.net/o8b5j15k/2/

Instead of attempting to copy the function bound inline, you could trigger the click event programatically:
function defaultFunction() {
$("a[onclick]").click(); // change selector to match your actual element
}
http://jsfiddle.net/o8b5j15k/3/

Its best to use addEventListener() you can add all types of events. example: "click", "mousemove", "mouseover", "mouseout", "resize" and many more. the false at the end is to stop the event from traversing up the dom. If you want parent dom objects to also receive the event just change it to true. also this example requires no javascript libraries. This is just plain old javascript and will work in every browser with nothing extra needed.
Also addEventListener() is better than onClick() as you can add an unlimited number of event listeners to a dom element. If you have an onClick() on an element and then set another onClick() on the same element you have overwritten the first onClick(). Using addEventListener() if i want multiple click events to trigger when i click on an element i can do it with no problem.
If you want data about the element that is triggering the event you can pass the event to the function. You will see in my example function(e) e is the event and you can use e or this to target the element that is being triggered. Using e or this i can also get more data about the triggered event. for example if the event was a mousemove or mouseclick i can get the x and y position of the mouse at the time of the event.
<!DOCTYPE html>
<html>
<head>
<title>exampe</title>
</head>
<body>
<a id="test" href="">test</a>
<script>
document.getElementById("test").addEventListener("click",function(e){
alert('hello world');
alert('my element '+e);
alert('my element '+this);
},false);
</script>
</body>
</html>
if you want to have addEventListener call a function just change the 2nd value to the function name like this.
document.getElementById("test").addEventListener("click",f1,false);
this will execute the function
function f1(){ ... }
When you want to remove an event listener just call target.removeEventListener(type, listener[, useCapture]). Very simple and easy to manage.

Related

How to wrap multiple dynamic eventListeners into one?

I just started to learn js and need a little help: I have the following function:
//SET CHAT BEHAVIOR
function chatSettings() {
console.log('ChatSettings called')
function BtnAndScrollBar(texteditor) {
console.log('BTNAndScrollBar called');
const sendBtn = $('.cl.active').find('.sendBtn');
const attachBtn = $('.cl.active').find('.attachBtn');
console.log(sendBtn)
}
function sendAndDeleteMessage(send) {
console.log(send);
}
var sendBtn = $('.cl.active').find('.sendBtn');
sendBtn.mousedown(function () {
sendAndDeleteMessage(this);
});
var textEditor1 = $('.cl.active').find('.chatTextarea');
textEditor1.on('focus change mousedown mouseout keyup mouseup', function (){
console.log(this);
BtnAndScrollBar(this)
});
}
$('document').ready(function () {
console.log('hello');
$('.tabs').tabs();
chatSettings();
});
I prepared a js.fiddle - As you can see from console.log when clicking into the textarea, the eventListener always listens to #cl1, even if .cl.active switches along with the according TAB.
The events in the textarea are just relevant, if .cl is active. My target is to wrap all three eventListener into one and apply the event to the textarea in the active stream, but all I tried went wrong... Can anyone help? #Dontrepeatyourself #DRY
$(".chatTextarea").on(
'focus change mousedown mouseout keyup mouseup',
function (this) {
//this.id can contain the unique id
greatFunction(this);
});
This will bind event individually with unique id found with this keyword and also wraps all event listener into one function but this is better when you want to process each event with same functionality
please let me know if this helps.
Peace
$(".cl textarea").on('focus change mousedown mouseout keyup mouseup', function () {
greatFunction(this)
});
Tada!
P.S. Is there a reason greatFunction is defined inside window.onload?
Try using $(document).ready function to load code when the page loads.
Also use $('textarea #cl1').on to get the textarea with the #cl1 or whichever id you want to use and then call the function after using the .on.
Hope this helps!
Let me know if it works!
$(document).ready(function () {
function greatFunction(elem) {
//do stuff
}
$('textarea').on('focus change mousedown mouseout keyup mouseup', function () {
greatFunction(this)
});
}
First off, I changed the onload to bind with jQuery, so all your logic is doing jQuery bindings, rather than swapping back and forth between jQuery and vanilla javascript. Also, doing an actual binding removes an inline binding.
Next, the binding has been condensed into a single delegate event listener. Since you eluded in your comments that it wasn't working for the active element after the active was moved or added, this reflected that you were dealing with dynamic elements. Delegate event listeners are one way to handle such things.
Delegate event listeners bind on a parent element of the elements that will change, or be created. It then waits for an event to happen on one of it's children. When it gets an event it is listening for, it then checks to see if the element that it originated from matches the child selector (second argument) for the listener. If it does match, it will then process the event for the child element.
Lastly, I added some buttons to swap around the active class, so you could see in the snippet that the event handler will start working for any element that you make active, regardless of it starting out that way.
$(window).on('load', function () {
function greatFunction (elem) {
console.log(elem.value);
}
$(document.body).on(
'focus change mousedown mouseout keyup mouseup',
'.cl.active .chatTextarea',
function () {
greatFunction(this);
}
);
$('.makeActive').on('click', function () {
$('.active').removeClass('active');
$(this).closest('div').addClass('active');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="cl1" class="cl active"><textarea class="chatTextarea">aa</textarea><button class="makeActive">Make Active</button></div>
<div id="cl2" class="cl"><textarea class="chatTextarea">bb</textarea><button class="makeActive">Make Active</button></div>
<div id="cl3" class="cl"><textarea class="chatTextarea">cc</textarea><button class="makeActive">Make Active</button></div>

Finding Triggering Element of onClick function

I'm working on someone's existing code. In the code there are some inline onClick events attached to some input elements, like this one:
<input type="button" id="inputID" onClick="someFunction()"/>
Problem is that I cannot edit that input's HTML, but I can edit the javascript function declaration of that function.
function someFunction(){
//want to console log the ID of the triggering input element e.g. #inputID
}
Is there a way that I could find the ID of the triggering input within the function, without passing any parameters at the time of calling the function (as I cannot edit the HTML)
Don't use inline event handlers. Use event listeners:
function someFunction(event) {
// Use `this` or `event.currentTarget` to get the current target
console.log(this.id);
}
document.getElementById("inputID").addEventListener('click', someFunction);
<input type="button" id="inputID" value="Click me" />
Since you listed in the tags that you're using jQuery, just leave the body of someFunction empty and attach an event listener to your inputs that call that function.
$('[onclick="someFunction()"]').click(function() {
console.log(this.id);
});
https://jsfiddle.net/k8o1umo4/
You can, however it's not cross browser, in IE it's
window.event.srcElement.id
In FF and Chrome, you have to pass it to the inline function like
someFunction(event)
And then you can access it from target property
event.target.id
You could use the global event object to achieve this:
function someFunction() {
var el = window.event.target;
console.log(el.id);
}
Example fiddle
Be aware that this is may have issues in older browsers. An alternative would be to leave the someFunction() empty (as you say that you cannot remove it in the HTML) and instead assign the event handlers through unobtrusive Javascript, from which you can access the element which raised the event through the this reference.
function someFunction() {
console.log(this.id);
}
var el = document.getElementById("inputID")
//remove inline click event
el.removeAttribute("onclick");
//attach click event
el.addEventListener("click", someFunction);
Within the function that was called from addEventListener 'this' will now reference the element from which the event was fired.
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#The_value_of_this_within_the_handler
First Way: Send trigger element using this
<button id="btn01" onClick="myFun(this)">B1</button>
<button id="btn02" onClick="myFun(this)">B2</button>
<button id="btn03" onClick="myFun(this)">B3</button>
<script>
function myFun(trigger_element)
{
// Get your element:
var clicked_element = trigger_element
alert(clicked_element.id + "Was clicked!!!");
}
</script>
This way send an object of type: HTMLElement and you get the element itself. you don't need to care if the element has an id or any other property. And it works by itself just fine.
Second Way: Send trigger element id using this.id
<button id="btn01" onClick="myFun(this.id)">B1</button>
<button id="btn02" onClick="myFun(this.id)">B2</button>
<button id="btn03" onClick="myFun(this.id)">B3</button>
<script>
function myFun(clicked_id)
{
// Get your element:
var clicked_element = document.getElementById(clicked_id)
alert(clicked_id + "Was clicked!!!");
}
</script>
This way send an object of type: String and you DO NOT get the element itself. So before use, you need to make sure that your element already has an id.
You mustn't send the element id by yourself such as onClick="myFun(btn02)". it's not CLEAN CODE and it makes your code lose functionality.
in your case it would be:
<input type="button" id="inputID" onClick="someFunction(this.id)"/>
js:
function someFunction(clicked_id){
// Get your element:
var clicked_element = document.getElementById(clicked_id);
// log your element id
console.log(typeof tab);
}

JavaScript: onclick and return false

I'm using this in my HTML:
Click
It calls the function preload() on an external js-file and works fine so far.
But i have dozens of those links and would like to remove alle those "return false" and put only one directly inside the preload()-function in the js-file.
But it will always be ignored?! Does the "return false" really only work inside the onclick="..."?
function preload () {
// some code
return false;
}
Click
or use addEventListener
For example:
Click
<script type="text/javascript">
document.querySelector('.link').addEventListener('click', function (e) {
// some code;
e.preventDefault();
}, false);
</script>
Putting return false; in the inline onclick attribute prevents the default behavior (navigation) from occurring. You can also achieve this by clobbering the onclick attribute in JavaScript (i.e. assigning the .onclick property to be a function that returns false), but that's frowned upon as old-fashioned and potentially harmful (it would overwrite any additional event listeners attached to that event, for example).
The modern way to prevent the <a> element's default click behavior from occurring is simply to call the .preventDefault() method of the triggering event from within the attached event listener. You can attach the listener the standard way, using .addEventListener()
Some examples:
// this works but is not recommended:
document.querySelector(".clobbered").onclick = function() {
return false;
};
// this doesn't work:
document.querySelector(".attached").addEventListener("click", function() {
return false;
});
// this is the preferred approach:
document.querySelector(".attachedPreventDefault").addEventListener("click", function(e) {
e.preventDefault();
});
If you click me, I don't navigate<br/>
<a class="clobbered" href="/fake">If you click me, I don't navigate</a>
<br/>
<a class="attached" href="/fake">If you click me, I navigate</a>
<br/>
<a class="attachedPreventDefault" href="/fake">If you click me, I don't navigate</a>
I think if you put it into the preload function and in the onclick event just put return false will work. Maybe you've tried this code?
Click
Try to put the return false clause into the inline function:
<input onclick="yourFunction();return false;">
I would maybe suggest not using onClick() and instead using similar jQuery.

Can I determine what was clicked using JavaScript?

Once again I've inherited someone else's system which is a bit of a mess. I'm currently working with an old ASP.NET (VB) webforms app that spits JavaScript onto the client via the server - not nice! I'm also limited on what I can edit in regards to the application.
I have a scenario where I have a function that does a simple exercise but would also need to know what item was clicked to executed the function, as the function can be executed from a number of places within the system...
Say I had a function like so...
function updateMyDiv() {
$('#div1').hide();
$('#div2').hide();
$('#div13').show();
}
how could I get the ID (for example) of the HTML element that was clicked to execute this?
Something like:
function updateMyDiv() {
alert(htmlelement.id) // need to raise the ID of what was clicked,
$('#div1').hide();
$('#div2').hide();
$('#div13').show();
}
I can expand on this if neccessary, do I need to pass this as an arguement?
The this keyword references the element that fired the event. Either:
<element onClick="doSomething(this);">
or
element.onclick = function() {
alert(this.id);
}
Bind your click events with jQuery and then reference $(this)
$('.myDivClass').live('click', function () {
updateMyDiv(this);
});
var updateMyDiv = function (that) {
alert(that.id);
// save the world
};
You don't need to pass "this", it is assigned automatically. You can do something like this:
$('div').click(function(){
alert($(this).attr('id'));
})
Attach the function as the elements event handler is one way,
$(htmlelement).click(updateMyDiv);
If you are working with an already generated event, you can call getElementByPoint and pass in the events x,y coords to get the element the mouse was hovering over.
$('.something').click(function(){
alert($(this).attr('id'));
});
You would need to pass it the event.target variable.
$("element").click(function(event) {
updateMyDiv($(event.target));
});
function updateMyDiv(target) {
alert(target.prop("id"));
}
Where is your .click event handler? Wherever it is, the variable this inside of it will be the element clicked upon.
If you have an onclick attribute firing your function, change it to
<tag attribute="value" onclick="updateMyDiv(this)">
and change the JavaScript to
function updateMyDiv(obj) {
alert(obj.getAttribute('id')) // need to raise the ID of what was clicked,
$('#div1').hide();
$('#div2').hide();
$('#div13').show();
}
use the .attr('id') method and specify the id which will return what you need.

Changing the onclick event delegate of an HTML button?

How do you change the JavaScript that will execute when a form button is clicked?
I've tried changing its onClicked and its onclicked child attributes like so:
$('mybutton').onClick = 'doSomething';
and
$('mybutton').attributes["onclick"] = 'doSomething()';
Neither seem to work. My other options are:
To have two buttons and hide one and show the other.
To have it directed to a function that evals a string and change the string to the function I want to execute.
Neither seem very elegant.
I'm using Prototype as a js library so it that has any useful tools I can use them.
If the original onclick event was set through HTML attributes, you can use the following to overwrite it:
$("#myButtonId").setAttribute("onclick", "myFunction();");
For Prototype, I believe that it would be something like this:
$("mybutton").observe('click', function() {
// do something here
});
EDIT: Or, as it says in the documentation, you could simply specify the function you want to call on click:
$('mybutton').observe('click', respondToClick);
function respondToClick(event) {
// do something here
}
But this is all, again, Prototype-specific.
Using the Prototype framework you can do:
Event.observe("mybutton", "click", clickHandler);
or:
Event.observe("mybutton", "click", function() {
alert("Button clicked!");
});
or:
$("mybutton").observe("click", clickHandler);
or:
$("mybutton").observe("click", function() {
alert("Button clicked!");
});
See the Event class documentation
The general way to set an onclick handler in javascript is to set onclick to a function, by passing it the name of a function directly, not in a string. So if myButton is set to a DOM Element, you would write:
myButton.onclick = doSomething;
So when you click the 'mybutton' button, the doSomething function will be called as doSomething(). For anonymous functions, you can write:
myButton.onclick = function() {
alert("myButton was clicked!");
};
In JQuery it's
$("#myButtonId").click(myFunction);
function myFunction(){
alert("Clicked");
}
Or if you want to put the function inline:
$("#myButtonId").click(function(){
alert("Clicked");
});
If you are using JQuery firstly make sure you use the relevant selector prefix (IE: If your using the Id of the element put a # in front of it). Secondly it's the click method to assign a callback to the click event.
Last I used Prototype, it was something like this:
Event.observe('mybutton', 'click', doSomething);
By the way, your examples might've even worked if you didn't quote the function names.
EDIT: Yes, Element.observe(element, eventName, handler) and someElement.observe(eventName, handler) also work. And don't quote the handler name - you want to pass the function not a string!
I found a solution for your issue with prototype under firefox:
$("#myButtonId").writeAttribute('onclick', ''); // first remove the attribute
$("#myButtonId").observe('click', function () { ... }); // then add the event

Categories