JS prevent a function from running as onclick event - javascript

I would like to disable a certain function from running as an onclick event.
Here, I would like to disable myfunc1, not myfunc2. Actually I want to disable myfunc1 from the whole page, but anyway this is the only thing that I need.
I have no control over the page and I am using userscript or other script injection tools to achieve this.
What I've tried:
Redefining the function after the page has loaded: I've tried adding an event listener to an event DOMContentLoaded with function(){ myfunc1 = function(){}; }
This seems to be working, but in a fast computer with fast internet connection, sometimes it runs before the myfunc1 is defined (in an external js file that is synchronously loaded). Is there any way that I can guarantee that the function will be executed after myfunc1 is defined?
Is there any way that I can 'hijack' the onclick event to remove myfunc1 by its name?

You should use event listeners, and then you would be able to remove one with removeEventListener. If you can't alter the HTML source you will need something dirty like
function myfunc1() {
console.log('myfunc1');
}
function myfunc2() {
console.log('myfunc2');
}
var a = document.querySelector('a[onclick="myfunc1();myfunc2();"]');
a.setAttribute('onclick', 'myfunc2();');
Click me
Or maybe you prefer hijacking the function instead of the event handler:
function myfunc1() {
console.log('myfunc1');
}
function myfunc2() {
console.log('myfunc2');
}
var a = document.querySelector('a[onclick="myfunc1();myfunc2();"]');
var myfunc1_;
a.parentNode.addEventListener('click', function(e) { // Hijack
if(a.contains(e.target)) {
myfunc1_ = window.myfunc1;
window.myfunc1 = function(){};
}
}, true);
a.addEventListener('click', function(e) { // Restore
window.myfunc1 = myfunc1_;
myfunc1_ = undefined;
});
Click me

Another way this could be done is using Jquery and setting the onlick propery on the anchor tag to null. Then you could attach a click function with just myfunc2() attached.
$(document).ready(function () {
$("a").prop("onclick", null);
$("a").click(function(){
myfunc2();
});
});
function myfunc1() {
console.log('1');
}
function myfunc2() {
console.log('2');
}
<a class="test" href="#" onclick="myfunc1();myfunc2();">Example</a>
You can see the codepen here - http://codepen.io/anon/pen/BLBYpO

Perhaps you are into jQuery.
$(document).ready(function(){
var $btn = $('button[onclick*="funcOne()"]');
$btn.each(function(){
var newBtnClickAttr;
var $this = $(this);
var btnClickAttr = $this.attr("onclick");
newBtnClickAttr = btnClickAttr.replace(/funcOne\(\)\;/g, "");
$this.attr("onclick", newBtnClickAttr);
});
});
Where in the variable $btn gets all the button element with an onclick attribute that contains funcOne().
In your case, this would be the function you would like to remove on the attribute e.g., myfunc1();.
Now that you have selected all of the elements with that onclick function.
Loop them and get there current attribute value and remove the function name by replacing it with an empty string.
Now that you have the value which does not contain the function name that you have replace, you can now update the onclick attribute value with the value of newBtnClickAttr.
Check this Sample Fiddle

Related

Same RadioButton-Setting Function from Both Startup / Change in jQuery

I have a single shared jQuery function that checks a RadioButton selection: if 1 is selected, it hides a span, otherwise it shows it.
This shared function is called both on startup and on Change, because on startup, it needs to do the same thing. The startup works, but the onChange reference does NOT work:
JS_OBJ = {
toggleTier : function() {
if ($('input[name="tier"]:checked').val() == 'Y_YES')
{
$('#tierSpan').hide();
}
else
{
$('#tierSpan').show();
}
},
// this is called from document.onReady - it comes here, OK
onReady : function() {
// on startup, toggle Tier - works OK
this.toggleTier();
// Also link the radio button Change to this shared function
$('input[name="tier"]:radio').change(function () {
alert('About to enter toggle...');
// NEVER COMES HERE - Object doesn't support this property or method
this.toggleTier();
});
}
};
the this is changing value as it is passing thru the different zones. when it is first instantiated, it has a good value, but the radiobutton:change has a different this
I was able to change it get it to work:
$('input[name="tier"]:radio').change(function () {
alert('About to enter toggle...');
self; //closure
toggleTier();
});
see this: What underlies this JavaScript idiom: var self = this?
Inside the change event, this does not refer to the current JS_OBJ, it refers to the current event target in stead. You want to explicitly save your reference to this, so you can use it inside the event.
Example:
onReady : function() {
var me = this;
me.toggleTier();
// Also link the radio button Change to this shared function
$('input[name="tier"]:radio').change(function () {
me.toggleTier();
});
}

Do I need to remove and replace event handlers with JQuery to swap them?

