have parent div clickable with clickable child div - javascript

How do I do something like:
<div onclick="foo1()">
<div onclick="foo2()"></div>
</div>
When I do that and I click the child element, it still runs the foo1() function. How do I temporarily disable the parent element or something?

With jQuery, you can use this: http://api.jquery.com/event.stopPropagation/

I have created a working EXAMPLE for you
HTML
<div id="parent">
<div id="child"></div>
</div>
CSS (just to distinguish the two divs)
#parent {
background-color: black;
width: 220px;
height: 220px;
}
#child {
position:relative;
background-color: blue;
width: 110px;
height: 110px;
top:160px;
left:160px;
}
JavaScript ( include jQuery )
$(document).ready(function(){
$('#child').click(function() {
alert('Child');
if (!e) var e = window.event;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
});
$('#parent').click(function() {
alert('Parent');
});
});
When you click on the child ONLY the action from the child is getting actioned.
You can modify my example as you like to achieve what you need.
Hope this works for you.

Yes, jQuery can solve your problem. See the code below:
<script src="jquery.js" type="text/javascript"></script>
<script>
function a()
{
alert('parent');
}
$(document).ready(function(){
$('#div2').click(function(e){alert('child');e.stopPropagation();})
})
</script>
<div onclick="a();" style="height:100px;width:100px;border:1px solid red">
<div id="div2" style="height:85px;width:85px;border:1px solid green">
</div>
</div>

You can try
<div onclick="foo1(event)">
parent
<div onclick="foo2(event)">child</div>
</div>
And
function foo1(e){
console.log('foo1', e)
}
function foo2(e){
e.stopPropagation();
console.log('foo2', e)
}
Demo: Fiddle

Related

How can I prevent parent element event execution from code inside children event

My question in the title probably looks vague. And I sketched an example for the question:
container.onclick = () => {
alert(0);
};
content.onclick = () => {
alert("how can I prevent here appearance alert(0) from parent element event?");
//how can I prevent parent event by content clicked?
};
#container{
height: 100px;
background-color: gray;
}
#content{
height: 50px;
width: 150px;
background-color: green;
}
<div id="container">
<div id="content"></div>
</div>k
This is a simple example. In a real project, I can't combine these two events into one, because the first one is programmatically assigned somewhere in the bowels of my framework and it shouldn't be removed from the EventListener after clicking on content
In General, is it possible to somehow interrupt the execution of the call chain event by clicking in the DOM layers? I tried to do this:
content.onclick = () => {
alert("how can I prevent here appearance alert(0) from parent element event?");
e.preventDefault();
return false;
//how can I prevent parent event by content clicked?
};
But this, of course, was not successful
You should pass the event by dependency injection to the specific method (content.onclick) and then stop the propagation of it.
container.onclick = () => {
alert(0);
};
content.onclick = (e) => {
e.stopPropagation();
alert("VoilĂ , this prevent that appears alert(0) from parent element event.");
};
#container{
height: 100px;
background-color: gray;
}
#content{
height: 50px;
width: 150px;
background-color: green;
}
<div id="container">
<div id="content"></div>
</div>
For this, you can use stop propogation of js like this
<div id="container">
<div id="content" onclick="event.stopPropagation();">
</div>
</div>
So when you click on content it will not trigger container event only.

Can i have a child div hide its parent div along with it when clicked?

For example :
<div id="parent">
<div id="child">Click here</div>
</div>
when i click on child, both div will disappear or hidden
You can do by using jquery on() and hide() function. Once you html properly render or loaded then following code will be ready to execute, this is beacuse of $(document).ready(function() {...Execute Once HTML Render...});
So the following code will be functional only click event as you see i am using on('click',function(){...});
$(document).ready(function() {
$( "#child" ).on('click',function(){
$(this).parent().hide();
});
});
Here is an example
Try this using jQuery
$("#child").on('click',function(){
$(this).parent().hide();
});
Link for reference
hope this helps...
Here you go with an working example https://jsfiddle.net/fdaqsks2/
$("#child").click(function(){
$(this).parent().hide();
})
#parent{
padding: 20px;
background: red;
}
#child {
padding:5px;
background: blue;
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent">
<div id="child">Click here</div>
</div>

