jQuery, discover what a dom object's class are - javascript

I have a .click() on several buttons. Each .click() calls a function. The function needs to know which button called it so that it can show or hide different content and change the styles of the other buttons. The function has an event object passed to it.
Is there a way I can get the current class that the event object has?

$('myButton').click(function() {
var className = this.className; // This will give you the whole class string of the clicked element
var hasClass = $(this).hasClass('myClass'); // This will tell you (true or false) whether the clicked element has class 'myClass'
});

You can get the class with .className or .attr("class"), though what you probably want is to have this refer to the button, for example:
$(".selector").click(myFunction);
function myFunction() {
//this == button that was clicked
var c = this.className;
}
Or an inline function:
$(".selector").click(function () {
var c = this.className;
});

As long as you are passing this to a function (though depending how you are doing this, some code would be nice!), if you pass e as the first parameter in the function then you can use e.target.className to get the class, or, with jQuery $(e.target).attr('class');

Couldn't you make different functions for the different .click() calls?

Related

How to bind 'this' to click listener and use the event - es6

I have a multistep form, with 4 frameset. Each one must come in when I press the "Next" button (of course)
My ES6 modular code cointains something like this:
class FormController {
// 1. describe and initiate object
constructor() {
this.nextBtn = $(".next");
this.next_fs;
....
this.events();
}
// EVENTS LISTENER
events(){
this.nextBtn.on("click", this.nextClicked.bind(this));
// other listeners
}
nextClicked() {
this.next_fs = $(this)
.parent()
.next(); // this is the next fieldset
// some actions...
}
// rest of the code
}
My problem is the following:
I need to bind "this" inside nextClicked function to be able tu use all variables and methods like this.next_fs, this.saveData(), etc...
But I also need to know which button has been clicked, and I cannot know that because this is no more "this button", and I cannot pass a variable (let's call it 'e') to trace the e.target.
What's the matter with my code? I know that's something stupid that I'm not seeing.
Thanks!
But I also need to know which button has been clicked, and I cannot know that because "this" is no more "this button", and I cannot pass a variable (let's call it 'e') to trace the e.target
The browser's event triggering code passes that. You just need to read it.
nextClicked(e) {
"...and I cannot pass a variable (let's call it 'e') to trace the e.target"
Actually, you don't need to pass it as variable, because even if you don't pass the e you can get it in nextClicked because browsers do it by default, so it will come as parameter if you declare the function as nextClicked(e){...} and keep the bind as you have.
Or, you can pass parameters after this, such as ...bind(this, this.nextBtn), then the first parameter on nextCliked will be the button.
See below these two possibilities I mentioned:
$(".buttons").on("click", this.nextClicked.bind(this))
function nextClicked(e){
//here your context is the same as when you binded the function, but you have the event
let target = e.target;
console.log(target.id);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="btn-1" class="buttons">click me 1</button>
<button id="btn-2" class="buttons">click me 2</button>
let nextButton = $("#btn-1")[0];
$(".buttons").on("click", this.nextClicked.bind(this, nextButton))
function nextClicked(nextBtn, e) {
//here your context is the same as when you binded the function,
//but you have the button AND the event
console.log("NextButton Id: " + nextBtn.id);
console.log("Clicked button Id: " + e.target.id);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="btn-1" class="buttons">next</button>
<button id="btn-2" class="buttons">previous</button>
You are doing
this.next_fs = $(this)
But, earlier you set this to an instance of FormController
this.nextBtn.on("click", this.nextClicked.bind(this));
so what you are doing is
this.next_fs = $( (FormController)this);
You are expecting jQuery to work with a class instance, instead of the event object.
I strongly discourage you from using $(this) ever in a event handling context. this can change it's meaning as you have shown in your sample by the code breaking.
Always use event.target or event.currentTarget. I prefer currentTarget as it points to the element on which the event was bound, and not a deeper lying element within that element.
so your code should be
nextClicked(e) {
this.next_fs = $(e.currentTarget)
.parent()
.next(); // this is the next fieldset
// some actions...
}

Getting the source of this click event in JQuery

I have multiple dynamically created buttons with the same class on my page and when I try to call a function on the click of the button, the function gets called for all of the buttons with the same class.
I want the function to be called for this click event only.
Here is my function:-
$(".js-btn-plus").click(function (e) {
var link = $(e.target);
var val = link.next('.value').text();
val++
link.next('.value').text(val);
});
Maybe generate unique ID for the button and use that as an event reference instead of the class?
.text() returns a string. Convert the string val to a number
val = Number(val) + 1
or
val = +val++
Please could you provide some sample HTML to alongside the JQuery?
From what I can see you may want to have a look at using $(this) instead of e.target
$(document).on('click', '.js-btn-plus', function() {
var val = parseInt( $(this).find('.value').text() );
val++;
$(this).find('.value').text(val);
});
Not 100% sure what it is that you're trying to achieve, there may be a better way of doing it if you could explain a little bit more and provide some HTML to go alongside your question.
Edit: Using the 'on' function allows you to dynamically bind the function events instead of having them have a listener fire when the script is loaded and executed.
My solution:
$(".js-btn-plus").click(function (e) {
var val = parseInt($(this).next('.value').text());
val++;
$(this).next('.value').text(val);
});

Two Html select drop down apply class for span element using Javascript

I am working on HTML select Dropdown. I have two dropdowns one is for font size adjust and other is for text alignment.
When I select the fontsize from the dropdown it has to apply along with text-capitalize (bootstrap css) and If I select the font alignment all three should apply for the span element. For Example.
<div>
<span id="Title"class="text-capitalize">check</span>
</div>
Right now the code was like this
function changeFont_size () {
var select = document.getElementById('font_size');
// Bind onchange event
select.onchange = function() {
document.querySelector("#Title").className = this.value += " text-
capitalize";
};
}
function changeAlignment () {
var select = document.getElementById('text_align');
// Bind onchange event
select.onchange = function() {
document.querySelector("#Title").className = this.value;
};
}
Actually I am newbe on Javascript. Some how I am not getting.
The output result would be the combination of :
<span class="h1 left text-capitalize">Text</span>
Everything should be in pure javascript.
Thanks in advance. Kindly help me.
Here is the Link
This jsfiddle makes your code work. You need to run the code when the document is loaded, so that your onchange functions are being hooked in time.
It does not work exactly like you intended though. Your alignment classes need to be on the parent element and when you select your alignment, you disregard the previously set h1 or h2 class.
window.onload = function() {
var font_size = document.querySelector('#font_size');
// Bind onchange event
font_size.onchange = function() {
document.querySelector("#Title").className = this.options[this.selectedIndex].value += " text-capitalize";
};
var text_align = document.querySelector('#text_align');
// Bind onchange event
text_align.onchange = function() {
document.querySelector("#Title").className = this.options[this.selectedIndex].value;
};
};
You are mixing things up. There are two ways to bind events (well, two ways which are still common even with recent browsers).
The first one is to put a function call in the onsomething property of an element in the html code. Whatever is put there will be executed when the event happens.
<button onclick="alert('hi');">Click me</button>
You should pass the event object to an event handler instead of writing inline code.
<button id="helloworld" onclick="helloworld_onclick(event)">Run</button>
...
function helloworld_onclick(e) {
alert("Hello world!");
}
If you want to be able to bind events dynamically, if you want to bind multiple events to an object and if you want to keep the JavaScript outside of your HTML, the modern way to to so is with addEventListener.
document.querySelector("#helloworld").addEventListener("click", function(e) {
alert("Hello world!");
});
The event object passed (called e in my functions) contains information about what triggered the event and can be used to prevent default behavior and to control event propagation. You can't use "this" in event handlers, but the element which called the handler will be stored in e.target.
In your code, you created functions which, when called, bind events to the elements. Then you bound those functions to the elements with the html attributes.
Finally, you seem to be stuck between querySelector and getElementById. Note that querySelector(All) returns a static node/nodelist while getElement(s)By(...) returns a live node/nodelist. A static node is a copy of all the information about the element. A live node is a reference to the real element. If you modify the element, it modifies the live node, but the static node will keep the old information. You should use getElementById over querySelector for that, and because it runs faster. For code simplicity however, you might prefer always using querySelector. Just don't mix using querySelector("#something") on a line and getElementById("something") on another one, it's the best way to get confused and end up wasting time on a bug because you wrote querySelector("something") or getElementById("#something") instead.
function changeFont_size (element) {
if(element.options[element.selectedIndex].value != 'select'){
document.getElementById('Title').className = element.options[element.selectedIndex].value;
} else{
document.getElementById('Title').className = '' }
}
function changeAlignment (element) {
if(element.options[element.selectedIndex].value != 'select'){
document.getElementById('container').className = element.options[element.selectedIndex].value;
} else{
document.getElementById('container').className = '' }
}
Try this, Hope it will work

Call a function as if an event called it

I have the following function:
bringToFront : function () {
"use strict";
Desktop.appZ += 1;
this.style.zIndex = Desktop.appZ;
}
This function get's called when certain elements are clicked:
appWindow.addEventListener("mousedown", Desktop.bringToFront, false);
appWindowParent.appendChild(appWindow);
However, if I add some elements to the DOM and click them, thus increasing their z-index, and then add another element, this element will appear behind the first elements, instead of in front of them. So when I add "appWindow" to "appWindowParent", I also want to call "bringToFront" on "appWindow". I need to do this without chaining the "bringToFront" function (i.e. without adding arguments).
Thanks!
By the way, I know I could just increase the z-index manually when I create the element, but I intend to do more things in the "bringToFront" function and I don't want to duplicate that code.
You can use apply() to set the value of this inside the function
appWindowParent.appendChild(appWindow);
Desktop.bringToFront.apply(appWindow);
Detect by following code if a new element is inserted into dom
$(document).on('DOMNodeInserted', function(e) {
if (e.target.id == 'someID') {
}
});

.class selector not working

I'm working in a card game system that the player can select the card by clicking on it and then select the place to put it on. My problem is that when the player click on the target place, nothing happens.
This is my try: http://jsfiddle.net/5qMHz/
And this is my code:
function target() {
$(".target").on("click", function() {
$("#"+x).appendTo(this);
console.log(x);
});
};
What's wrong?
Try binding with document, since you change the class during document ready and there was no element with the class target initially
$(document).on("click",".target", function() {
$("#" + x).appendTo(this);
console.log(x);
}
WORKING FIDDLE
Firstly, your practice of putting function references in to jQuery objects is rather odd. The problem however is that because the .target class is applied after DOM load you need to use a delegate selector. Try this:
var $card
$(".card").on("click", function () {
$card = $(this);
if ($(".myslot").length) {
if ($(".myslot").is(':empty')) {
$(".myslot:empty").addClass("target");
} else {
alert('No empty slots');
}
}
});
$('.field').on('click', ".target", function () {
$card.appendTo(this);
$card = $();
});
Example fiddle
At the moment you are trying to bind the event handler, the elements don't have a class target yet. From the documentation:
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on().
(Technically the elements exist, but they are not (yet) addressable by the class target)
You have three options to solve this:
Add the class to your HTML markup.
Bind the handler after you added the class to the elements.
Use event delegation.
The first two don't really fit to your use case, since your are adding the class target in response to an other event and the number of elements with the class target changes over time. This is a good use case for event delegation though:
$('.field').on('click', '.target', function() {
// ...
});

Categories

Resources