Temporary creation of html div using Jquery - javascript

I am trying to create div's on demand which then timeout and are then hidden and removed from the dom.
The display property of "load_bar" is set to none so that I can use the last selector to get a reference to the instance I have just created.
It is important that this solution can create several div's which are running on their own timeout clock
$(document).ready(function () {
$('#add').click(function () {
var t = Math.random()*20;
alert(t);
var destination = $('input').val();
$('#holding_pen').append('<div class="load_bar">'+destination+'</div>');
$('.load_bar:last').show().delay(t).hide().remove();
});
});
Every thing works to create divs when I remove .delay().hide().remove();
However when I add this the div is not shown at all

Create proper elements, that way you'll have a reference to the element within the function:
$(document).ready(function () {
$('#add').click(function () {
var t = (Math.random()*20)*1000,
destination = $('input').val(),
div = $('<div />', {'class':'load_bar', text: destination});
$('#holding_pen').append(div);
div.show(1).delay(t).hide(1, function() {
$(this).remove();
});
});
});
Also, hide() and show() does not work with the animation queue and subsequently not with delay() unless a duration is given, and that's why the element is never shown, delay() doesn't work and the element is hidden right away.
EDIT:
Also, remove() is not an animated method, so it doesn't work with delay(), but hide() a useful callback for that, see edited code above.
FIDDLE

The problem is because delay is used to stop jQuery animation queue, which both show and hide do not use. Therefore your div is being shown and them immediately hidden. Use setTimeout instead:
$('#add').click(function () {
var destination = $('input').val();
$('#holding_pen').append('<div class="load_bar">'+destination+'</div>');
$('.load_bar:last').show();
setTimeout(function() {
$('.load_bar:last').hide();
}, Math.random() * 20 * 1000); // * 1000 = seconds
});
Example fiddle

The delay() function only applies to actions queued on the element.
$(document).ready(function () {
$('#add').click(function () {
var t = Math.random()*20;
alert(t);
var destination = $('input').val();
$('#holding_pen').append('<div class="load_bar">'+destination+'</div>');
$('.load_bar:last').show().delay(t).queue(function( nxt ) {
$(this).hide().remove();
nxt(); // continue the queue
});
});
});

$(document).ready(function () {
$('#add').click(function () {
var t = Math.random()*20;
alert(t);
var destination = $('input').val();
$('#holding_pen').innerHTML='<div class="load_bar">'+destination+'</div>';
});
});

Related

JQuery click function order

I would like to know how can I change the background-image of another div element, when I click on it. I would like to see images one after another in order but what I get is the last one. Here is some code:
$(document).ready(function () {
// console.log('ready!');
$('.right').click(function () {
$('.zur-gda-img').css('background','url(images/sail-boat.jpg)');
}).click(function() {
$('.zur-gda-img').css('background','url(images/sad_ostateczny.jpg)');
}) }).click(function() {
$('.zur-gda-img').css('background','url(images/twierdza_wisloujscie.jpg)');
});
Instead of adding multiple event handler use single. Inside handler change images from the array with help of a counter variable.
$(document).ready(function() {
// store images in an array
var images = ['url(images/sail-boat.jpg)', 'url(images/sad_ostateczny.jpg)', 'url(images/twierdza_wisloujscie.jpg)'],
// variable to store index
i = 0;
$('.right').click(function() {
// update index based on array length
i = i % images.length;
// update background from array using the index value
$('.zur-gda-img').css('background', images[i++]);
})
});
You don't need three event handlers for this (they will just fire one after another and you'll only see the last image). If you want to see images changing, try the following:
$(document).ready(function () {
// document has loaded
$('.right').click(function () {
// 1st image:
$('.zur-gda-img').css('background','url(images/sail-boat.jpg)');
// 2nd image, appears in a second:
setTimeout(function() {
$('.zur-gda-img').css('background','url(images/sad_ostateczny.jpg)');
// 3rd image, appears in another second:
setTimeout(function() {
$('.zur-gda-img').css('background','url(images/twierdza_wisloujscie.jpg)');
},
1000);
},
1000);
});
});

Adding a jQuery delay on autocomplete