Javascritpt change class to a div near to his grand-father

I want to dynamically change the class of the element #sidePanel from .compact to .expanded, in this code:
<div id="sidePanel" class="compact"></div>
<div id="topbar">
<div id="buttonContainer">
<div id="button"></div>
</div>
</div>
I'm stuck here, I can't apply the class to the correct <div>, I can just add the class to the topbar:
$(document).ready(function(){
$("#button").mouseover(function(){
$("this").parent().eq(2).addClass(".expanded").removeClass(".compact");
});
});
I also tried this:
$(document).ready(function(){
$("#button").mouseover(function(){
$("#sidepanel").addClass(".expanded").removeClass(".compact");
});
});
Your second example was pretty close. When you $.addClass() and $.removeClass(), or are referring to classnames outside of using a selector to target something, just reference the class name (no need for the leading .). Also JS (and CSS) are case-sensitive, so $('#sidepanel') won't target #sidePanel - the cases need to match.
$("#button").mouseover(function() {
$("#sidePanel").addClass("expanded").removeClass("compact");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style>.expanded {color: red;}</style>
<div id="sidePanel" class="compact">sidepanel</div>
<div id="topbar">
<div id="buttonContainer">
<div id="button">button</div>
</div>
</div>
In your first example, $(this) is how you reference this in jQuery. If you put this in quotes, the word this is treated as a string literal instead. And since to use $.parent() you would need to go up 2 levels, you should use $.parents() with the ID of the parent you want to target, then use $.prev() to select the previous element, which is #sidePanel. So to traverse the DOM like that, this is how I would do it.
$("#button").mouseover(function() {
$(this).parents('#topbar').prev().removeClass('compact').addClass('expanded');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style>.expanded {color: red;}</style>
<div id="sidePanel" class="compact">sidepanel</div>
<div id="topbar">
<div id="buttonContainer">
<div id="button">button</div>
</div>
</div>
Your problem is you used $("#sidepanel") instead of $("#sidePanel")
Here's a working example after the change is made:
$(document).ready(function(){
$("#button").on('mouseover', function(){
$("#sidePanel").addClass("expanded").removeClass("compact");
});
});
#topbar > div {
width: 100px;
height: 30px;
background: #ccc;
margin-top: 20px;
}
#sidePanel {
width: 100%;
height: 40px;
background: #ccc;
}
#sidePanel.expanded {
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="sidePanel" class="compact"></div>
<div id="topbar">
<div id="buttonContainer"></div>
<div id="button"></div>
</div>
first: the solution
$(document).ready(function()
{
$("#button").mouseover(function()
{
// class names - without the dot
$("#sidepanel").addClass("expanded").removeClass("compact");
});
});
then: why you were really close on your first attempt
$(document).ready(function()
{
$("#button").mouseover(function()
{
// $(this) selector uses the `this` keyword (not as a string)
$(this).parent().eq(2).addClass(".expanded").removeClass(".compact");
});
});

How can I get outer div target with event.target?

I'm making web service with javascript (and jQuery), and I'm trying to make custom menu.
But the main point is "Widget's ID which is clicked by user".
I want to return widget's id (like widget1 or widget2),
even if user pressed inner objects (img, textarea, etc.)
I tried event.target.id but it returns inner object's id, not outer div.
How could I solve this problem?
JavaScript and HTML :
$("#wrapper_widgets").bind("contextmenu", function(event) {
event.preventDefault();
alert(event.target.id);
});
<div id="wrapper_widgets">
<div id="widget1">
<img src="blablabla.png">
<textarea id="widget1_textarea">blablabla</textarea>
</div>
<div id="widget2" style="border: 1px solid blue; width: 500px; height: 100px;">
<p id="widget2_timedoc">asdasdasd</p>
</div>
</div>
The problem is event.target will refer to the element from which the event was originated from, so you will have to find the closest ancestor widget element
One easy solution is to use a class to all the widgets and target it
<div id="wrapper_widgets">
<div id="widget1" class="widget">
<img src="blablabla.png">
<textarea id="widget1_textarea">blablabla</textarea>
</div>
<div id="widget2" class="widget" style="border: 1px solid blue; width: 500px; height: 100px;">
<p id="widget2_timedoc">asdasdasd</p>
</div>
</div>
then
$("#wrapper_widgets").on("contextmenu", '.widget', function (event) {
event.preventDefault();
alert(this.id);
});
or
$("#wrapper_widgets").bind("contextmenu", function(event) {
event.preventDefault();
alert($(event.target).closest('.widget').attr('id'));
});
You can use .closest('div') with .prop() to get the immediate ancestor ID.
$(event.target).closest('div').prop('id')
Note : This would work only if there is no further nesting of <div>s inside wrappers.
$("#wrapper_widgets").bind("contextmenu", function (event) {
event.preventDefault();
alert($(event.target).closest('div').prop('id'));
});
$("#wrapper_widgets").bind("contextmenu", function (event) {
event.preventDefault();
alert($(event.target).closest('div').prop('id'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper_widgets">
<div id="widget1">
<img src="blablabla.png">
<textarea id="widget1_textarea">blablabla</textarea>
</div>
<div id="widget2" style="border: 1px solid blue; width: 500px; height: 100px;">
<p id="widget2_timedoc">asdasdasd</p>
</div>
</div>
In the event function use
$(this).parent().prop('id')
to get the immediate parent's id of the clicked element. This will always return the immediate parent and not necessarily only divs but in your case it will work and return 'widget1' or 'widget2'.

New class keeps old class behaviour

I'm taking by first babysteps in jQuery and stumbled upon a problem I can't seem to get around.
I couldn't find an article that quite described what my problem was, so I would like to try to get an answer this way.
I don't understand why my objects keep behaving like their former class.
When I setup a hover action for a class, and change the class of the object by clicking, jQuery keeps doing the animation for the new class.
I used toggleClass() and removeClass/ addClasswithout any result:
https://jsfiddle.net/biest9160/f0na6sro/
var wide = function() {
$(this).animate({ 'width': '120px' }, 200);
}
var normal = function() {
$(this).animate({ 'width': '100px' }, 200);
}
$(document).ready(function() {
$('.class1').hover(wide, normal);
$('.class1').click(function() {
$(this).toggleClass('class1 class2');
})
})
div {
width: 100px;
height: 100px;
border: 1px solid #000;
margin: auto;
}
.class2 {
background: #555;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="box1" class="class1">box1</div>
<div id="box1" class="class1">box2</div>
<div id="box1" class="class1">box3</div>
<div id="box1" class="class1">box4</div>
I don't understand why the the hover action is triggered while the object has a new class.
Initialy you attach the event to the element with the class name. After the class is changed the event remains on the element.
To remove the event you can use .unbind. To remove .hover event you can check this answer.
A working example using .unbind to remove the event and after to reattach it will look like in the snippet (basically is toggle hover event):
var wide = function(){
$(this).animate({'width':'120px'},200);
}
var normal = function(){
$(this).animate({'width' : '100px'},200);
}
$(document).ready(function(){
$('.class1').hover(wide,normal);
$('.class1').click(function(event){
var $this = $(this);
$this.unbind('mouseenter mouseleave'); // remove hover
if( $this.hasClass('class2'))
{
$this.hover(wide, normal); // reattach hover
}
$this.toggleClass('class1 class2');
})
})
div{
width:100px;
height:100px;
border: 1px solid #000;
margin: auto;
}
.class2{
background: #555;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="box1" class="class1">box1</div>
<div id="box1" class="class1">box2</div>
<div id="box1" class="class1">box3</div>
<div id="box1" class="class1">box4</div>
Use .on() menthod to bind the event which will actually bind the event on the parent of the class.
Here is the example:
$(document).on("click", '.class1', function(){
$(this).toggleClass('class1 class2');
});
This will defiantly work...

Categories