My query is regarding using Javascript to change the value of an onclick function that already exists on the page.
There's a button. This button has the following onclick function:
onclick="if (confirm('Yahdy Yahdy yah?')) { someFunction(); }; return false;"
I would like to change the onclick function using Javascript to just be as follows and or extract the someFunction(); and run that directly without having to go through the confirmation. As I understand it, you can't confirm a confirm through scripting, so my only option is to run someFunction(); directly. My question is, how do I access someFunction() directly as someFunction() contains randomly generated values each time the page loads.
onclick="someFunction();"
That's basically what I'd like, so I can then call onclick() directly. I'm happy to use vanilla or jQuery to go about this.
TLDR: I want to extract PART of the old onclick function and make a new onclick function with JUST that part.
You can do this:
var code = obj.onclick.toString();
That will give you the javascript code assigned to that click handler to which you can search through it, find what you're looking for and reassign the click handler to something else.
I have no idea if this is the best way to do it, but here's something that worked for me:
function nullConfirm() { return true;};
(function() {
var obj = document.getElementById("test");
var code = obj.onclick.toString();
code = code.replace("confirm(", "nullConfirm(");
var matches = code.match(/\{(.*)\}/);
if (matches) {
obj.onclick = function() {
eval(matches[1]);
}
}
})();
Related
document.querySelector('html').onclick = function() {
alert('Hy');
}
works each time I click on the webpage displaying a dialogue box.
but if I were to remove function declaration and instead write
document.querySelector('html').onclick = alert('Hey');
it works only for once.
I don't understand this because I am asking javascript to alert by Hey each time I click on the webpage but it does the same only for once.
What effect does function declaration having on this snippet of code?
You need to distinguish between a function and the result of calling a function. In the second case, you're running the alert function immediately, and then setting the onclick to its result (which isn't a function and doesn't do anything useful).
Because what this does:
document.querySelector("html").onclick = alert("Hey");
It runs the code alert("Hey"), then sets the onclick of the element to the return value of alert("hey"). This will only work as a proper event handler if alert("Hey") returns a function. It doesn't:
console.log(alert("Hey"));
So you need to attach a function or function reference like so:
document.body.onclick = () => alert("Hey");
<p>Click Me</p>
The above works and is only a small addition to your wanted syntax - we're using ES6 arrow functions for this.
Can I retrieve and modify a previously assigned event function?
For example I originally add an onclick event handler to a node, like this :
var someNode = document.getElementByID('someNode');
someNode.onclick = function(){
//some stuff
};
Ideally later I would need to get back this event and modify the "some stuff" code content.
Is it doable in javascript?
You can modify the onclick event. Simply assign that to a new function will do. However, similar to most dynamic languages, function is not a data structure that you can easily modify. So keeping the same function but modifying it is AFAIK impossible.
The way I would suggest is to create a new function for your use, and assign it to the onclick property. However, JS is a very nice language that provide closure to your variables. So you can make a function that return a function to fit your need if you need some flexibility.
It's not really clear what you are trying to accomplish. But do you mean something like that ?
var someNode = document.getElementByID('someNode');
let customizablePart = function (e) {
// do some stuff
}
someNode.onclick = function (e) {
// unchangeable instructions
customizablePart.call(this, e)
}
// later ...
customizablePart = function (e) {
// do new stuff
}
What I want in html code:
<a onclick="DeleteImage('javascript:this.id', <?=$_SESSION['UserID']?>)"></a>
which passes the var userid from $_session to the javascript function:
function DeleteImage(aid,userid){}
This worked when i didnt had to pass the $_session variable and only had this function
function DeleteImage(aid){}
Then i could create the a element in javascript like this:
cross = document.createElement('a');
cross.onclick = function() { DeleteImage(this.id) };
How can I create the a element so it generates the html code i want?
I want something like:
cross.onclick = function() { DeleteImage(this.id, "<?=$_SESSION['UserID']?>") };
which obviously does not work. Any help appreaciated :)
I think you should change the way you retrieve an information like $_SESSION['UserID']. An interesting option would be creating a data attribute, for example in the <html> tag itself:
<html data-user-id="<?=$_SESSION['UserID']?>">
Then all you have to do is to retrieve that value in the DeleteImage function itself:
function DeleteImage(aid) {
var userId = document.documentElement.getAttribute("data-user-id");
...
}
And you're done, you can call DeleteImage with the old way. (Note: you can also use document.documentElement.dataset.userId in Chrome, Firefox and Opera. There are partial polyfills for IE, but I guess they're not worth the effort in your case.)
You can even save some extra cycles retrieving the value at the beginning of the script and storing it in a scoped variable:
var userId = document.documentElement("data-user-id");
function DeleteImage(aid) {
...
}
Slightly off topic, may I suggest to using some more modern way to attach event listeners? And maybe considering some kind of event delegation?
Sorry if my question seems naive (a bit of a newbie here), but I seem not to be able to get a simple answer to my question.
In JavaScript I try something like this
window.onload = init; *// ok, this assigns to the window load event a function that doesn't execute straight away*
// now I define my init()function
function init(){
// say...
alert('Noise!');
/* but here is my dillema...
Next say I want to assign to an button.onclick event a function that only executes when I click the button.
But (!here it is...!) I want to pass arguments to this function from here without causing to execute because it (obviously) has brackets.
Something like: */
var button = document.getElementById('button');
var promptInput = prompt("Name?");
button.onclick = printName(promtInput); // I only want to print name on button click
}
function printName(name){
alert(name);
}
So... OK, I know the example is stupid. Simply moving all prompt gathering inside printName() function and assign to button.onclick a bracketless printName function will solve the problem. I know. But, still. Is there a way to pass args to functions you don't want to execute immediately? Or it really is a rule (or 'by definition') you only use functions that await execution when you don't plan to pass args via it?
Or how do you best to this thing otherwise?
Thanks a lot!
Ty
button.onclick = function() {
printName(promptInput);
};
You can use Function.prototype.bind():
The bind() method creates a new function that, when called, has its
this keyword set to the provided value, with a given sequence of
arguments preceding any provided when the new function is called.
For example:
button.onclick = printName.bind(null, promtInput);
You could put the data that you would normally pass as an argument into some other holding location. You can either put it in a hidden HTML element, or you can use the sessionStorage API to keep it. So your code would look like this:
var button = document.getElementById('button');
var promptInput = prompt("Name?");
sessionStorage.setItem('MyName', promptInput);
button.onclick = printName; // I only want to print name on button click
}
function printName(){
alert(sessionStorage.getItem('MyName');
}
What Im trying to do is to get the content of a specific textarea tag in a specific clicks of a button, so I think a loop will solve this problem. The while loop on PHP does the role of making the name of textarea different and button's onclick trigger. But the loop in javascript wont work. Please anyone help what is the right one to complete my task?? Sorry for bad english...Thanks in advance
<html>
<head>
<script>
var i = 0;
while(i < 2000)
{
i++;
function feedbacks+i()
{
var feed = document.getElementsByName("feedback"+i)[0].value;
alert(feed);
}
}
</script>
</head>
<body>
<?php
while($i < 2000)
$i++;
echo "<textarea name='feedback$i' >you post</textarea>";
echo "<button onclick='feedbacks$i()' >send feedback</button>";
?>
</body>
</html>
I'm not sure if i get your question right, but why don't you write one single javascript function and pass the index as a parameter?
like:
function feedbacks(index) {
var feed = document.getElementsByName("feedback"+index)[0].value;
alert(feed);
}
and
onclick='feedbacks($i)'
Your code is incorrect, Since you have tagged your question with Jquery, I would like to suggest the following solution,
$(document).ready(function(){
$(document).on('click','button',function(){
alert($(this).prev('textarea').val())
});
});
You are creating those elements textarea and the button in runtime, So you have to use delegation inorder to register the click event for those buttons. Additionally you have to wrap your code inside .ready() function, Which means you have to manipulate the DOM only after it got ready.
Please see here for references,
.on (for delegation)
.ready()
.prev()
You have two major problems here.
Naming your function
When you name a function, you can't use variables, only a single identifier.
You could use a function expression and then assign the result somewhat that you can identify with a variable. e.g.
an_array_i_created_earlier[i] = function () {
// etc etc
}
Closures
You are trying to use i inside the function you are creating, but you are changing it outside that function before that function runs.
You can get around this by creating a new closure.
function createFunction(i) {
return function () {
// can use i sanely here because it was passed into a local variable belonging to `createFunction`
};
}
an_array_i_created_earlier[i] = createFunction(i);
This is all very messy though. You can forget about having to deal with i entirely, and throw out the horribly intrinsic event attributes while you are at it. Instead, navigate through the DOM to find the element:
addEventListener('click', function (evt) {
var textarea, t = evt.target;
if (t.classList.contains('feedback')) {
textarea = t.previousElementSibling;
alert(textarea.value);
}
});
Note that this uses some fairly recent additions to browser DOM. If you want compatibility with older browsers (in particular IE9 and earlier) then you will probably want to rewrite it to add some support for legacy approaches. A library like YUI or jQuery can help with that.
There's some error in your JavaScript code:
You tried to define a sequence of functions in a loop, and the function became local function to that loop. You cannot get access to these functions outside the loop. In order to make this work, you should define the function on window object, with the syntax window["feedbacks1"] = function () {}.
function feedbacks+i() is invalid syntax, use window['feedbacks' + i], as pointed in (1).
Functions defined in loop will share some local variable (closure). The variable in the function feedbacks#{i} will all share the same i. After the loop, i became 2001 and all the functions defined will try to get textarea with name feedbacks2001, which of course will not work. You will need the (function (i) { /* the code using i */ })(i); trick to make a local copy of the shared variable.
I made a demo on jsFiddle which correct the mistakes. I showed only 2 textareas. The following javascript should work for you 2000 textareas case.
for (var i = 0; i <= 2; ++i) {
window["feedbacks" + i] = (function (i) {
return function (e) {
var feed = document.getElementsByName("feedback"+i)[0].value;
alert(feed);
};
})(i);
}