I have a webpage with 100+ hyperlinks that all have the onClick and href attribute set. This works for the most part but I've run into the issue where browsers like IE7 use the href attribute over the onClick attribute. I need the onClick attribute to be the default so my function will load on click. I figured I could easily do this using jQuery and setting the click event to the onClick attribute value but I'm not having any luck, how would I go about this? Right now the code below sets TONS of click events to a single hyperlink. When I click a hyperlink I can watch the GET events sent multiple times for the hyperlink.
$("a[href*='/RightSizeOption/NewForm.aspx']").click(function() {
OpenPopUpPage($(this).attr('href'), RefreshPage);
return false;
});
Doesn't seem to make sense, unless that exact click handler is actually being bound multiple times. A better way of binding clicks is with delegate (also using preventDefault instead of return false for good measure):
$('#myParent').delegate("a[href*='/RightSizeOption/NewForm.aspx']", "click", function(event) {
event.preventDefault();
OpenPopUpPage($(this).attr('href'), RefreshPage);
});
#myParent is any ancestor element that is not expected to get destroyed; could be a wrapper div or 'body' even, though it's better to pick the closest common ancestor that never gets destroyed.
But what worries me is the multiple binding; if your sample code is within a function, that function is being fired multiple times, for example.
I'm also not certain about the "RefreshPage" that you're passing to OpenPopUpPage. I'd have to see what OpenPopUpPage does to even hazard a guess.
Related
I am using jquery currently and I bind an event handler to checkboxes to bring users to a new page. The problem is that this does not scale well as binding 1500 checkboxes can cause ie8 on slower machines to think the script is not responsive when taking 2-3 seconds to bind these event handlers.
The only other solution I could think of was to use images instead of checkboxes so that they could be surrounded by an tag instead of having 1500+ event handlers bound. I do not prefer this solution as in general I dont think it's good practice to override the browser's default behavior/style.
Does anyone know a scalable way to bring users to a url when a checkbox is clicked?
The new jQuery recommandation is to put handlers on a common parent, like document, using .on:
$(document).on("click", ":checkbox", function () {
// your handler code
});
The handler isn't attached to your 1500 checkbox but the event naturally bubble to the document that check if the event target match your selector.
You could just use the 'onchange' method to check if it's 'checked' and then change the 'document.location.href' to the link you want.
<input type="checkbox" onchange="if(this.checked) document.location.href='http://www.google.com';"/>Go to google
$(document).ready(function() {
$(document).on('click', 'checkbox', function() { // <-- assuming your checkboxes are loaded asynchronously
window.location= "http://www.example.com";
});
});
When a button is clicked, I use addClsOnOver to change the over cls of the button and it works fine. The second time the button is clicked, addClsOnOver is called again but with a different class and this is expected to happen multiple times but unfortunately, the event listeners created by addClsOnOver are not over-written after the first click.
I know now that I need to use removeListener() and then addClsOnOver if I want to change it again after the first time but dont know what parameters to put in it to remove the addClsOnOver listener.
I'm sure its fairly simple but I'm out of guesses atm and cant find anything in the docs that might suggest what the auto-generated listener might be called.
Help please? :)
If you do not set fn parameter in removeListener() method, all listeners for specified event will be removed.
So if you do not use your own listeners for mouseenter and mouseleave on button element you can use for removing listeners seted by addClsOnOver() method this code:
// use el.dom as scope because it is used el.hover method when listeners were created
el.removeListener('mouseenter', null, el.dom);
el.removeListener('mouseleave', null, el.dom);
Fiddle with example: https://fiddle.sencha.com/#fiddle/30d
I could not make preventdefault to prevent action. I apologize if the answer is too easy but I simply cant find the error. why is it not preventing from entering the link? jsfiddle given below.
http://jsfiddle.net/zwY5p/34/
$('#theForm').click(function(e) {
event.preventDefault();
alert('FORM!');
});
e != event
$('#theForm').click(function(event) {
event.preventDefault();
alert('FORM!');
});
The parameter passed to the handler function is what you need to execute preventDefault on. In your code, you are passing e but calling preventDefault on event.
preventDefault prevents the default browser action. It does not cancel the inline JavaScript, since that runs first. If you have to override that, just remove it (no event listener necessary):
$('#theForm').removeAttr('onclick').
your event parameter name e and the variable you are using event are different,
$('#theForm').click(function(event) {
event.preventDefault();
alert('FORM!');
});
Other than the errors pointed out on other answers there's another small issue, specifically in your markup declaration:
<!-- Use either the closing tag or the slash (/) in the opening tag -->
<button id="theForm" onclick="location.href='http://www.example.com'" />
go to google
</button>
On the topic, you have two different handlers attached to the button element, they are both handling the click event but they are still different and separate things. jQuery won't know about the handler defined in the markup:
var btn = document.getElementById('theForm');
jQuery._data( btn, "events" );
will return an array with a single element which is the handler added via jQuery.
Now you have to re-evaluate the need of two different handlers for the same element and event and apply conditions. Do you really need to do it this way?
You're using 2 'click' events.
You end up using preventDefault once, and it's used after the 1st click event has ran.
If you make your button an href, then your preventDefault will be working.
It will also make more sense, as the JS will be separated from the HTML markup.
Also, of course you must use the same parameter name. (function(event), with event.preventDefault for example).
If you are passing "e" as an event to the function then you should prevent the default action only for that "e" that you have passed and not for "event".
$('#theForm').click(function(e) {
e.preventDefault();
alert('FORM!');
});
jQuery preventDefault() method: http://api.jquery.com/event.preventDefault/
Hi I have a dynamically create table which acts as a pick list using check boxes. I Want these check boxes to be mutually exclusive. So upon checking a box I need to clear any other checked boxes.
$(document).on("keydown", "#list_Instructors input.allocate",function(event){
alert("hit");
$("#list_Instructors input.allocate").removeAttr('checked');
$(event.target).attr('checked', 'checked');
});
This sort of works but there is a huge delay between clicking and anything happening which is no good. I have tried all sorts of combinations with no success.
Is there is simple explanation as to why this is creating a delay.
Your problem is you bind on method for whole DOM which is really BAD.
So always try to bind that to the closest div (closest parent element) which your controls are exist.
And second thing is always cache your selectors for better performance.Like below
var dataTable=$('#dataTable');
dataTable.on("click", function(event){
alert($(this).text());
});
About Event performance from Jquery API says like below.
Attaching many delegated event handlers near the top of the document
tree can degrade performance. Each time the event occurs, jQuery must
compare all selectors of all attached events of that type to every
element in the path from the event target up to the top of the
document. For best performance, attach delegated events at a document
location as close as possible to the target elements. Avoid excessive
use of document or document.body for delegated events on large
documents.
What you might be seeing is that until the alert box is dismissed, the code afterwards is not executed. The alert command is a blocking one.
Perhaps you can use console.log() for debugging purposes of this feature. This will not block your code and it will be executed on the keydown event.
You need to use $(this) instead of going through another lookup. Also as stated above try to bind to the closest parent element if possible, for example a container div. With that said this should speed you up a bit:
$(document).on('keydown', '#list_Instructors input.allocate', function (event) {
//alert("hit");
console.log('hit');
$(this).removeAttr('checked');
$(event.target).attr('checked', 'checked');
});
But you should try to replace document with a container div or another parent element
Heres my link:
http://tinyurl.com/6j727e
If you click on the link in test.php, it opens in a modal box which is using the jquery 'facebox' script.
I'm trying to act upon a click event in this box, and if you view source of test.php you'll see where I'm trying to loacte the link within the modal box.
$('#facebox .hero-link').click(alert('click!'));
However, it doesn't detect a click and oddly enough the click event runs when the page loads.
The close button DOES however have a click event built in that closes the box, and I suspect my home-grown click event is being prevented somehow, but I can't figure it out.
Can anyone help? Typically its the very last part of a project and its holding me up, as is always the way ;)
First, the reason you're getting the alert on document load is because the #click method takes a function as an argument. Instead, you passed it the return value of alert, which immediately shows the alert dialog and returns null.
The reason the event binding isn't working is because at the time of document load, #facebox .hero-link does not yet exist. I think you have two options that will help you fix this.
Option 1) Bind the click event only after the facebox is revealed. Something like:
$(document).bind('reveal.facebox', function() {
$('#facebox .hero-link').click(function() { alert('click!'); });
});
Option 2) Look into using the jQuery Live Query Plugin
Live Query utilizes the power of jQuery selectors by binding events or firing callbacks for matched elements auto-magically, even after the page has been loaded and the DOM updated.
jQuery Live Query will automatically bind the click event when it recognizes that Facebox modified the DOM. You should then only need to write this:
$('#facebox .hero-link').click(function() { alert('click!'); });
Alternatively use event delegation
This basically hooks events to containers rather than every element and queries the event.target in the container event.
It has multiple benefits in that you reduce the code noise (no need to rebind) it also is easier on browser memory (less events bound in the dom)
Quick example here
jQuery plugin for easy event delegation
P.S event delegation is pencilled to be in the next release (1.3) coming very soon.