I'm trying to create a jQuery autocomplete for an application:
$("#search-input").on('keyup', function() {
search = $(this).val();
autocomplete_div = $(".autocomplete")
$.get('/ajax/search/', {'search': search,}, function(response){
autocomplete_div.html(response)
});
});
What would I need to add to the above code to add a 400ms delay?
Use
setTimeout(function() {
// your code here
}, 400);
setTimeout is a method provided by the browser's window object.
A more complete example that cancels a timer if already set using clearTimeout would be:
var myTimer = 0;
$("#search-input").on('keydown', function() {
search = $(this).val();
// cancel any previously-set timer
if (myTimer) {
clearTimeout(myTimer);
}
myTimer = setTimeout(function() {
autocomplete_div = $(".autocomplete")
$.get('/ajax/search/', {'search': search,}, function(response){
autocomplete_div.html(response)
});
}, 400);
});
Also note use of on instead of the deprecated live.
Your code should look like this: (for jQuery 1.7+)
$(document).on('keyup', "#search-input", function () {
clearTimeout($(this).data('timeout'));
var _self = this;
$(this).data('timeout', setTimeout(function () {
$.get('/ajax/search/', {
search: _self.value
}, function (response) {
$(".autocomplete").html(response);
});
}, 400));
});
If using older jQuery version, use live() or better delegate(). BTW, you should bind it to closest static container, not document.
You can use the setTimeout() function to delay the start of the expression, in this case, your function. Beware that this does not delay processing beyond this code. It will only delay the start of this function, while continuing to process code after the function.
$("#search-input").live('keydown', setTimeout(function() {
search = $(this).val();
autocomplete_div = $(".autocomplete")
$.get('/ajax/search/', {'search': search,}, function(response){
autocomplete_div.html(response)
})
},400));
EDITED: to correct misplaced parentheses.

How to manage many setInterval function by jquery each individually

hey i have a setInterval function [see below] inside a an each function for all divs with class, my problem is to manage each divs differently
please help
var div_holder = $('div.products_each');
div_holder.each(function(i){
var vari= setInterval(function() {
//do something here
},1000/60)
});
and i could close this by
$(document).on("mouseenter", ".products_each_all",function(){
$(this).children('div._title').css('margin-left',"0px");
clearInterval(vari);
})
this Clear all setInterval call [effects all div action]
My question is how to manage each classes setinterval differently
thanks in advance
use .data() to store the interval reference of each element individually.
var div_holder = $('div.products_each');
div_holder.each(function (i) {
var vari = setInterval(function () {
//do something here
}, 1000 / 60)
$(this).data('vari', vari)
});
$(document).on("mouseenter", ".products_each_all", function () {
$(this).children('div._title').css('margin-left', "0px");
//each products_each element will have a data item called vari which holds the interval reference, you can use it to clear it later
var div_holder = $('div.products_each');
div_holder.each(function (i) {
clearInterval($(this).data('vari'));
});
})
you can achieve it like this:
$.each($(".products_each"), function (index, value) {
var vari = setInterval(function() {
// do what ever you want with value
// it is your div : $(value).hide();
}, 1000/60);
});

losing variable in function

