How to fire 2 events together for bootstrap modal? - javascript

I have below 2 events for bootstrap modal
https://getbootstrap.com/docs/4.0/components/modal/
$('.modal').on('show.bs.modal', function() {
});
$('.modal').on('hidden.bs.modal', function() {
});
I have same code in both events.
Can I call both together at one time only for code optimisation.

Yes, you can do:
$('.modal').on('show.bs.modal hidden.bs.modal', function() {
});

You can store your function in a variable.
var fnCallback = function() {
//my function
console.log('my function was triggered');
};
$('.modal').on('show.bs.modal', fnCallback);
$('.modal').on('hidden.bs.modal', fnCallback);

Related

WP Heartbeat API in Vanilla JS (addEventListener for custom events)

Why following code written in jquery works great, but when I try to use it with vanilla js then it’s not working.
Here is WP Heartbeat API code - https://github.com/WordPress/WordPress/blob/master/wp-includes/js/heartbeat.js
jQuery(document).ready( function($) {
$(document).on('heartbeat-tick', function() {
console.log('jquery');
});
});
jQuery(document).ready( function($) {
document.addEventListener('heartbeat-tick', function() {
console.log('Heartbeat tick JS');
});
});
jQuery(document).ready( function($) {
var event = new Event('heartbeat-tick');
window.addEventListener('heartbeat-tick', function() {
console.log('Heartbeat tick JS');
});
window.dispatchEvent(event);
});
Your document event is not firing because you are dispatching the event on the window. Call document.dispatchEvent to dispatch it to the document.
jQuery(document).ready(function($) {
var event = new Event('heartbeat-tick');
$(document).on('heartbeat-tick', function() {
console.log('jquery');
});
document.addEventListener('heartbeat-tick', function() {
console.log('Heartbeat tick JS from document');
});
window.addEventListener('heartbeat-tick', function() {
console.log('Heartbeat tick JS from window');
});
console.log('window');
window.dispatchEvent(event);
console.log('document');
document.dispatchEvent(event);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Combine onload, onresize and onclick

The function below runs on document load and document resize:
$(window).on("resize", function () {
// code
}).resize();
How can I also trigger the function when the user clicks on <div id="my_div"></div> ?
You can explicitly create the callback function, like..
function callbackFn() {
var $caller = $(this);
// do something...
}
$(window).on('resize', callbackFn);
$('#my_div').on('click', callbackFn);
Move your function to some named function and call it on event:
function myFunction () {
alert('Working');
}
$(window).on("resize", function () {
myFunction();
}).resize();
$('#my_div').click(function () {
myFunction();
});
One way to achive that is by triggering the resize event inside the click event handler:
$('#my_div').on('click', function() {
$(window).trigger('resize');
});

Bootstrap popovers don't allow DOM access. What to do?

I have problems with Bootstrap (3.3.4) popovers. My html code for the popover is in the data-html tag, which also contains a class link_click. The jQuery click function for this class doesn't work. Why is jQuery not seeing this link_click class from data-content field of the popover? What to change?
popover = 'Main-Objekt';
$('#popover_test').html( popover );
$('[data-toggle="popover"]').popover({ trigger:"manual", animation:false})
.on("mouseenter", function () {
var _this = this;
$(this).popover("show");
$(".popover").on("mouseleave", function () {
$(_this).popover('hide');
});})
.on("mouseleave", function () {
var _this = this;
setTimeout(function () {
if (!$(".popover:hover").length) {
$(_this).popover("hide");
}
}, 100);
});
$('.link_click').click( function(){
alert('Click success!');
});
Thanks
Michael
Event delegation for dynamic content:
$('#popover_test').on('click', '.link_click', function(){
alert('Click success!');
});

Why Doesn't Modal FadeOut Slowly?

I inherited this modal/overlay/content close/empty method that works, but abruptly:
method.close = function () {
$modal.hide();
$overlay.hide();
$content.empty();
$(window).unbind('resize.modal');
};
To fade out gradually, I modified the method like below, but elements are left behind and subsequent clicks don't open new modals loaded with content, only the overlay:
method.close = function () {
$modal.fadeOut('slow', function() {
$(this).hide();
});
$overlay.fadeOut('slow', function() {
$(this).hide();
});
$content.fadeOut('slow', function() {
$(this).empty();
});
$(window).unbind('resize.modal');
};
What am I missing?
UPDATE: The solution is a single nested callback, based on garryp's answer, like this:
method.close = function() {
$overlay.fadeOut('slow', function() {
$overlay.hide();
$content.empty();
});
$modal.hide();
$(window).unbind('resize.modal');
};
Hide is asynchronous; the calls you have in your original code do not block while the transition occurs, execution moves immediately to the next. You need to use callbacks, like this:
var me = $(this); //Added to ensure correct this context
$modal.fadeOut('slow', function () {
me.hide(function () {
$overlay.fadeOut('slow', function () {
me.hide(function () {
$content.fadeOut('slow', function () {
me.empty();
});
});
});
});
});
Assuming the rest of your code is correct this should ensure the transitions fire one after the next.
Firstly, you do not need $(this).hide(). JQuery fadeOut automatically set display: none at the end of fading animation (read more: http://api.jquery.com/fadeout/).
That mean, in your case $content element will also have display: none after fadeOut animation. I expect you forgot to add $content.show() in modal open method.

jQuery stops working after

I have a page which relies heavily on CSS3 animations. I am in the process of creating a script that will be the fallback that will work for those browsers that do not have CSS3 animations (looking at you IE...). I created the following script that will do the basic of what I need:
var $j = jQuery.noConflict();
$j(document).ready(function() {
//Hide All Elements to Fade Them In
$j(".frame-1, .frame-2, .frame-3, .frame-4, #tile-wrap, #copyright").addClass("hide", function() {
//Change Color of "Frames"
$j(".frame-1, .frame-2, .frame-3, .frame-4").addClass("color", function() {
//Frame 1
$j(".frame-1").fadeIn("slow", function() {
$j('.frame-1').delay(3000).fadeOut('slow', function() {
//Frame 2
$j(".frame-2").fadeIn("slow", function() {
$j('.frame-2').delay(3000).fadeOut('slow', function() {
//Frame 3
$j(".frame-3").fadeIn("slow", function() {
$j('.frame-3').delay(3000).fadeOut('slow', function() {
//Frame 4
$j(".frame-4").fadeIn("slow", function() {
$j('.frame-4').delay(3000).fadeOut('slow', function() {
//Tile
$j('#tile-wrap').fadeIn('slow');
});
});
});
});
});
});
});
});
});
});
});​
The first part of the script works without issue (adding the class of .hide). But nothing after that fires or works. I am stuck because no errors are seen and I assume I have an error in my script.
Here is a fiddle of the script with the rest of the code.
Note: I am not very knowledgeable of writing JS and welcome any ways to improve the script, please provide examples.
FIDDLE NOTE Firebug shows a couple errors when running the fiddle. These errors are only on the Fiddle page and I believe are related to the jsFiddle not my code or page.
What I am attempting to Achieve
What I want is for each item (as listed by class or id) is to fade them in then fade them out after a delay then fade in the last div and it stays.
This will work, http://jsfiddle.net/VNfT2/2/. There is no callback for addclass. Having said that. AHHH!!!!!! This is NOT the right way to do it. Hint: When you see more than 10 }); in a row, stop and take a deep breath. :)
Edit: There are hundreds of plugins to do this (google for jquery slideshow). But, if you want to do it manually...look at this: fiddle: http://jsfiddle.net/VNfT2/5/
See http://jsfiddle.net/VNfT2/4/
var $j = jQuery.noConflict();
$j(document).ready(function() {
//Hide All Elements
$j(".frame-1, .frame-2, .frame-3, .frame-4, #tile-wrap, #copyright")
.addClass("hide")
//Change Color of "Frames"
.addClass("color");
//Frame 1
$j(".frame-1").fadeIn("slow", function() {
$j(this).delay(3000).fadeOut('slow', function() {
//Frame 2
$j(".frame-2").fadeIn("slow", function() {
$j(this).delay(3000).fadeOut('slow', function() {
//Frame 3
$j(".frame-3").fadeIn("slow", function() {
$j(this).delay(3000).fadeOut('slow', function() {
//Frame 4
$j(".frame-4").fadeIn("slow", function() {
$j(this).delay(3000).fadeOut('slow', function() {
//Tile
$j(this).fadeIn('slow');
});
});
});
});
});
});
});
});
});
As I said im my comment, you can call addClass with a string (the class) or with a function which return the class. But you can't do it with a string and a function... See api.jquery.com/addClass
And in your callback functions you should use $(this), it's faster because this way you don't search the element again.
The problem that your callbacks aren't called since they're supplied as the second argument.
addClass( className )
Description: Adds the specified class(es) to each of the set of matched elements.
.addClass( className )
.addClass( function(index, currentClass) )
Here are some tips:
1)
Try to only have 1 nested/callback function inside another function.
Refer to tip 4, then function fadeElementsInThenOut for an example.
2)
Don't repeat lookups.
Old code:
// Let's forget about the callbacks for now
$j(".frame-1, .frame-2, .frame-3, .frame-4, #tile-wrap, #copyright").addClass("hide");
$j(".frame-1, .frame-2, .frame-3, .frame-4").addClass("color");
New Code:
$j(".frame-1, .frame-2, .frame-3, .frame-4").addClass("color hide");
$j("#tile-wrap, #copyright").addClass("color");
3)
Use $(this) to reference the same element within a callback.
Old Code:
$j(".frame-4").fadeIn("slow", function () {
$j('.frame-4').delay(3000).fadeOut('slow', function () {
//...
});
});
New Code:
$j(".frame-4").fadeIn("slow", function () {
$j(this).delay(3000).fadeOut('slow', function () {
//...
});
});
4)
Don't use a callback if you don't have to.
Old Code:
$j(".frame-4").fadeIn("slow", function () {
$j(this).delay(3000).fadeOut('slow', function () {
//...
});
});
New Code:
$j(".frame-4").fadeIn("slow").delay(3000).fadeOut('slow', function () {
//...
});
Here's your code rewritten to fix the problems.
var $j = jQuery.noConflict();
$j(function () {
var frames = [ ".frame-4", ".frame-3", ".frame-2", ".frame-1" ];
var fadeElementsInThenOut = function( els, lastCallback ){
var el = els.pop();
if( el ){
$j(el).fadeIn("slow").delay(3000).fadeOut('slow', function(){
fadeElementsInThenOut( els, lastCallback );
});
}else{
lastCallback();
}
};
$j( frames.join( ", " ) ).addClass("color hide");
$j("#tile-wrap, #copyright").addClass("color");
fadeElementsInThenOut( frames, function(){
$j('#tile-wrap').fadeIn('slow');
});
});

Categories