I want the events click and touchstart to trigger a function.
Of course this is simple with JQuery. $('#id').on('click touchstart', function{...});
But then once that event is triggered, I want that same handler to do something else when the events are triggered,
and then later, I want to go back to the original handling function.
It seems like there must be a cleaner way to do this than using $('#id').off('click touchstart'); and then re-applying the handler.
How should I be doing this?
You can create a counter variable in some construct in your javascript code that allows you to decide how you want to handle your event.
$(function() {
var trackClicks = (function() {
var clicks = true;
var getClicks = function() {
return clicks;
};
var eventClick = function() {
clicks = !clicks;
};
return {
getClicks: getClicks,
eventClicks: eventClicks
}
})();
$('#id').on('click touchstart', function {
if (trackClicks.getClicks()) {
handler1();
} else {
handler2();
}
trackClicks.eventClick();
});
function handler1() { //firsthandler};
function handler2() { //secondhandler};
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
The way I would do this is by creating a couple of functions for the handler function to call based on certain flags. Sudo code would be something like this:
function beginning_action() {
...
}
function middle() {
...
}
var beginning_state = true;
$('#id').on('click touchstart', function{
if(beginning_state) {
beginning_action();
} else {
middle();
}
});
Then all you need to do is change the variable beginning_state to change which function is called. Of course you would give them better names that describe what they do and not when they do it.
Additionally, if you want the handler to call more than two functions you can change the beginning_state variable from a boolean to an int and check it's value to determine which function to call.
Good luck!

Function out of scope?

I have a function defined as follows:
window.onload = function() {
var ids = document.getElementById("idname");
function myFunction(){
/...*use ids var in here*./
}
}
I am trying to call myFunction from button onclick in html:
<button onclick="myFunction();"></button>
But it says myFunction is not defined. I understand because this is inside window.onload. How can I fix this? I need window.onload because I need to use document.getElementById("testID") to get content.
I need window.onload because I need to use document.getElementById("testID") to get content
No, you don't need window.onload. You simply have to put the code somewhere after the element with ID testID in the document.
Example:
<div id="testID"></div>
<script>
var ids = document.getElementById("testID");
function myFunction(){
/...*use ids var in here*./
}
</script>
However, if you want to keep using window.onload, then I suggest to not use inline event handlers, but bind the handler with JS:
window.onload = function() {
var ids = document.getElementById("testID");
ids.onclick = function(event){
/...*use ids var in here*./
}
};
(that might be a good thing to do anyway).
Lastly, you can get the a reference to the element inside the event handler using this or event.target:
<div id="testID"></div>
<script>
document.getElementById("testID").onclick = function(event) {
// access element via `this` or `event.target`
};
</script>
Learn more about event handling.
You defined it within a function so it's locked to that scope. Maybe you want to define it outside of that:
function myFunction() {
var ids = document.getElementById("idname");
// ...
}
window.onload = function() {
// ...
}
As a note, this is extremely old-school JavaScript. You could clean this up considerably using something like jQuery which would look something like this:
$(function() {
// Any initialization after page load.
});
function myFunction() {
var ids = $('#idname');
// ...
}

How to call javascript function immediately rather than on scroll

I have a piece of javascript code here. When a hyperlink is clicked, the load_button() function is called which just sets the variable load_switch to true. I have a piece of code inside $(window).scroll(function() { which will fire the code when the user scrolls. So at the moment, the user clicks the hyperlink to set the variable to true, and then my load_posts function (which I omitted from the code I included to make it easier to read, see below) fires when the user scrolls.
I would like to know how I can make the function fire without the user having to scroll first to activate it. I am editing a previously programmed function which used to be an infinite scroll (hence the function being called when the user scrolls). Here is my javascript:
<script language="javascript">
var load_switch = false;
function load_button(){
load_switch = true;
}
$(document).ready(function() {
$('.loader').hide();
var load = 0;
$(window).scroll(function() {
if(load_switch) {
//load_posts function goes here
}
});
});
</script>
Name your function
var load_switch = false;
function load_button(){
load_switch = true;
}
// Name your function instead of defining it inline
function onScroll() {
if(load_switch) {
//load_posts function goes here
}
}
$(document).ready(function() {
$('.loader').hide();
var load = 0;
$(window).scroll(onScroll);
// Call it whenever you'd like
onScroll();
});
You can use triggerHandler:
$(window).triggerHandler('scroll');
Note this will run all event handlers. If you don't want that, you need to store the desired event handler in a variable:
function handleScroll() {
//load_posts function goes here
}
function load_button(){
$(window).on('scroll', handleScroll);
}
$(document).ready(function() {
$('.loader').hide();
handleScroll(); // Call it manually
});
Also note your approach was bad. Instead of running the event handler always and exiting if a boolean flag is false, get rid of that flag and add or remove the event handler instead of setting the flag to true or false.

Function becomes undefined after first trigger

I have a block of code like so:
function doSomething() {
someVar.on("event_name", function() {
$('#elementId').click(function(e) {
doSomething();
});
});
}
// and on document ready
$(function () {
$('#anotherElemId').click(function () {
doSomething();
});
});
The problem that I'm encountering is that when I call doSomething() from anotherElemId click event(that is binded on document ready) it works as expected, but calling it recursively from elementId click doesn't work.
Any ideas? Thinking is something trivial that I'm missing.
Is someVar an actual jQuery reference to a dom element? (e.g. $('#someitem'))
The second problem is you cant put a .click event inside a function that you would like to instantiate later on. If you are trying to only allow #elementId to have a click event AFTER some previous event, try testing if a tester variable is true:
var activated = false;
$(function () {
$('#anotherElemId').click(function () {
activated = true;
});
$('#secondElemId').on("event_name", function() {
if (activated) {
// code that happens only after #anotherElemId was clicked.
}
});
});

Categories

Resources