$(*).click event click it and all of its parent. - javascript

This is my code:
<p>
<div>
<div><span>Hello</span></div>
<span>Hello Again</span>
</div>
<div>
<span>And Hello Again</span>
</div>
</p>
<b>Click Hellos to toggle their parents.</b>
<script>
function showParents() {
$("div").css("border-color", "white");
var len = $("span.selected")
.parents("div")
.css("border", "2px red solid")
.length;
$("b").text("Unique div parents: " + len);
}
$("*").click(function () {
$("b").text($(this).parents().length);
});
</script>
The problem is when I click on a span, this shows 0 instead of 3!
I think the problem is *
Now the question is, how do I get the parent count when I don't know the type of the element?

The problem is event propagation(bubbling). The click event gets propagated to the root of the document from the clicked element triggering each of the click handler associated with those ancestor elements, so when the html element's click handler is triggered there is no more parents so you gets 0 as the result.
Demo: Fiddle - take a look at the console
Instead you can bind the click handler only to the document object then use the event's target property to find the element which triggered the click and find its parents
$(document).click(function (e) {
$("b").text($(e.target).parents().length);
});
Demo: Fiddle

Related

jQuery display property not changing but other properties are

I'm trying to make a text editable on clicking it. Below is the code I'm trying. When the title is clicked it shows an input box and button to save it.
<div class="block">
<div class="title">Title</div>
<div class="title-edit">
<input type="text" name="title" value="Title">
<button>Save</button>
</div>
</div>
I have changed other properties like color or changing the text of the elements and its working, but it is not applying the display property or .show()/.hide() function on the title or edit elements.
Below is my jQuery
$(function(){
$('.block').on('click', editTitle);
$('.title-edit button').on('click', saveTitle);
});
function saveTitle(){
var parent = $(this).closest('.block');
var title = $('.title', parent);
var edit = $('.title-edit', parent);
$(title).show();
$(edit).hide();
}
function editTitle(){
$('.title-edit', this).show();
$('.title', this).hide();
}
Here's the jsfiddle
https://jsfiddle.net/ywezpag7/
I've added
$(title).html('abcd');
to the end to show that other properties/functions are working, but just not the display.
For checking the html change on title element you will have to check the source through developer tools cause the title element is hidden.
Where am I going wrong?
Your problem is in the function saveTitle. The first line must stop the event propagation otherwise after this function the editTitle function is called.
The snippet:
$(function(){
$('.block').on('click', editTitle);
$('.title-edit button').on('click', saveTitle);
});
function saveTitle(e){
// this line
e.stopPropagation();
var parent = $(this).closest('.block');
var title = $('.title', parent);
var edit = $('.title-edit', parent);
title.show();
edit.hide();
title.text($('.title-edit input').val());
}
function editTitle(e){
$('.title-edit', this).show();
$('.title', this).hide();
}
.title-edit{
display:none
}
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<div class="block">
<div class="title">Title</div>
<div class="title-edit">
<input type="text" name="title" value="Title">
<button>Save</button>
</div>
</div>
The issue as mentioned already is that your click events are fighting. In your code, the title-edit class is within the block, so when you click on the save button it triggers events for both clicks.
The easiest and, imho, cleanest way to resolve this is to switch your click event to be called on .title, and .title-edit button. You can also simplify the code beyond what you've got there.
$(function(){
$('.title').click(editTitle);
$('.title-edit button').click(saveTitle);
});
function saveTitle(){
$('.title').show();
$('.title-edit').hide();
$(title).html('abcd');
}
function editTitle(){
$('.title-edit').show();
$('.title').hide();
}
https://jsfiddle.net/ywezpag7/7/
I tried debug your code, and I had seen, that then you click to "Save" button, handled both functions, saveTitle() and editTitle(), and in that order. Therefore, the elements initially hidden, and then shown.

How do I add an event listener to all the childnodes of a div in and array of those div?

I'm teaching myself JS and trying to avoid jQuery until my JS skills are better.
Goal: add an eventlistener, for click event, to all the divs of a certain class. Have all the child nodes of that class respond to the event.
My HTML
<div class="grid-panel six columns">
<div class="grid-panel-image">
<i class="fa fa-css3"></i>
</div>
<div class="grid-panel-title">
<h4>css3</h4>
</div>
</div>
<div class="grid-panel six columns">
<div class="grid-panel-image">
<i class="fa fa-paint-brush"></i>
</div>
<div class="grid-panel-title">
<h4>tamberator</h4>
</div>
</div>
I select all the .grid-panel divs using this JS
var gridPanels = document.querySelectorAll('.grid-panel');
then, since that returns an array of divs with the class .grid-panel
I add the event listener for click as such
for(i=0; i<gridPanels.length; i++){
gridPanels[i].addEventListener('click', myFunction);
}
my function is this
myFunction(){
var e = event.target;
switch(e){
case gridPanels[0]:
modalArray[0].setAttribute("data-modal-display", "show");
break
case gridPanels[1]:
modalArray[1].setAttribute("data-modal-display", "show");
break
}
console.log(e);
}
This does work if I click a very specific part of the .grid-paneldiv and the e logs that specific element. However, clicking any children of the div logs the e as the element i clicked, but the eventlistener is not applied to that element. I'm clearly missing something here with this event delegation. I really want the function to fire on the div clicked and all of its childnodes.
You're binding correctly, but if you want to get the element to which the handler is bound in the handler, then use this or event.currentTarget instead of event.target.
The event.target represents the actual element that was clicked, which is sometimes useful as well.
Also, you should define the event parameter in the function. Not all browsers have it available as a global variable.
function myFunction(event){
var e = this
// var e = event.currentTarget // same as above
switch(e){
case gridPanels[0]:
modalArray[0].setAttribute("data-modal-display", "show");
break
case gridPanels[1]:
modalArray[1].setAttribute("data-modal-display", "show");
break
}
console.log(e);
}

