Make one element disappear when another element disappears - javascript

Context: I am making a small jQuery library for modals (in-window popups): https://github.com/hypesystem/d_modal.js
When creating a new modal, it is possible to also fade the page. This is done by adding a div with a semi-transparent black background.
When the modal is removed I want the "fade" to disappear as well. But not just when the modal is .remove()'d - I want the fade to disappear in the same way as the modal on any action that makes the modal disappear: fadeOut(), hide(), etc.
Here is a jsFiddle to test in (if you have any ideas): http://jsfiddle.net/n5fqS/
What I'm looking for is one solution that handles all the cases.

there are many ways of hidding elements (removing content of div, changing css "display" property, fadeOut(), hide(), etc, etc) and Jquery does not have a universal event listener that would group all these events. I think you will have to manually trigger a "hide" event as a callback function in all the places where your first div is being hidden. For example:
$(".dismiss").click(function() {
$("#div-one").hide(function(){
$(this).trigger('hide');
});
});
Then you only have to have once the event handler:
$("#div-one").on('hide', function(){
//code that hides my second div
)};
Of course, you will have to manually add the trigger every place where relevant. So its not "the one solution".

you can use jquery dialog to achieve this functionality.

The short answer seems to be: jQuery does not emit events on hide.
In order to combat this, I have used the best solution I could find, and started an open project to enable sending of the required events: https://github.com/hypesystem/showandtell.js
This should cover, at the moment, the most common use-cases. Any feedback on this is appreciated.

try like this
$(".dismiss").click(function() {
$("#div-one").hide(function(){
$("#div-two").hide('slow');
});
});

Related

Function to change CSS of nested submenu not working (jQuery)

