Perform action for only one clicked element of a class - javascript

I have several of these lines in my HTML:
<img src="Iconos/heart.png" alt="Fave" class="fave_icon">
I want to change the 'src' when one of them is clicked (but ONLY on that one)
I tried this but it does not work:
$(document).on('click', '.fave_icon', function (event) {
if ($(this).getAttribute('src') == "Iconos/heart.png")
{
$(this).src = "Iconos/heart_coloured.png";
}
else
{
$(this).src = "Iconos/heart.png";
}
});

this is the function you're in.
The clicked element is event.target. Replace $(this) with $(event.target) and it will work.
For the general case, where the targeted element has children, it's possible that the target of your click is a child (of .fave_icon). Use closest() to target the closest .fave-icon:
$(document).on('click', '.fave_icon', function(event) {
let elem = $(event.target).closest('.fave_icon');
if (elem.getAttribute('src') == "Iconos/heart.png") {
elem.src = "Iconos/heart_coloured.png";
} else {
elem.src = "Iconos/heart.png";
}
});

I ended up solving it like this:
<img src="Iconos/heart.png" onclick="fav(this);" alt="Fave" class="fave_icon">
And then
function fav(heart){
if (heart.getAttribute('src') == "Iconos/heart.png")
{
heart.src = "Iconos/heart_coloured.png";
}
else
{
heart.src = "Iconos/heart.png";
}

Related

How to run only one function if we have multiple class

So. to begin with,
I am writing my eventlisteners in this way.
document.addEventListener('click',(e)=>{
const element = e.target;
if(element.classList.contains('classOne'){
fire_function_one();
}
if(element.classList.contains('classTwo'){
fire_function_two();
}
});
I have a div like follows
<div class='classOne classTwo'>Something</div>
So what I want to achieve is,
When our div has classOne, I want to fire 'fire_function_one()', However when our div has both classOne and ClassTwo, I want to fire 'fire_function_two()' but I dont want to run 'fire_function_one()'.
What I have tried,
event.stopPropogation; //Not working
event.preventDefault; //Not working
if(element.classList.contains('classTwo' && !element.classList.contains('classOne'){
fire_function_two();
//Doesnt acheive what I want
}
Change the Order of your condition and use else if statement.
document.addEventListener('click',(e)=>{
const element = e.target;
if(element.classList.contains('classTwo'){
fire_function_two();
}
else if(element.classList.contains('classOne'){
fire_function_one();
}
});
If you are sure that the element can have classOne or both classTwo and classOne, you can just change the order and use else if statement:
document.addEventListener('click',(e)=>{
const element = e.target;
if(element.classList.contains('classTwo'){
fire_function_two();
} else if(element.classList.contains('classOne'){
fire_function_one();
}
});
You need to write click on element as below.
var eleOne = document.getElementsByClassName('classOne')
if(eleOne.length > 0) {
var currentEleOne = eleOne[0];
currentEleOne.onclick = function () {
// Click code for classOne
}
}
var eleTwo = document.getElementsByClassName('classTwo')
if(eleTwo.length > 0) {
var currentEleTwo = eleTwo[0];
currentEleTwo.onclick = function () {
// Click code for classTwo
}
}
Here you have two cases,
When both classes are present, fire only class two
If only class one is present, fire class one
So, First check with if whether both classes are present or not. If true then fire class two. Otherwise inside else if, check if class one is present and if this condition is met, fire class one.
document.addEventListener('click', function(e) {
const element = e.target;
if (element.classList.contains('classTwo')) {
console.log("Fire class two");
} else if (element.classList.contains('classOne')) {
console.log("Fire class one");
}
});
<div class='classOne classTwo'>Something 1 2</div>
<div class='classOne'>Something 1</div>
You could try a simple ternary like this:
document.addEventListener('click', (e) => {
const element = e.target;
element.classList.contains('classTwo') ? fire_function_two() : fire_function_one();
});
If the classList contains 'classTwo' then run fire_function_two() else fire_function_one()

How to detect click outside an element with a class selector Using Pure Javascript (without using Jquery)

I want to detect clicking outside an element using class name as
selector
<div id="popOne" class="pop">...</div>
<div id="popTwo" class="pop">...</div>
...
<div id="popLast" class="pop">...</div>
<script>
var popElement = document.getElementById("pop");
document.addEventListener('click', function(event) {
var isClickInside = popElement.contains(event.target);
if (!isClickInside) {
alert("Outside");
//the click was outside the popElement, do something
}
});
</script>
As an alternative to iterating over all possible .pop elements for every click event, just traverse the DOM looking to see if the node or any ancestor thereof has the desired class:
document.addEventListener('click', function(e) {
var node = e.target;
var inside = false;
while (node) {
if (node.classList.contains('pop')) {
inside = true;
break;
}
node = node.parentElement;
}
if (!inside) {
alert('outside');
// click was outside
} else {
alert('inside');
}
});
This would make the performance scale relative to the depth of the DOM tree, rather than by the number of .pop elements.
Made the following changes to the script
var popElement = document.getElementsByClassName("pop");
document.addEventListener('click', function(event) {
for(i=0; i < popElement.length; i++){
popEl = popElement[i];
var isClickInside = popEl.contains(event.target);
if (!isClickInside) {
alert("Outside");
} else {
alert("Inside");
break;
}
}
});
First of all you are using the incorrect function to get Element. It should be getElementsByClassName("pop") and not getElementsById("pop") and also getElementsByClassName returns a HTMLCollection of elements having that class. So you need to loop over them and check whether clicked inside any of them or not. Here is the demo. Have added some style to divs so that it easy to differentiate between them. And also if need to check whether the click was on any of the divs then you need to check for that and as soon as you find that it was clicked inside a div having class pop. Break from the loop and continue with you conditions. But if for all the elements the IsClickedInside comes out to be false then you can handle it accordingly
document.addEventListener('click', function(event) {
var popElement = document.getElementsByClassName("pop");
var isClickInside;
for (var i = 0; i < popElement.length; i++) {
isClickInside = popElement[i].contains(event.target);
if (isClickInside) {
break;
//alert("Outside of" + popElement[i].id);
//the click was outside the popElement, do something
}
}
if(isClickInside){
alert("Clicked inside one of the divs.");
}else{
alert("Clicked outside of the divs.");
}
});
div {
height: 100px;
border:2px solid black;
}
<div id="popOne" class="pop">...</div>
<div id="popTwo" class="pop">...</div>
...
<div id="popLast" class="pop">...</div>
Hope it helps :)

Remove class onclick anything else

This may seem like a really simple question, but I'm having a lot of trouble trying to get it to work.
I have a series of elements spread across different parts of a page.
<span class="click-element"><span>
---
<span class="click-element"><span>
--
<span class="click-element"><span>
I want to toggle a class ("active") on/off on each of them when they are clicked individually, this should also remove the class from all the others.
To do this, my function looks like this:
var targets = document.querySelectorAll('.click-element');
for (i = 0; i < targets.length; i++) {
targets[i].addEventListener('click', function () {
var clicked = this;
if (this.classList.contains("active")) {
[].forEach.call(targets, function (a) {a.classList['remove']('active');});
}
else {
[].forEach.call(targets, function (a) {a.classList[a == clicked ? 'add' : 'remove']('active');});
}
});
}
But what I'm trying to do, is then remove the class when anything else is clicked in the document:
document.addEventListener('click', function () {
document.querySelector('.click-element.active').classList.remove("active");
});
However, the problem I'm having is the second event seems to just override the first. How can I fix this? Or is there a cleaner approach to do what I want?
No jQuery thanks
try to cancle the event bubbling like this:
for (i = 0; i < targets.length; i++) {
targets[i].addEventListener('click', function(e) {
var clicked = this;
if (this.classList.contains("active")) {
[].forEach.call(targets, function(a) {
a.classList['remove']('active');
});
}
else {
[].forEach.call(targets, function(a) {
a.classList[a == clicked ? 'add' : 'remove']('active');
});
}
e.stopPropagation();
});
}
Keys:
targets[i].addEventListener('click', function(e) {...
e.stopPropagation();...
Try this :
var targets = document.querySelectorAll('.click-element');
var activeElement; // this should be some global variable
for (i = 0; i < targets.length; i++) {
targets[i].addEventListener('click', function () {
if(activeElement){
activeElement.classList['remove']('active');
}
var clicked = this;
activeElement = this;
if (this.classList.contains("active")) {
[].forEach.call(targets, function (a) {a.classList['remove']('active');});
}
else {
[].forEach.call(targets, function (a) {a.classList[a == clicked ? 'add' : 'remove']('active');});
}
});
}
I think better solution will be to use event bubbling.
If you have a common container:
document.getElementById('#containerId').addEventListener('click', function(evt){
var element = evt.target;
if(element.classList.contains('click-element'){
//toggle active
element.classList[element.classList.contains('active') ? 'add' : 'remove']('active');
} else{
//remove the active from all elements
document.querySelectorAll('.click-element.active').forEach(
function (clickElement, index) {clickElement.classList[remove]('active')}
);
}
});
In your case you don't have child elements in the spans, but if you had you need to check if the clicked element is a descendant of the span.
try jQuery libraries it will make it easy
$( "span" ).removeClass( "yourClass" );
http://api.jquery.com/removeclass/

jQuery .on with .get methods

I am trying to get the tag name of the element clicked inside an li when the user clicks on the element. The li element is added dynamically to the HTML code. To do this I am using the code below however it does not seem to be working.
$('li *','div#contentWrapper').on('click','#interfaceContainer #left #sortableTestComponents li',function(e){
e.stopPropagation();
var domEl = $(this).get(0);
alert(domEl.tagName);
if(!$(event.target).hasClass("deleteTestComp")){
var type = $(this).find('div.headerName').html();
var information = $(this).find('input[type=hidden]').val();
if(type == "CliSessionType"){
parseCliComponent(information);
}
else if(type == "DBSessionType"){
parseDbComponent(information);
}
else{
parseScreenComponent(information);
}
}
});
Why is my code not working? Nothing happens when the user clicks on an element.
JSFiddle - http://jsfiddle.net/3FxQE/
Since you are interested in click events in li elements which comes under #interfaceContainer, the event registration must be $('#interfaceContainer').on('click','li',function(e){...});
Then to get the tagName, you need to use the actual source of the event this is available in e.target so you need to use $(e.target).get(0) to get the clicked dom element.
$('#interfaceContainer').on('click','li',function(e){
e.stopPropagation();
var domEl = $(e.target).get(0);
alert(domEl.tagName);
if(!$(event.target).hasClass("deleteTestComp")){
var type = $(this).find('div.headerName').html();
var information = $(this).find('input[type=hidden]').val();
if(type == "CliSessionType"){
parseCliComponent(information);
}
else if(type == "DBSessionType"){
parseDbComponent(information);
}
else{
parseScreenComponent(information);
}
}
});
Demo: Fiddle
You are trying to use a context where you don't need to, in your selector. Change $('li *','div#contentWrapper') with $('div#contentWrapper') and $(event.target) with $(e.target). A working fiddle is here
$('div#contentWrapper').on('click', '#interfaceContainer #left #sortableTestComponents li', function (e) {
e.stopPropagation();
var $this = $(this),
domEl = $this.get(0);
alert(domEl.tagName);
if (!$(e.target).hasClass("deleteTestComp")) {
var type = $this.find('div.headerName').html(),
information = $this.find('input[type=hidden]').val();
if (type == "CliSessionType") {
parseCliComponent(information);
} else if (type == "DBSessionType") {
parseDbComponent(information);
} else {
parseScreenComponent(information);
}
}
});

jQuery trigger event when click outside the element

$(document).click(function(evt) {
var target = evt.currentTarget;
var inside = $(".menuWraper");
if (target != inside) {
alert("bleep");
}
});
I am trying to figure out how to make it so that if a user clicks outside of a certain div (menuWraper), it triggers an event.. I realized I can just make every click fire an event, then check if the clicked currentTarget is same as the object selected from $(".menuWraper"). However, this doesn't work, currentTarget is HTML object(?) and $(".menuWraper") is Object object? I am very confused.
Just have your menuWraper element call event.stopPropagation() so that its click event doesn't bubble up to the document.
Try it out: http://jsfiddle.net/Py7Mu/
$(document).click(function() {
alert('clicked outside');
});
$(".menuWraper").click(function(event) {
alert('clicked inside');
event.stopPropagation();
});
http://api.jquery.com/event.stopPropagation/
Alternatively, you could return false; instead of using event.stopPropagation();
if you have child elements like dropdown menus
$('html').click(function(e) {
//if clicked element is not your element and parents aren't your div
if (e.target.id != 'your-div-id' && $(e.target).parents('#your-div-id').length == 0) {
//do stuff
}
});
The most common application here is closing on clicking the document but not when it came from within that element, for this you want to stop the bubbling, like this:
$(".menuWrapper").click(function(e) {
e.stopPropagation(); //stops click event from reaching document
});
$(document).click(function() {
$(".menuWrapper").hide(); //click came from somewhere else
});
All were doing here is preventing the click from bubbling up (via event.stopPrpagation()) when it came from within a .menuWrapper element. If this didn't happen, the click came from somewhere else, and will by default make it's way up to document, if it gets there, we hide those .menuWrapper elements.
try these..
$(document).click(function(evt) {
var target = evt.target.className;
var inside = $(".menuWraper");
//alert($(target).html());
if ($.trim(target) != '') {
if ($("." + target) != inside) {
alert("bleep");
}
}
});
$(document).click((e) => {
if ($.contains($(".the-one-you-can-click-and-should-still-open").get(0), e.target)) {
} else {
this.onClose();
}
});
I know that the question has been answered, but I hope my solution helps other people.
stopPropagation caused problems in my case, because I needed the click event for something else. Moreover, not every element should cause the div to be closed when clicked.
My solution:
$(document).click(function(e) {
if (($(e.target).closest("#mydiv").attr("id") != "mydiv") &&
$(e.target).closest("#div-exception").attr("id") != "div-exception") {
alert("Clicked outside!");
}
});
http://jsfiddle.net/NLDu3/
I do not think document fires the click event. Try using the body element to capture the click event. Might need to check on that...
This code will open the menu in question, and will setup a click listener event. When triggered it will loop through the target id's parents until it finds the menu id. If it doesn't, it will hide the menu because the user has clicked outside the menu. I've tested it and it works.
function tog_alerts(){
if($('#Element').css('display') == 'none'){
$('#Element').show();
setTimeout(function () {
document.body.addEventListener('click', Close_Alerts, false);
}, 500);
}
}
function Close_Alerts(e){
var current = e.target;
var check = 0;
while (current.parentNode){
current = current.parentNode
if(current.id == 'Element'){
check = 1;
}
}
if(check == 0){
document.body.removeEventListener('click', Close_Alerts, false);
$('#Element').hide();
}
}
function handler(event) {
var target = $(event.target);
if (!target.is("div.menuWraper")) {
alert("outside");
}
}
$("#myPage").click(handler);
try this one
$(document).click(function(event) {
if(event.target.id === 'xxx' )
return false;
else {
// do some this here
}
});
var visibleNotification = false;
function open_notification() {
if (visibleNotification == false) {
$('.notification-panel').css('visibility', 'visible');
visibleNotification = true;
} else {
$('.notification-panel').css('visibility', 'hidden');
visibleNotification = false;
}
}
$(document).click(function (evt) {
var target = evt.target.className;
if(target!="fa fa-bell-o bell-notification")
{
var inside = $(".fa fa-bell-o bell-notification");
if ($.trim(target) != '') {
if ($("." + target) != inside) {
if (visibleNotification == true) {
$('.notification-panel').css('visibility', 'hidden');
visibleNotification = false;
}
}
}
}
});

Categories

Resources