I'm trying to have the span, on click, toggle its classes between .btn-warning and .btn-primary. However, my code only works for the first click. Every click thereafter doesn't work.
JavaScript
$(document).ready(function(){
$('.btn-warning').on('click',function(){
$(this).removeClass('btn-warning').addClass('btn-primary');
});
$('.btn-primary').on('click',function(){
$(this).removeClass('btn-primary').addClass('btn-warning');
});
});
HTML
<span class="btn btn-warning" >Click me</span>
Changing the class does not magically add the events that were previously added. You either need to unbind/bind the events once again, or use a generic onclick handler that knows how to handle it, or use event delegation.
All that code could be reduced to:
$(".btn").on("click", function() {
$(this).toggleClass('btn-warning').toggleClass('btn-primary');
});
.btn-primary { background-color: blue; }
.btn-warning { background-color: yellow; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<span class="btn btn-warning" >Click me</span>
You need to use event delegation method because you're binding event to dynamically added class element:
$(document).ready(function(){
$(document).on('click','.btn-warning',function(){
$(this).removeClass('btn-warning').addClass('btn-primary');
});
$(document).on('click','.btn-primary',function(){
$(this).removeClass('btn-primary').addClass('btn-warning');
});
});
Simply you may do like this:
$(document).on("click",".btn", function() {
$(this).toggleClass('btn-warning btn-primary');
});
Related
By triggering an onClick event I would like to select the same element the onClick event is attached to, to add a class to that same element. What I tried is the following:
<div class="class1" onClick="TestFunction();">Click</div>
<script>
function TestFunction() {
$(this).addClass('active');
}
</script>
After clicking the div, the class "active" should be added to the same element, resulting in...
<div class="class1 active" onClick="TestFunction();">Click</div>
However this doesn't work. I am wondering whether the this selector works differently in this case.
The structure of the div element should stay the same and also the function should stay in the same place as it is on the onClick attribute.
The reason is this refers to the global Window object inside the function.
You have to pass this to the function so that you can refer that inside the function:
.active{
color:green;
font-size: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="class1" onClick="TestFunction(this);">Click</div>
<script>
function TestFunction(el) {
console.log(this.constructor.name) //Window
$(el).addClass('active');
}
</script>
Though it is better to avoid inline event handler:
$('.class1').click(function(){
$(this).addClass('active');
});
.active{
color:green;
font-size: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="class1">Click</div>
When using an inline handler the function invoked runs under the scope of the window element, not the element which raised the event. To work around that you can pass this as an argument:
<div class="class1" onClick="TestFunction(this);">Click</div>
function TestFunction(el) {
el.addClass('active');
}
However this is not good practice. Inline event attributes are outdated and now considered bad practice. The better way to achieve this is to attach unobtrusive event handlers. In plain JS it would look like this:
<div class="class1">Click</div>
document.querySelectorAll('.class1').forEach(el => {
el.addEventListener('click', function() {
this.classList.add('active');
});
});
In jQuery it would look like this:
<div class="class1">Click</div>
jQuery($ => {
$('.class1').on('click', function() {
$(this).addClass('active');
});
});
This question already has an answer here:
toggleclass not binding click event
(1 answer)
Closed 4 years ago.
I have no idea why this is not working. Seems like such a simple concept. I have some classes being toggled when a button is clicked. These classes just control the display of text open menu and close menu. That part is working, however, I need to have some additional scripts run when the button is clicked when its in it's opened state. When I click the button when it has the class opened then nothing in my button.opened click function happens.. it just runs the button.closed function. What am I doing wrong?
https://jsfiddle.net/dmcgrew/sfvhtahq/7/
$("button.closed").on("click", function(){
console.log("open the menu");
$(this).toggleClass("opened");
$(this).toggleClass("closed");
});
$("button.opened").on("click", function(){
//why does nothing in here happen?
console.log("close the menu");
$(this).toggleClass("opened");
$(this).toggleClass("closed");
});
.expand {width:100px; height:100px; background:red; display:block;}
.close, .open {display:none;}
.opened .close {display:inline;}
.closed .open {display:inline;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="expand closed"><span class="open">open menu</span><span class="close">close menu</span></button>
When you assign these event handlers, no button with class "opened" exists, so that event doesn't get attached to anything.
The easiest way to solve this is to instead assign delegated event handlers to a DOM element that does already exist. Now it doesn't matter whether button.closed or button.opened existed when the handler was assigned; it will check for the existence of the child node when the event occurs.
(In practice it's better to not hang everything on the body; choose a DOM node that's a closer parent to the nodes you're delegating to, but for now body will do:)
$("body").on("click", "button.closed", function(){
console.log("open the menu");
$(this).toggleClass("opened");
$(this).toggleClass("closed");
});
$("body").on("click", "button.opened", function(){
console.log("close the menu");
$(this).toggleClass("opened");
$(this).toggleClass("closed");
});
.opened .open, .closed .close {display:none}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="expand closed">
<span class="open">open menu</span>
<span class="close">close menu</span>
</button>
Meanwhile: it's rarely necessary to have two separate classes controlling the same state change. Treat one state as the default, and add CSS rules only for the other state:
$('body').on("click", "button", function() {
$(this).toggleClass("opened");
if ($(this).hasClass('opened')) {
console.log("opened the menu")
} else {
console.log("closed the menu")
}
});
.expand .close,
.expand.opened .open {
display: none
}
.expand.opened .close {
display: block
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="expand">
<span class="open">open menu</span>
<span class="close">close menu</span>
</button>
Since the .opened class does not exist on the button at assignment, you will have to use an event-delegation approach. Like so:
<div class="dynamic-button">
<button class="expand closed">
<span class="open">open menu</span>
<span class="close">close menu</span>
</button>
</div>
$(".dynamic-button").on("click", "button.closed", function(){
console.log("open the menu");
$(this).toggleClass("opened");
$(this).toggleClass("closed");
});
$(".dynamic-button").on("click", "button.opened", function(){
console.log("close the menu");
$(this).toggleClass("opened");
$(this).toggleClass("closed");
});
For more explanation, read more about $.on().
Try unbinding the click event first and then binding it again.
$("button.opened").off("click").on("click", function(){
console.log("close the menu");
$(this).toggleClass("opened");
$(this).toggleClass("closed");
});
This question already has answers here:
Add click event on div tag using JavaScript
(6 answers)
Closed 5 years ago.
I have a <div> that I have formatted very carefully to look nice, and I need to make it have the functionality of a button. How would I go about doing this?
You can give that div tag a onclick function as follows.
function myfns() {
console.log("Clicked")
}
<div id="btn" onclick="myfns()">Click</div>
First recommendation is to use a <button> instead. You can style that however you want as well. If that is not an option for some reason, you'll have to do a few different things to create a proper button out of a div element (to ensure that it works with keyboard and screen readers).
Add click handler. Eg btn.addEventListener('click', clickHandler);
Add enter key handler. Eg btn.addEventListener('keyup', keyHandler);
Add button role. role="button"
Add it to tab order: tabindex="0"
var buttons = document.querySelectorAll('.btn');
buttons.forEach(function (btn) {
btn.addEventListener('click', function(e) {
console.log('clicked');
});
btn.addEventListener('keyup', function(e) {
if (e.key === 'Enter') {
console.log('keyup');
}
});
});
.btn {
display: inline-block;
background: #eee;
border: 1px solid #aaa;
padding: 6px;
cursor: pointer;
}
<div class="btn" role="button" tabindex="0">My Button</div>
<div class="btn" role="button" tabindex="0">My Button</div>
<div class="btn" role="button" tabindex="0">My Button</div>
document.getElementByID("#divID").addEventListenet('click',()=>{
//write your logic
})
handle all button event similarly
e.g. doubleclick etc
Like if you have div
<div class="demo" >
....
</div>
And If you are using javascript
document.getElementsByClassName('demo')[0]
.addEventListener('click', function (event) {
// do something
});
using jquery u can do like
$(".demo").click(function(){
//do something
});
I'm trying to modify the css properties of a div by triggering a click event. For some reason, this isn't happening and it's driving me crazy. Do you know why this happens?
The event looks like this:
$("#colButton3").on("click", function() {
unCollapse('#CarouselSpace','#CarouselBody');
});
The unCollapse function is this:
var unCollapse = function(headerElement, bodyElement) {
$(headerElement).css('margin-top', '1500px');
$(bodyElement).css('min-height', '820px');
};
And the button itself is generated with jquery, but its html is:
<button class="btn btn-success" href="#" id="colButton3" style="display: inline-block;">Learn More</button>
The target divs are these:
<div id="CarouselSpace" class="row"><h1 id="CarouselHeader"></h1></div>
<div id="CarouselBody" class="row"></div>
What am I doing wrong?
Thank you guys.
Dynamic elements needs to have the bind on the document not the element itself as the element is loaded after the document loads
$(document).ready(function() {
$(document).on("click", "#colButton3", function() {
unCollapse('#CarouselSpace', '#CarouselBody');
});
});
var unCollapse = function(headerElement, bodyElement) {
$(headerElement).css('margin-top', '1500px');
$(bodyElement).css('min-height', '820px');
};
#CarouselBody,
#CarouselSpace {
border: 1px solid #ff6600;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="CarouselSpace" class="row">
<h1 id="CarouselHeader">Header</h1>
</div>
<div id="CarouselBody" class="row">Body</div>
<button id=colButton3>button
</button>
The code should work, you are probably trying to bind click event before you create the button. Try using $.live or bind after creating the button.
How do I listen a mouseover event from shadow DOM. I did try as snipcode below but nothing happen. The template instance is generated after button Add is clicked and I register mouseover event for it and hopping this event is fired when mouseover.
Thank a lot
HTML
<body>
<h1 class="text-center">Test import Node</h1>
<div class="container-fluid" style=" background-color: #FAFAFA"></div>
<div class="col-md-12" id = 'root'>
<button type="button" class="btn btn-default go" id='_add'><i class="fa fa-pencil-square-o"></i> Add</button>
<div id = 'textbox' style="height: 200px; width: 400px; font-size: 18px"></div>
</div>
<template id = 'area'>
<div style="height : 400px; width: 300px ; background-color: red"></div>
</template>
</body>
Javascript
$(document).ready(function() {
var button = document.querySelector('#_add');
button.addEventListener('click', function(){
check();
}, false);
});
function check(){
// document.querySelector('#textbox').innerHTML = "Ukie";
var content = document.querySelector('#area').content;
content.addEventListener('mouseover', function(){
display();
}, false);
var root = document.querySelector('#root');
root.appendChild(document.importNode(content, true));
}
function display(){
document.querySelector('#textbox').innerHTML = "Here";
}
As per addEventListener docs:
The event target may be an Element in a document, the Document itself, a Window, or any other object that supports events (such as XMLHttpRequest).
Therefore element must exist in the DOM, when you call addEventListener on it.
As a workaround, you can use event delegation using jquery on method to achieve the same. Here is a working jsfiddle by tweaking your sample a bit.
$('#root').on('mouseover', '.dyn', function(){
display();
});
Here bound element will be parent of template content(about which you are sure that it will exist while binding event) and you'll pass selector of your content html to .on method as argument. Thus whenever event occurs on child(in this case your template content) it will bubble up to parent and callback will be triggered.
You can use on function with jQuery. With on function you can "bind" events on element which not created in the DOM when the code was executed.
Read this: http://api.jquery.com/on/