Best way to slim down my code on onclicks - javascript

I am not great at javascript/jquery for the most part but I know how to get some software to work. But my issue is that I have a whole bunch of
$("body").on("click", "button#thisid", function(event) {
//do stuff here
});
There are alot of the on clicks that use jquery post and get functions but they all have tiny and simple differences that i need to have get sent through. I dont want every single button to have an onclick event but I am not sure how to bind the event to a large list of items that need to have it attached to.
I have been trying to come up with some way to slim all these down but I want to have the best approach instead a whole bunch of crash and fails. So I am reaching out to people who know more than me in order to lead me in the correct path.
Please help

Considering your elements are dynamically injected, you will need to apply the click handler to an element that always exist on page load:
$(document).ready(function() {
$(document).on("click", "button.target", function() {
console.log($(this)[0].id);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="1" class="target">One</button>
<button id="2" class="target">Two</button>
In the above example, the click handler is applied to document, and triggers whenever a button element with the class of target is clicked, running the code inside the function.
To combine the .get() and .post() functions, you'll have to find synonymous data. Keep in mind that you have access to $(this), so you can extract the relevant ID if need be :)
Hope this helps!

I dont exactly get what you want to do...
But the $("body") is the jquery selector which defines on which elements your listener will be bound to.
So if you want to create a listener for more different elements the probably easiest solution is creating a class like "listenedElement" which you give to every element you want the listener to react to and write write the selector like this
$('.listenedElement').on( "click", function() {});
If you just look for click listeners this one looks pretty nice as well:
https://api.jquery.com/click/

A nice way I find is having a one line for each button like so:
$('#model').on('click', openModel());
$('#openDropdown').on('click', openDropdown());
$('#shoppingCart').on('click', shoppingCart());
And then defining each of these functions:
function openModel() {
// Stuff here
}
function openDropdown() {
// Stuff here
}
function shoppingCart() {
// Stuff here
}
So instead of writing the function as a parameter, I find it neater to just do it separately and call it like above.

Related

Adding code via addEventListener without loop by mouseover

I want to add some code by addEventListener. I would use DOMContentLoaded, but ID which I'm trying to select is not available on page load. I could use mouseover, but it iterate the code on any move. I could also use click event, but I don't want it show on click, but just when it's shown. How can I handle it?
document.addEventListener("mouseover", function(event){
document.querySelector("#id").insertAdjacentHTML('afterend', '<div>asd</div>');
});
You need to delegate
var yourSpecificId = "some-id";
document.addEventListener("mouseover", function(event){
if (event.target.id == yourSpecificId ) //only when the id of the mouseover element is matching yourSpecificId
{
//code you want to execute
}
});
I would suggest a Mutation Observer. It looks hard to implement, but it's very easy. You can provide a callback function, and then a quick if statement to check if the newly added element has the correct id. If so, run your code and disconnect the observer.
It would be easier to help you if you posted a working example of when an element is added and the function you need to run.
Read this blog: https://davidwalsh.name/mutationobserver-api

Issue with .on in dealing with appended nodes

I have this bit of code that monitors clicks on <div class="selectable_item">
$(function(){
$("#matchres .selectable_item").on("click", function(){
console.log('Sending request')
$.post("/request", $.param({'crit_id': this.id}), function(){}).fail(function(){console.log("matchres error...");});
return true;});
});
What I'm noticing is when I use the chrome console, for example, to see if there are any $("#matchres .selectable_item"); it finds them, and if I define in the console $("#matchres .selectable_item").on("click", function(){console.log('hi')}); the action is as expected and the console logs correctly. But what I showed you above does not work. Any ideas why that is? Any help would be very much appreciated. As added information, I'm using jquery v1.10.2.
#Hanlet's idea is correct, at the time of document load those items don't exist because you're dynamically creating them, and they do exist by the time you interact with them in the developer console. What you want to do is bind the event handler to a delegate, or an object that will listen for events on child elements.
What you do not want to do is add delegate callbacks to the document when avoidable. Any click on the document will have to check against its event target to see if it should trigger this document delegate callback. You do this enough times and it becomes a performance concern. Instead, pick the closest ancestor element that isn't dynamically created.
For instance, if you're creating .selectable_item dynamically but not #matchres, then add this:
$('#matchres').on('click', '.selectable_item', function () { ... });
Because you add these dynamically, this could be an event delegation issue, very common. Try this instead:
$(document).on("click", "#matchres .selectable_item", function(){ ... }
The problem consists mainly in the fact that you bind these when the DOM is first built, and then you add more elements dynamically, but the event is not bound to these new elements.
Look at these two examples:
http://jsfiddle.net/hescano/aKfWf/
and
http://jsfiddle.net/hescano/aKfWf/1/

How to use same jquery fuunction on a multiple buttons that are created in a loop?

Im creating the same button in a loop as long as there is a certain condition, and I want to run the same jquery event handler for those buttons.
The problem is that the event handler only works for the first button generated.
My button is generated like this:
<?php while($row_c= mysqli_fetch_array($result_comments))
{ ?>
<button name="comment" id="comment" class="button_comment" value="Post">Post</button>
<?php } ?>
and the jquery im using is this:
$('.button_comment').click(function()
{
//some staff thats done here
});
What should do, so that the event handler works for all buttons that are generated?
Thank you
Your jQuery should work. Note that your buttons form invalid HTML/DOM: The id on an element must be unique. But since you're also using a class (which doesn't have to be unique), and that's what you're using in your jQuery selector, that works: Live Example | Source
Perhaps when you were trying it and it wasn't working, you were using $("#comment").click(...), which would not work, because of the id issue.
Check in firebug:
var buttoncomments = $('.button_comment');
console.log(buttoncomments);
Bind the control in question to a variable so you're certain that it's that one you're working with.
$('.button_comment').click(function()
{
var that = $(this);
"What should do, so that the event handler works for all buttons that are generated?"
A Fiddle would be a good way to show us the context of your problem ;)
Your code is valid because it will attach a handler to every element having 'button_comment' as a css class
Did you put this code inside a dom ready function ?
$(function(){
/* code here */
});
You can use event delegation
This mean you have to attach the event listener to the first common ancestor of those buttons. This is a good choice when many elements have to trigger the same routine an even more if some of them may be added to the DOM in the futur via AJAX (This keep the page from having to many event handlers attached to it)
Delegation syntax
// Event delegation
$( "#Ancestor").on("click", '.button_comment', function() {
alert( $( this ).val() );
});
Take the ID off from your php code. Remember ID's should be unique elements. Also, change your jquery from:
('.button_comment').click(function()
{
//some staff thats done here
});
to
('.button_comment').on('click', function()
{
//some staff thats done here
});
The on event will perform what you tell it to do at the time you tell it to do, so it does it pretty much at runtime. If you use your previous code, the element must exist at page load time for it to work.

JavaScript - All onClick events are not working?

Alright, so I'm making a Facebook-style chat. But that doesn't really matter.
See here:
http://jsfiddle.net/SkHme/7/
Nice and pretty, right? Well, there's a problem. Notice this line:
<div class="conversation EmperorCuzco" onclick="setActive('EmperorCuzco')">
See the onclick attribute? Well, it's not working. However, I have confirmed that the function itself DOES work. (if you run it just like that in the JavaScript, it runs like a dream) I have further confirmed that the function is not the problem by attempting to replace the onclick value with a simple alert('blah'), but that doesn't work either.
So, what's up? I'm guessing that something in my JavaScript is somehow disabling something, but I have absolutely no idea what it could be, nor how I could go about fixing it. I did some web searching, but couldn't find anything that helps.
What's going on?
Your setActive function is defined inside the scope of the $(document).ready handler. Move the function outside that function so that it is in the global scope.
Right now it looks like this:
$(document).ready(function()
{
// ...
function setActive(new_conversation)
{
// ...
}
});
Now change that to:
$(document).ready(function()
{
// ...
});
function setActive(new_conversation)
{
// ...
}
Really though, you should separate your content from your interactions and bind those event handlers in your script itself. Something like:
// Refers to the last clicked conversation *button*
// Initialize to empty jQuery object
var $active_conversation = $([]);
// Binding on #chat, targeting click events on .conversation_button children
$("#chat").on("click", ".conversation_button", function() {
// Hide currently active conversation
$active_conversation.hide();
$active_conversation.siblings('.conversation_button').removeClass("selected");
// Set as currently active conversation button
// Note: this refers to the clicked <div class="conversation_button">
var $this = $(this);
$active_conversation = $this.siblings('.conversation');
// Show this conversation
$active_conversation.show();
$this.removeClass("alert").addClass("selected");
});
Some advantages of this approach:
You don't need different classes for different conversations. By storing the actual conversation DOM element (as a jQuery object) in $active_conversation, the conversation can be identified without any extra processing.
You can add and remove whole list items with a conversation without assigning new event handlers. In the sample above, the event handler for all .conversation_button elements is defined at the level of #chat. For more about this binding mechanism, read up on .on (or .delegate for pre-1.7).
Here, have an updated fiddle! :-)
If all you say is really true (bad mistakes happen), the only thing that can make this is that an other event handler which takes your event before uses stopPropagation() or return false;
A quick check that can do is replace onclick with onmousedown or onmouseup, and see if you alert become visible.

Triggering anchor click within a table using jquery

I am using the below code to trigger the anchor click within the table compareTable, but it does not seem to take any effect. Can any1 point out the solution?
$('#compareTable a').click(function() {
alert("hi");
});
Here is the demo
The <a> tag doesn't exist at the time you bind that click handler. You can solve this by using .delegate() or .live() (or binding the handler when you create the element). The former is usually considered preferable, but I find you markup difficult, so I'll share a quick workaround with .live(). Simple as can be:
$('#compareTable a').live('click', function() {
alert("hi");
});
jQuery's methods are two-folded. If you call them with empty arguments (that is, you don't pass any argument), then do what they mean. $('#something').click() means that it would be clicked. If you provide an argument which is usually a callback handler, they just register that handler. So, you should use:
$('#copareTable a').click();
And of course, since you don't want to click those links without any reason, you probably should write this code in response to another event. Something like:
$('#register').click(function(){
$('#compareTable a').click();
});
And also don't forget that $('#comparetTable a') is a collection of all anchor links inside that table. So if you send click directive, all of them would be clicked.

Categories

Resources