I'm attempting to create a slide-in menu for a mobile website which has nested submenus that also slide in over the primary parent menu. This is done by editing the right style attribute to move each menu off & on screen.
Everything is working properly except that once I open a submenu, the function that's supposed to close the submenu is changing the CSS. The function that contains this instruction itself is executing (as evidenced by a console.log), but the line that edits the CSS is not working.
Here is the function that is having trouble:
$(document).ready(function(){
$('.close-sub-menu').click(function(){
$(this).parent().css("right", "-425px");
console.log("this line is logging correctly");
});
});
Interestingly enough, if I attempt to edit the CSS of background-color or left, it will work. But right will not work.
I've tried using addClass and removeClass instead, referencing the parent's class name directly instead of using this, and inline function calls, but none of it has seemed to work. I think it is either a scoping issue, or perhaps some interference with the parent menu. Either way, I'm not able to figure it out.
Here is a simple example of my problem in a JSFiddle: https://jsfiddle.net/wk4wwfer/2/
JQuery is very acceptable.
Your $('.slide-menu-sub-parent').click function is still firing when you click the close button.
Update your close function to be:
$('.close-sub-menu').click(function(e){
e.stopPropagation(); //Prevents the click event from bubbling up and triggering the other click events registered
$(this).parent().css("right", -425);
}
Fiddle solution.

How can I toggle a the visibility of a DIV element?

I'm trying toggle a DIV element using jQuery, a good example of this implemented is clicking the sign up button on Udemy.
I've implemented something similar using jQuery but I'm sure that to gain the effect I'm looking for, I will have to use JavaScript but its just that I'm don't know how to use JavaScript.
The my implementation be seen in my fiddle here, I've initially set the div to display:none and used jQuery to show the div on button click.
As you can tell with the fiddle, it displays with an enlarging animation instead of just appearing (not sure how to change this) and i'm only unable to make the div disappear by again clicking the button.
Also, how would I go about implementing functionality to make the div disappear by clicking anywhere on the screen?
Thanks to anyone in advance for taking the time to help me out.
The issue you face is that a click on the button is also a click on an area where you would like the pop up to disappear, if it's already shown. Because events bubble, the button click would make the pop up appear and then the document click (which fires after this because of bubbling) would make the pop up immediately disappear.
To solve the problem, you must stop a click on the button from bubbling to the rest of the document as well. You do this with:
event.stopPropagation();
So, what you need to do is make sure that when the button is clicked, the click event doesn't bubble up to the document, where you will have already set up a click event handler that makes the pop up go away:
$(document).on('click', function(event) {
// We want to hide the pop up, but not if you click on
// the pop up itself - - anywhere else, but not the pop up
if(event.target.id !== "pop-up"){
$('#pop-up').hide();
}
});
See this fiddle for a working version: https://jsfiddle.net/0ajpd9go/8/
If you want your div to just appear on the screen change this line:
jQuery('#pop-up').toggle('fast');
to this:
jQuery('#pop-up').show();
Maybe you'd like to give bootstrap modal a try:
http://getbootstrap.com/javascript/#modals
I think what you are looking for is $.fn.toggle();
$.fn.toggle(); toggles the visibility of an element meaning if the element is visible then it will be hidden when toggled and if the element is hidden it will be shown when toggled.
Here is a basic (animation free) example of using toggle:
$(".button-that-toggles").on("click", function() {
$(".div-to-toggle").toggle();
});
Your box toggles with an "enlarging animation" because you used $.fn.slideToggle();
There are three default ways to toggle using jQuery (toggle, fadeToggle and slideToggle)
Here is an example of toggling a element using $.fn.fadeToggle();:
$(".button-that-toggles").on("click", function() {
// NOTE: 250 represents the duration of the animation, meaning that the animation will last 250 milliseconds.
$(".div-to-toggle").fadeToggle(250);
});
Here is an example of toggling a element using $.fn.slideToggle();:
$(".button-that-toggles").on("click", function() {
// NOTE: 250 represents the duration of the animation, meaning that the animation will last 250 milliseconds.
$(".div-to-toggle").slideToggle(250);
});
Also here is an example of how you can hide your div by clicking anywhere on the page:
// listen for a click anywhere in the page
$(document).on("click", function(event) {
// make sure the element that was clicked is not your div
if(!$(event.target).is(".your-div")) {
// you can now hide your div
$(".your-div").hide();
}
});
Also please remember that jQuery is JavaScript as a matter of fact jQuery is a library written in JavaScript.

jQuery click function slow (lagging) on mobile

So i have this click function that toggles a dropdown-menu, but on Smartphones this is slow and not smooth.
Is there any other way to make this dropdown work with a smooth transition on any mobile device using jQuery?
(I've heard about "vclick" but couldn't find out how to make this work.
$j('.dropdown-menu').click(function() {
$j('.dropdown-menu').not(this).children('ul').slideUp("slow");
$j(this).children('ul').slideDown("slow");
});
$j('.dropdown-menu').blur(function() {
$j('.dropdown-inside').hide('slow', function() {
});
});
Try the click on Id rather then class. Class is always slow. So suppose if your dropdown has id like 'myDropdown' then do it like
$j('#myDropdown').click(function(){
//your code here
});
The first part can be simplified to this:
$j('.dropdown-menu').click(function() {
$j('.dropdown-menu').not(this).children('ul').slideToggle(2000);
});
Also, try wrapping the hidden content in a div and giving it a width. When you click on the div, it actually pulls it out of position to measure it before quickly replacing it because JQuery doesn't know the dimensions of your hidden div until it's displayed. So . This could make the whole animation laggy!
Another suggestion:
ID is faster than class. Part of the reason is that ID is supposed to be unique, so the API stops searching after the ID is found in the DOM.
If you must use a class or attribute selector, you can improve performance by specifying the optional context parameter.
Credits
Cause
According to Google :
...mobile browsers will wait approximately 300ms from the time that you tap the button to fire the click event. The reason for this is that the browser is waiting to see if you are actually performing a double tap.
Solution
1. Use fastclick.js to get rid of this 300ms lag
https://github.com/ftlabs/fastclick
2. Use application cache to speed up the load
https://developer.mozilla.org/en-US/docs/Web/HTML/Using_the_application_cache

How to unbind() .hover() but not .click()?

I'm creating a site using Bootstrap 3, and also using a script that makes the dropdown-menu appear on hover using the .hover() function. I'm trying to prevent this on small devices by using enquire.js. I'm trying to unbind the .hover() event on the element using this code:
$('.dropdown').unbind('mouseenter mouseleave');
This unbinds the .hover of that script but apparently it also removes the .click() event(or whatever bootstrap uses), and now when I hover or click on the element, nothing happens.
So I just want to how I can remove the .hover() on that element, that is originating from that script, but not change anything else.
Would really appreciate any help.
Thanks!
Edit: Here is how I'm calling the handlers for the hover functions:
$('.dropdown').hover(handlerIn, handlerOut);
function handlerIn(){
// mouseenter code
}
function hideMenu() {
// mouseleave code
}
I'm trying to unbind them with this code.
$('.dropdown').unbind('mouseenter', showMenu);
$('.dropdown').unbind('mouseleave', hideMenu);
But its not working.
Please help!
**Edit2: ** Based on the answer of Tieson T.:
function dropdownOnHover(){
if (window.matchMedia("(min-width: 800px)").matches) {
/* the view port is at least 800 pixels wide */
$('.dropdown').hover(handlerIn, handlerOut);
function handlerIn(){
// mouseenter code
}
function hideMenu() {
// mouseleave code
}
}
}
$(window).load(function() {
dropdownOnHover();
});
$(window).resize(function() {
dropdownOnHover();
});
The code that Tieson T. provided worked the best; however, when I resize the window, until I reach the breakpoint from any direction, the effect doesn't change. That is, if the window is loaded above 800px, the hover effect will be there, but if I make the window smaller it still remains. I tried to invoke the functions with window.load and window.resize but it is still the same.
Edit 3: I'm actually trying to create Bootstrap dropdown on hover instead of click. Here is the updated jsFiddle: http://jsfiddle.net/CR2Lw/2/
Please note: In the jsFiddle example, I could use css :hover property and set the dropdow-menu to display:block. But because the way I need to style the dropdown, there needs to be some space between the link and the dropdown (it is a must), and so I have to find a javascript solution. or a very tricky css solution, in which the there is abot 50px space between the link and the dropdown, when when the user has hovered over the link and the dropdown has appeared, the dropdown shouldn't disappear when the user tries to reach it. Hope it makes sense and thanks.
Edit 4 - First possible solution: http://jsfiddle.net/g9JJk/6/
Might be easier to selectively apply the hover, rather than try to remove it later. You can use window.matchMedia and only apply your script if the browser has a screen size that implies a desktop browser (or a largish tablet):
if (window.matchMedia("(min-width: 800px)").matches) {
/* the view port is at least 800 pixels wide */
$('.dropdown').on({
mouseenter: function () {
//stuff to do on mouse enter
},
mouseleave: function () {
//stuff to do on mouse leave
}
});
}
else{
$('.dropdown').off('mouseenter, mouseleave');
}
Since it's not 100% supported, you'd want to add a polyfill for those browsers without native support: https://github.com/paulirish/matchMedia.js/
If you're using Moderizr, that polyfill is included in that library already, so you're good-to-go.
I still don't understand how you intend to "dismiss" the dropdown-menu once it is displayed upon mousing over the dropdown element partly because there's not enough code in your question, but that's sort of irrelevant to this answer.
I think a much easier way to approach the mousenter event handling portion is not by using off()/on() to unbind/bind events at a specific breakpoints, but rather to do just do a simple check when the event is triggered. In other words, something like this:
$('.dropdown').on('mouseenter', function() {
if($('.navbar-toggle').css('display') == 'none') {
$(this).children('.dropdown-menu').show();
};
});
$('.dropdown-menu').on('click', function() {
$(this).hide();
});
Here's a working fiddle: http://jsfiddle.net/jme11/g9JJk/
Basically, in the mouseenter event I'm checking if the menu toggle is displayed, but you can check window.width() at that point instead if you prefer. In my mind, the toggle element's display value is easier to follow and it also ensures that if you change your media query breakpoints for the "collapsed" menu, the code will remain in sync without having to update the hardcoded values (e.g. 768px).
The on click to dismiss the menu doesn't need a check, as it has no detrimental effects that I can see when triggered on the "collapsed" menu dropdown.
I still don't like this from a UX perspective. I would much rather have to click to open a menu than click to close a menu that's being opened on a hover event, but maybe you have some magic plan for some other way of triggering the hide method. Maybe you are planning to register a mousemove event that checks if the mouse is anywhere within the bounds of the .dropdown + 50px + .dropdown-menu or something like that... I would really like to know how you intend to do this (curiosity is sort of killing me). Maybe you can update your code to show the final result.
EDIT: Thanks for posting your solution!

How do you think about respective callback for bootstrap modal triggers?

On bootstrap modals, we know that we can bind events for triggers like show or hide using show, shown, hide, hidden, but this event binding only works for general case. What I want is 'specific case' such as:
$("#myModal").modal("show", function(e){
alert("This pops-up after #myModal is shown properly.");
});
or maybe using dictionaries for more options.
Anyway, I want to call some functions as callback after these modal triggers are done.
I do know that there can be alternative implementations, like using setTimeout to wait until the modal is completely shown or hidden, or just unbind the event inside the callback function so the event handler works only for once. Either way, it's not very convenient and ugly.
Can this feature be feasible feature request for bootstrap?
Also, I'm not very satisfied that to change modal's property after its init, I have to change it by directly managing $("#myModal").data("bs.modal").options.
Again, I'm asking about particular situation. I don't want to make callback function called for every show, shown, hide or what ever. Just for specific situation where the modal is triggered manually via javascript.
Here is an example:
Let's say that there are #myModal, and #btn-a, #btn-b.
$(document).ready(function(){
$("#myModal").on("shown.bs.modal", function(e){
console.log("myModal shown.");
})
$("#btn-a").click(function(e){
$("#myModal").modal("show");
});
$("#btn-b").click(function(e){
// There is no such thing like below. It's just pseudo code.
$("#myModal").modal("show", function(e2){
console("myModal shown by b.");
});
});
}
Then if #btn-a is clicked,
myModal shown.
will appear while if #btn-a is clicked,
myModal shown.
myModal shown by b.
will appear.
Again and again, I'm actually not asking how to make it. I already made what I want. What I'm asking is, will this feature be feasible feature request for bootstrap.
Check out the section titled Events here:
http://getbootstrap.com/javascript/#modals
Hopefully, it will give you all the information you need
You can use shown events to detect when the modal has been made visible on the screen:
$('#myModal').on('shown.bs.modal', function (e) {
alert("This pops-up after #myModal is shown properly.");
})
You can check for more information in the events section of modal here.

Categories

Resources