remove onclick when attached to children

I have the following code:
layoutOverlaysBldg = $("#layout-overlays-bldg")
layoutOverlaysBldg.on("click", "div", function(event) {
var floor;
console.log("floornum: " + this.dataset.floornum);
floor = parseInt(this.dataset.floornum);
...
$("#choose-floor").fadeOut();
$("#choose-apt").fadeIn();
});
later - based on data I'm getting back from the DB - I want to remove some of the .on("click", "div", ...) from only some of the divs. I already have the selector that is getting the right divs but I cannot figure out how to remove the click event. I have tried .off("click") after selecting the right div but it has no effect.
This issue here is because you are using a delegated event. You can add or remove the event for all child elements, but not individual ones given your div selector.
With that in mind the easiest way to do what you need is to add the event based on a class, then add and remove that class on the children as needed. Something like this:
layoutOverlaysBldg = $("#layout-overlays-bldg")
layoutOverlaysBldg.on("click", "div.clickable", function(event) {
// your code...
});
You can then enable/disable the event on the child div by adding or removing the .clickable class.
You can try like this :
Example :
<div id="test">
<div id="first">first</div>
<div id="second">second</div>
</div>
<div onclick="unbindSecondDiv();">UNBIND</div>
<script>
function unbindSecondDiv()
{
test = $("#second")
test.unbind("click");
alert('Selected Area Click is Unbind');
}
$(document).ready(function(){
//BIND SELECTED DIV CLICK EVENT
test = $("#test > div")
test.bind("click" , function(event) {
alert($(this).attr('id'));
});
});
</script>
In the above example , selected DIV elements click event is bind.
And after execute function unbindSecondDiv() , second DIV click event will be unbind.
Have a try , may helps you.

Catch the onClick event on `span` tags

I have got a lot of span tags inside my div elements. Each div has a unique id.I want to add an onclick event to the span elements in each div uniquley. How can i do that?
<div class="bootstrap-tagsinput"id="1">
<span class="tag label label-info">Access control lists</span>
<span class="tag label label-info">Network firewall</span>
</div>
<div class="bootstrap-tagsinput"id="2">
<span class="tag label label-info">Access control lists</span>
<span class="tag label label-info">Network firewall</span>
</div>
My current script which catches all the span elements irrespective of the div.
$('span.label-info').click(function() {
var news=$('input[type=text][id="vuln<?php echo $model->v_id;?>"]').val()+','+$(this).text();
$('input[type=text][id="vuln<?php echo $model->v_id;?>"]').val(news);
return false;
});
How can i catch click on span elements inside each div separately?
I think you're looking at it the wrong way. Instead of having a separate click handler for each div, you can keep the shared click handler, but find out which div is the parent, and use its ID in the subsequent selectors.
$('span.label-info').click(function() {
// find the parent/ansector that is a div and has the class
var divId = $(this).closest('div.bootstrap-tagsinput').prop('id');
var news=$('input[type=text][id="vuln' + divId + '"]').val()+','+$(this).text();
$('input[type=text][id="vuln' + divId + '"]').val(news);
return false;
});
Your code should work to add a click even handler to each span.
$('span.label-info').click(function() {
$(this).attr('id'); //<--$(this) is a handle to the clicked span
$(this).parent().attr('id'); //<-- $(this).parent() references the parent div
});
It's worth mentioning, consider changing .click() to .on('click').
Also - if you wanted to bind once without rebinding after spans were dynamically added to the div, you could bind it like this:
$('div').on('click', 'span.label-info').click(function() {
/* <-- do stuff with $(this) or $(this).parent() here --> */
});
http://jsfiddle.net/GZVdL/3/
Hi.
in your span click event you can find parent div and then get its attribute id to find which div it is.
Below is the code
$(document).ready(function(){
$(".tag").click(function(){
alert($(this).parent().attr("id"));
});
});

Jquery click - thinks its the parent element, not the child

When I click on a child element inside a div (the 'butMedWhite ' class) - the jquery thinks that I am clicking on the parent element ('.alternative') - even when I dump 'this' inside the console it says i have clicked on the class 'alternative' (see code below) - not the 'butMedWhite ' class - does anyone have any ideas why?
Here is the html:
<div class="alternative _activeCategory">
<div class="alternative_inner"></div>
<div class="expandable" style="display: block;">
<div class=" criteriaContainer">
<a class="butMedWhite altCreator">add rule</a>
</div>
</div>
</div>
and here is the jquery:
$('.altExpander').on('click', '.alternative', function(e) {
console.log(this);
if(!$(this).hasClass('_activeCategory')){
expandCategory($(this));
}else{
closeCategory();
}
});
Thanks for any help!
jQuery provides as context to your callback the element on which you bound the event handler, just like the native DOM functions.
If you want the clicked element instead, don't use this but e.target :
$('.altExpander').on('click', '.alternative', function(e) {
var clicked = $(e.target);
console.log(clicked);
if(!clicked.hasClass('_activeCategory')){
expandCategory(clicked);
}else{
closeCategory();
}
});
That's because your selector is ".alternative" in this line:
$('.altExpander').on('click', '.alternative', function(e)
If you want this to be the anchor tag, you need to use
$('.altExpander').on('click', '.alternative a', function(e)

Categories

Resources