I have a parent <a> with an href attribute. I have a child <p> and I want a small box to be opened when I click on child element.
The problem is when I click on the child element, it opens the small box but after a second the parent link opens up too. I don't want the parent link to be opened when I click on child element. I added event.stopPropagation() but it doesn't change anything. I also added z-index property but no changes either.
In my JS Fiddle demo you can see a live example; but here is my code so far:
.parent {
background-color: blue;
display: inline-block;
width: 400px;
height: 300px;
z-index: 1;
}
.child {
color: black;
background-color: yellow;
display: inline-block;
width: 100px;
height: 50px;
z-index: 2;
}
[title] {
position: relative;
display: inline-flex;
justify-content: center;
}
.child:focus::after {
content: attr(title);
position: absolute;
top: 90%;
color: #000;
background-color: #fff;
border: 1px solid;
width: fit-content;
padding: 3px;
font-size: 10px;
z-index: 20;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<a class="parent" href="https://www.google.com/">
<p class="child" title="This is mobile tooltip" tabindex="0" (click)="$event.stopPropagation();">Click</p>
</a>
JS Fiddle demo
PS: I cannot use jQuery.
Thanks.
Let me explain What I did was create a variable that changed whenever it hovered on the element or off the element. Next Whenever the user clicked on it I just ran a check to see if the mouse was not hovering on the element and executed a code if was on the element I ran a other code
var mouse = false;
function mouseStatus(n) {
mouse = n;
}
function parent() {
if (mouse == false) {
console.log('parent');
window.open('www.google.com');
}
}
function child() {
console.log('child');
}
.parent {
background-color: blue;
display: inline-block;
width: 400px;
height: 300px;
z-index: 1;
}
.child {
color: black;
background-color: yellow;
display: inline-block;
width: 100px;
height: 50px;
z-index: 2;
}
[title] {
position: relative;
display: inline-flex;
justify-content: center;
}
.child:focus::after {
content: attr(title);
position: absolute;
top: 90%;
color: #000;
background-color: #fff;
border: 1px solid;
width: fit-content;
padding: 3px;
font-size: 10px;
z-index: 20;
}
<a class="parent" onclick="parent()">
<p class="child" title="This is mobile tooltip" onmouseover="mouseStatus(true);" onmouseout="mouseStatus(false);" onclick="child()">Click</p>
</a>
call a function instead :
onEvent(event) {
event.stopPropagation();
return false;
}
calling the function with
(click) ="onEvent($event)"
Related
I have a custom select list which I did with checkbox and label elements.
Then I added a little JS script that changes options on click.
It works perfectly, except you can't close it on click outside of it or its child elements.
I tried to use event listener(commented in snippet) to track if the click was done outside and if it is - change checkbox status on 'false' and it kinda worked, however, it breaks the original checkbox functionality and you can't now close it in any way except for clicking outside of it. Is there a way I can fix this?
//SELECT FROM LIST
function selectList(id) {
let selected = document.getElementById('selected');
selected.innerHTML = id;
}
//BREAKS CHECKBOX
//window.addEventListener('mouseup', function(event){
// let checkbox = document.getElementById('checkbox');
// if (event.target != checkbox && event.target.parentNode != checkbox){
// checkbox.checked = false;
// }
// });
.btn {
display: block;
width: 100px;
height: 50px;
text-align: center;
color: white;
background: black;
border-radius: 15px;
line-height: 50px;
cursor: pointer;
user-select: none;
position: relative;
}
.btn:active {
background: grey;
}
.btn ul {
display: none;
list-style: none;
color: black;
flex-direction: column;
margin: 0;
padding: 2.5px 5px;
left: 0;
top: 50px;
background: grey;
border-radius: 15px;
position: absolute;
}
.btn ul li {
display: block;
width: 90px;
height: 35px;
line-height: 35px;
background: black;
border-radius: 15px;
color: white;
margin: 2.5px 0;
}
.btn ul li:active {
background: grey;
}
/* CHECKBOX CHEKCED */
#checkbox:checked + .btn ul {
display: flex;
}
<input type="checkbox" id="checkbox">
<label class="btn" for="checkbox">
<span id="selected">SELECT</span>
<ul>
<li onclick="selectList('Opt1')">Opt1</li>
<li onclick="selectList('Opt2')">Opt2</li>
<li onclick="selectList('Opt3')">Opt3</li>
</ul>
</label>
Your strategy uses css to style the state of the dropdown based on the radio option value.
So there's no event handler in place already catching that point in time and the only approach to close the dropdown when you click outside, was using a click event handler on the main document and check for the element triggering the event to be of type HTML. Not the best approach indeed. (I edited the question to use a better approach... there's a container having the class dropdown now and event.target gets checked for having an ancestor with such class to understand if the click was fired from the dropdown itself or outside of it)
document.addEventListener('click', function(event){
if(event.target.closest('.dropdown') === null){
document.querySelector('#checkbox').checked = false;
}
});
Anyway once there, the logic just force the radio option to unchecked and restore the dropdown collapse state.
//SELECT FROM LIST
function selectList(id) {
let selected = document.getElementById('selected');
selected.innerHTML = id;
}
document.addEventListener('click', function(event){
if(event.target.closest('.dropdown') === null){
document.querySelector('#checkbox').checked = false;
}
});
//BREAKS CHECKBOX
//window.addEventListener('mouseup', function(event){
// let checkbox = document.getElementById('checkbox');
// if (event.target != checkbox && event.target.parentNode != checkbox){
// checkbox.checked = false;
// }
// });
.btn {
display: block;
width: 100px;
height: 50px;
text-align: center;
color: white;
background: black;
border-radius: 15px;
line-height: 50px;
cursor: pointer;
user-select: none;
position: relative;
}
.btn:active {
background: grey;
}
.btn ul {
display: none;
list-style: none;
color: black;
flex-direction: column;
margin: 0;
padding: 2.5px 5px;
left: 0;
top: 50px;
background: grey;
border-radius: 15px;
position: absolute;
}
.btn ul li {
display: block;
width: 90px;
height: 35px;
line-height: 35px;
background: black;
border-radius: 15px;
color: white;
margin: 2.5px 0;
}
.btn ul li:active {
background: grey;
}
/* CHECKBOX CHEKCED */
#checkbox:checked + .btn ul {
display: flex;
}
<div class="dropdown">
<input type="checkbox" id="checkbox">
<label class="btn" for="checkbox">
<span id="selected">SELECT</span>
<ul>
<li onclick="selectList('Opt1')">Opt1</li>
<li onclick="selectList('Opt2')">Opt2</li>
<li onclick="selectList('Opt3')">Opt3</li>
</ul>
</label>
</div>
I have a simple emoji picker and the ballon remains open as default when the page is refreshed, I can't find a way how to keep it close and only open the ballon when pressing a button.
HTML
<div class="container">
<div class="emoji-btn open"><img src='images/smileys.png' title='Smileys'>
<!--this is the div I want to keep hidden till I click the button > --> <div class="emoji-popup">
<div class="emoji-wrapper"></div>
</div>
</div>
</div>
JS
emojibtn.addEventListener("click", function (e) {
e.stopPropagation();
this.classList.toggle("open");
});
document.body.addEventListener("click", function () {
emojibtn.classList.remove("open");
});
CSS
.emoji-popup {
position: absolute;
top: -140px;
left: 10px;
height: 130px;
width: 194px;
background: #999;
border-radius: 2px;
text-align: left;
overflow-y: auto;
opacity: 0;
pointer-events: none;
transition: all 0.25s;
box-sizing: border-box;
}
.emoji-wrapper {
overflow: hidden;
padding: 10px;
box-sizing: border-box;
}
.emoji-popup .emoji-img {
margin: auto;
width: 30px;
height: 30px;
text-align: center;
border-radius: 5px;
}
.emoji-popup .emoji-img:hover {
background: rgba(0, 0, 0, 0.25);
}
You can add the property display: none; ( https://developer.mozilla.org/en-US/docs/Web/CSS/display), visibility: hidden(https://developer.mozilla.org/en-US/docs/Web/CSS/visibility) or opacity: 0; (https://developer.mozilla.org/en-US/docs/Web/CSS/opacity). Then onClick you can add the class open with the properties display: block (if it's a div), visibility: visible or opacity: 1.
html
<div id="speech"></div>
<div id="test"></div>
<div id="testt"></div>
css
/*speech bubble*/
.bubble {
position: relative;
width: auto;
height: 40px;
padding-left: 10px;
padding-right: 10px;
background: #FFFFFF;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
font-family: sans-serif;
font-size: 15px;
display: inline-block;
left: 17px;
vertical-align: middle;
line-height: 40px;
max-width: 240px;
float: left;
clear: both;
}
.bubble:after {
content: '';
position: absolute;
border-style: solid;
border-width: 10px 10px 10px 0;
border-color: transparent #FFFFFF;
display: block;
width: 0;
z-index: 1;
left: -10px;
top: 10px;
}
#test, #testt {
height: 100px;
width: 100px;
}
#speech {
height: 500px;
width: 200px;
float: right;
overflow-y: scroll;
background-color: #000;
}
javascript
$(document).ready(function () {
"use strict";
$("#test").click(function () {
$("#speech").append('<p class="bubble">test223123</p>');
});
$("#testt").click(function () {
$("#speech").append('<p class="bubble">test</p>');
});
});
When I click on "test" a few times, the speech bubbles that are appended into the speech div continues to go downwards but the scroll thing stays at the top.
How do i make it such that the scroll bar goes to the bottom whenever new speech bubbles are added?
Very simple, just use the scrollTop function. Add this single line:
$('#speech').scrollTop($('#speech').height());
You're now simply appending your bubble. When the bubble is appended, you find the height of your div and you use this value to scroll down.
I have made a little codepen where you can view all the code.
do not use height, but scrollHeight
$(document).ready(function () {
"use strict";
$("#test").click(function () {
$("#speech").append('<p class="bubble">test223123</p>').scrollTop($("#speech").prop("scrollHeight"));
});
$("#testt").click(function () {
$("#speech").append('<p class="bubble">test</p>').scrollTop($("#speech").prop("scrollHeight"));
});
});
So My code do when i click on name(class ='frnd'), then in result open one window and it is drag-able but when i again click on (class =frnd) then their open again new windows, for example if i click on Simon there popup new windows and after one click it is drag-able and than once more i click on name(class ='frnd' (Simon)) its popup one more window again. Problem: I dont want that if the window is already open, it wont open again same window Simon.
For avoid this problem i was trying this code in js
if(!($("#windows").hasClass('.5647383'+id))){
$html = '<div class="mwindow "><div class="hwindow 5647383'+id+'">'+usr+'<span class="cls">x</span></div><div class="msgbody '+id+'"><div id="mstd"class= umsg'+id+'></div><div id="tarea"><form method="post"><textarea class="ctarea" name="'+id+'"></textarea></form></div></div></div>';
$('#windows').append($html);
}
I don't know why isnt working thiscondition if($("#windows").hasClass('.5647383'+id)).
$(document).ready(function(){
$('.frnd').click(function(){
var id = $(this).attr("id");
var usr=$(this).text();
var exst = document.getElementsByClassName('.5647383'+id);
if($("#windows").hasClass('.5647383'+id)){
$html = '<div class="mwindow "><div class="hwindow 5647383'+id+'">'+usr+'<span class="cls">x</span></div><div class="msgbody '+id+'"><div id="mstd"class= umsg'+id+'></div><div id="tarea"><form method="post"><textarea class="ctarea" name="'+id+'"></textarea></form></div></div></div>';
$('#windows').append($html);
}
});
$('#windows').on('click','.cls', function(){
$(this).parent().parent().hide();
});
$(function(){
$('.frnd').click(function(){
var id = $(this).attr("id");
$('#windows').on('click','.'+id,function(){
$(this).parent().draggable({
handle: ".hwindow",
containment:"body"
});
});
});
});
});
body {
margin: 0;
background-color: #999;
height: 700px;
}
.frnd {
text-align: center;
width: 50px;
height: 20px;
display: inline-block;
background-color: #9B59B6;
margin: 5px;
border: 4px solid #3498DB;
color: #F1C40F;
cursor: pointer;
float: right;
}
.mwindow {
position: fixed;
width: 220px;
height: 220px;
border: 5px solid #16a085;
background-color: #fff;
display: block;
margin: 5px;
border-radius: 10px;
}
.mwindow:hover {
z-index: 9999;
}
.hwindow {
width: 210px;
height: 25px;
background-color: #FF4500;
padding: 5px;
display: block;
margin: 0px;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.cls {
display: inline-block;
float: right;
cursor: pointer;
font-size: 20px;
font-weight: bold;
}
.msgbody {
position: relative;
height: 185px;
background-color: #FF4500;
//z-index:9999;
}
.ctarea {
position: absolute;
width: 210px;
resize: none;
outline: none;
top: 133px;
font-size: 15px;
padding: 5px;
min-height: 40px;
opacity: 0.9;
border: none;
border-top: 2px solid #ff0000;
}
#mstd {
position: absolute;
width: 220px;
height: 133px;
background-color: #bb4500;
opacity: 1;
overflow-x: hidden;
}
<script src="//code.jquery.com/jquery-2.1.4.js"></script>
<script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<li id="7" class="frnd">Maxi</li>
<li id="8" class="frnd">John</li>
<li id="9" class="frnd">Henry</li>
<li id="10" class="frnd">Max</li>
<li id="11" class="frnd">Simon</li>
<div id="windows"></div>
Elements by their ID attribute are selected using the hashmark symbol, so
'.' + id should be '#' + id.
The dot symbol (.) selects elements by their class name.
http://codepen.io/anon/pen/qdaXgX
EDIT
You had a number of other problems, look at the reviewed code:
http://codepen.io/anon/pen/bdwaWx
The problem is hasClass() doesn’t use a period prefix for classes — that’s selector syntax. So:
var hwindow_div = $('.5647383'+id) will find your .hwindow div,
hwindow_div.hasClass('5647383'+id) checks whether it has the class.
A simple example.
PS. while it’s a separate problem, #marekful is correct about the #id syntax.
I´m trying to make an animation that when I click on a search icon, it fadeIn the search input and add a class to make it wider. The problem is that I don´t know how to make it fadeOut in the second click after the search input it´s already displayed:
this is my code:
$('#menu_search').click(function(){
$('.search_input').fadeIn().toggleClass('full');
});
<li id="menu_search">
<div class="search_input_container">
<input type="text" class="search_input" value="Buscar">
</div>
</li>
&#menu_search{
background: url('../img/sprites.png') #000 2px 2px;
width: 34px;
height: 28px;
padding: 0;
margin-right: 0;
a{
display: inline-block;
width: 100%;
height: 100%;
}
.search_input_container{
width: 500px;
height: 30px;
position: absolute;
z-index: 20;
left: -466px;
.search_input{
float: right;
width: 100px;
background: #ffffff;
height: 30px;
border: none;
.round_corners();
.animate();
display: none;
&.full{
width: 772px;
display: block;
}
}
}
}
There's also a fadeToggle in jQuery. Try this:
$('#menu_search').click(function(){
$('.search_input').fadeToggle().toggleClass('full');
});
If it's always the second click, you should use fadeToggle() instead.