Could someone tell me why in the first alert(items.index($(this))) = 1 and the second alert(items.index($(this))) = -1. How does this value get changed within the other function?
$(function () {
var items = $('#v-nav>ul>li').each(function () {
$(this).click(function () {
//remove previous class and add it to clicked tab
items.removeClass('current');
$(this).addClass('current');
alert(items.index($(this)));
$('#v-nav>div.tab-content').fadeOut("slow", function () {
alert(items.index($(this)));
$('#v-nav>div.tab-content').eq(items.index($(this))).fadeIn("slow");
});
// window.location.hash = $(this).attr('tab');
});
});
this refers to current object.
In first version,
this is an item of $('#v-nav>ul>li') list.
While in second version,
this is DOM object selected by $('#v-nav>div.tab-content')
If you want to retain the previous value of this, then cache it in a variable.
(Caching $(this) is a very good practise, as you always save a function call).
When you use $(this) you actually passes this into $ function.
$(function () {
var items = $('#v-nav>ul>li').each(function () {
var $this = $(this);
$this.click(function () {
//remove previous class and add it to clicked tab
items.removeClass('current');
$this.addClass('current');
alert(items.index($this));
$('#v-nav>div.tab-content').fadeOut("slow", function () {
alert(items.index($this));
$('#v-nav>div.tab-content').eq(items.index($(this))).fadeIn("slow");
});
// window.location.hash = $(this).attr('tab');
});
});
Inside the callback function for the animation, this is not the element that you clicked, it's the element being animated.
"The callback is not sent any arguments, but this is set to the DOM
element being animated."
http://api.jquery.com/fadeOut/
(And if it hadn't been set to the animated element, it would have been a reference to the window object.)
Copy the reference to a variable outside the animation call:
var t = this;
$('#v-nav>div.tab-content').fadeOut("slow", function () {
alert(items.index($(t)));
$('#v-nav>div.tab-content').eq(items.index($(t))).fadeIn("slow");
});
You have to consider the context of each "this", each of the callbacks has a distinct "this" variable. If you want to keep the original this around, do something like:
var self = this;

jQuery event to trigger action when a div is made visible

I'm using jQuery in my site and I would like to trigger certain actions when a certain div is made visible.
Is it possible to attach some sort of "isvisible" event handler to arbitrary divs and have certain code run when they the div is made visible?
I would like something like the following pseudocode:
$(function() {
$('#contentDiv').isvisible(function() {
alert("do something");
});
});
The alert("do something") code should not fire until the contentDiv is actually made visible.
Thanks.
You could always add to the original .show() method so you don't have to trigger events every time you show something or if you need it to work with legacy code:
Jquery extension:
jQuery(function($) {
var _oldShow = $.fn.show;
$.fn.show = function(speed, oldCallback) {
return $(this).each(function() {
var obj = $(this),
newCallback = function() {
if ($.isFunction(oldCallback)) {
oldCallback.apply(obj);
}
obj.trigger('afterShow');
};
// you can trigger a before show if you want
obj.trigger('beforeShow');
// now use the old function to show the element passing the new callback
_oldShow.apply(obj, [speed, newCallback]);
});
}
});
Usage example:
jQuery(function($) {
$('#test')
.bind('beforeShow', function() {
alert('beforeShow');
})
.bind('afterShow', function() {
alert('afterShow');
})
.show(1000, function() {
alert('in show callback');
})
.show();
});
This effectively lets you do something beforeShow and afterShow while still executing the normal behavior of the original .show() method.
You could also create another method so you don't have to override the original .show() method.
The problem is being addressed by DOM mutation observers. They allow you to bind an observer (a function) to events of changing content, text or attributes of dom elements.
With the release of IE11, all major browsers support this feature, check http://caniuse.com/mutationobserver
The example code is a follows:
$(function() {
$('#show').click(function() {
$('#testdiv').show();
});
var observer = new MutationObserver(function(mutations) {
alert('Attributes changed!');
});
var target = document.querySelector('#testdiv');
observer.observe(target, {
attributes: true
});
});
<div id="testdiv" style="display:none;">hidden</div>
<button id="show">Show hidden div</button>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
There is no native event you can hook into for this however you can trigger an event from your script after you have made the div visible using the .trigger function
e.g
//declare event to run when div is visible
function isVisible(){
//do something
}
//hookup the event
$('#someDivId').bind('isVisible', isVisible);
//show div and trigger custom event in callback when div is visible
$('#someDivId').show('slow', function(){
$(this).trigger('isVisible');
});
You can use jQuery's Live Query plugin.
And write code as follows:
$('#contentDiv:visible').livequery(function() {
alert("do something");
});
Then everytime the contentDiv is visible, "do something" will be alerted!
redsquare's solution is the right answer.
But as an IN-THEORY solution you can write a function which is selecting the elements classed by .visibilityCheck (not all visible elements) and check their visibility property value; if true then do something.
Afterward, the function should be performed periodically using the setInterval() function. You can stop the timer using the clearInterval() upon successful call-out.
Here's an example:
function foo() {
$('.visibilityCheck').each(function() {
if ($(this).is(':visible')){
// do something
}
});
}
window.setInterval(foo, 100);
You can also perform some performance improvements on it, however, the solution is basically absurd to be used in action. So...
The following code (pulled from http://maximeparmentier.com/2012/11/06/bind-show-hide-events-with-jquery/) will enable you to use $('#someDiv').on('show', someFunc);.
(function ($) {
$.each(['show', 'hide'], function (i, ev) {
var el = $.fn[ev];
$.fn[ev] = function () {
this.trigger(ev);
return el.apply(this, arguments);
};
});
})(jQuery);
If you want to trigger the event on all elements (and child elements) that are actually made visible, by $.show, toggle, toggleClass, addClass, or removeClass:
$.each(["show", "toggle", "toggleClass", "addClass", "removeClass"], function(){
var _oldFn = $.fn[this];
$.fn[this] = function(){
var hidden = this.find(":hidden").add(this.filter(":hidden"));
var result = _oldFn.apply(this, arguments);
hidden.filter(":visible").each(function(){
$(this).triggerHandler("show"); //No bubbling
});
return result;
}
});
And now your element:
$("#myLazyUl").bind("show", function(){
alert(this);
});
You could add overrides to additional jQuery functions by adding them to the array at the top (like "attr")
a hide/show event trigger based on Glenns ideea:
removed toggle because it fires show/hide and we don't want 2fires for one event
$(function(){
$.each(["show","hide", "toggleClass", "addClass", "removeClass"], function(){
var _oldFn = $.fn[this];
$.fn[this] = function(){
var hidden = this.find(":hidden").add(this.filter(":hidden"));
var visible = this.find(":visible").add(this.filter(":visible"));
var result = _oldFn.apply(this, arguments);
hidden.filter(":visible").each(function(){
$(this).triggerHandler("show");
});
visible.filter(":hidden").each(function(){
$(this).triggerHandler("hide");
});
return result;
}
});
});
I had this same problem and created a jQuery plugin to solve it for our site.
https://github.com/shaunbowe/jquery.visibilityChanged
Here is how you would use it based on your example:
$('#contentDiv').visibilityChanged(function(element, visible) {
alert("do something");
});
What helped me here is recent ResizeObserver spec polyfill:
const divEl = $('#section60');
const ro = new ResizeObserver(() => {
if (divEl.is(':visible')) {
console.log("it's visible now!");
}
});
ro.observe(divEl[0]);
Note that it's crossbrowser and performant (no polling).
Just bind a trigger with the selector and put the code into the trigger event:
jQuery(function() {
jQuery("#contentDiv:hidden").show().trigger('show');
jQuery('#contentDiv').on('show', function() {
console.log('#contentDiv is now visible');
// your code here
});
});
Use jQuery Waypoints :
$('#contentDiv').waypoint(function() {
alert('do something');
});
Other examples on the site of jQuery Waypoints.
I did a simple setinterval function to achieve this. If element with class div1 is visible, it sets div2 to be visible. I know not a good method, but a simple fix.
setInterval(function(){
if($('.div1').is(':visible')){
$('.div2').show();
}
else {
$('.div2').hide();
}
}, 100);
You can also try jQuery appear plugin as mentioned in parallel thread https://stackoverflow.com/a/3535028/741782
This support easing and trigger event after animation done! [tested on jQuery 2.2.4]
(function ($) {
$.each(['show', 'hide', 'fadeOut', 'fadeIn'], function (i, ev) {
var el = $.fn[ev];
$.fn[ev] = function () {
var result = el.apply(this, arguments);
var _self=this;
result.promise().done(function () {
_self.triggerHandler(ev, [result]);
//console.log(_self);
});
return result;
};
});
})(jQuery);
Inspired By http://viralpatel.net/blogs/jquery-trigger-custom-event-show-hide-element/
There is a jQuery plugin available for watching change in DOM attributes,
https://github.com/darcyclarke/jQuery-Watch-Plugin
The plugin wraps All you need do is bind MutationObserver
You can then use it to watch the div using:
$("#selector").watch('css', function() {
console.log("Visibility: " + this.style.display == 'none'?'hidden':'shown'));
//or any random events
});
Hope this will do the job in simplest manner:
$("#myID").on('show').trigger('displayShow');
$('#myID').off('displayShow').on('displayShow', function(e) {
console.log('This event will be triggered when myID will be visible');
});
I changed the hide/show event trigger from Catalint based on Glenns idea.
My problem was that I have a modular application. I change between modules showing and hiding divs parents. Then when I hide a module and show another one, with his method I have a visible delay when I change between modules. I only need sometimes to liten this event, and in some special childs. So I decided to notify only the childs with the class "displayObserver"
$.each(["show", "hide", "toggleClass", "addClass", "removeClass"], function () {
var _oldFn = $.fn[this];
$.fn[this] = function () {
var hidden = this.find(".displayObserver:hidden").add(this.filter(":hidden"));
var visible = this.find(".displayObserver:visible").add(this.filter(":visible"));
var result = _oldFn.apply(this, arguments);
hidden.filter(":visible").each(function () {
$(this).triggerHandler("show");
});
visible.filter(":hidden").each(function () {
$(this).triggerHandler("hide");
});
return result;
}
});
Then when a child wants to listen for "show" or "hide" event I have to add him the class "displayObserver", and when It does not want to continue listen it, I remove him the class
bindDisplayEvent: function () {
$("#child1").addClass("displayObserver");
$("#child1").off("show", this.onParentShow);
$("#child1").on("show", this.onParentShow);
},
bindDisplayEvent: function () {
$("#child1").removeClass("displayObserver");
$("#child1").off("show", this.onParentShow);
},
I wish help
One way to do this.
Works only on visibility changes that are made by css class change, but can be extended to watch for attribute changes too.
var observer = new MutationObserver(function(mutations) {
var clone = $(mutations[0].target).clone();
clone.removeClass();
for(var i = 0; i < mutations.length; i++){
clone.addClass(mutations[i].oldValue);
}
$(document.body).append(clone);
var cloneVisibility = $(clone).is(":visible");
$(clone).remove();
if (cloneVisibility != $(mutations[0].target).is(":visible")){
var visibilityChangedEvent = document.createEvent('Event');
visibilityChangedEvent.initEvent('visibilityChanged', true, true);
mutations[0].target.dispatchEvent(visibilityChangedEvent);
}
});
var targets = $('.ui-collapsible-content');
$.each(targets, function(i,target){
target.addEventListener('visibilityChanged',VisbilityChanedEventHandler});
target.addEventListener('DOMNodeRemovedFromDocument',VisbilityChanedEventHandler });
observer.observe(target, { attributes: true, attributeFilter : ['class'], childList: false, attributeOldValue: true });
});
function VisbilityChanedEventHandler(e){console.log('Kaboom babe'); console.log(e.target); }
my solution:
; (function ($) {
$.each([ "toggle", "show", "hide" ], function( i, name ) {
var cssFn = $.fn[ name ];
$.fn[ name ] = function( speed, easing, callback ) {
if(speed == null || typeof speed === "boolean"){
var ret=cssFn.apply( this, arguments )
$.fn.triggerVisibleEvent.apply(this,arguments)
return ret
}else{
var that=this
var new_callback=function(){
callback.call(this)
$.fn.triggerVisibleEvent.apply(that,arguments)
}
var ret=this.animate( genFx( name, true ), speed, easing, new_callback )
return ret
}
};
});
$.fn.triggerVisibleEvent=function(){
this.each(function(){
if($(this).is(':visible')){
$(this).trigger('visible')
$(this).find('[data-trigger-visible-event]').triggerVisibleEvent()
}
})
}
})(jQuery);
example usage:
if(!$info_center.is(':visible')){
$info_center.attr('data-trigger-visible-event','true').one('visible',processMoreLessButton)
}else{
processMoreLessButton()
}
function processMoreLessButton(){
//some logic
}
$( window ).scroll(function(e,i) {
win_top = $( window ).scrollTop();
win_bottom = $( window ).height() + win_top;
//console.log( win_top,win_bottom );
$('.onvisible').each(function()
{
t = $(this).offset().top;
b = t + $(this).height();
if( t > win_top && b < win_bottom )
alert("do something");
});
});
$(function() {
$(document).click(function (){
if ($('#contentDiv').is(':visible')) {
alert("Visible");
} else {
alert("Hidden");
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="contentDiv">Test I'm here</div>
<button onclick="$('#contentDiv').toggle();">Toggle the div</button>
<div id="welcometo">Özhan</div>
<input type="button" name="ooo"
onclick="JavaScript:
if(document.all.welcometo.style.display=='none') {
document.all.welcometo.style.display='';
} else {
document.all.welcometo.style.display='none';
}">
This code auto control not required query visible or unvisible control

Categories

Resources