Is there a jQuery equivalent to do the following:
$(document).ready(function() {
for an element:
$(a).ready(function() {
I have content in an updatepanel and I am calling jQuery UI's .button() on some anchor elements. After the updatepanel refreshed, the anchors are rerendered and lose the UI styling.
I already know how to detect the end of an ajax request using .NET AJAX's add_endrequest(handler), but was hoping for a neater solution using jQuery.delegate.
e.g.
$('body').delegate('#mybutton', 'load', (function(){ //this doesnt work... }
If I understand your requirement correctly, one way to do this is with the Live Query plug-in.
Live Query ... has the ability to fire
a function (callback) when it matches
a new element and another function
(callback) for when an element is no
longer matched
For example:
$('#someRegion a').livequery( function(){
do_something();
});
Update: Since the DOM changes are not running through jQuery, unfortunately livequery doesn't see them. I mulled over this issue before and considered a polling-based solution in this answer.
Update: Polling is kind of ugly, but if there's really no other alternative, here's a polling-based solution that uses a jQuery "dummy" manipulation to make livequery "see" the change. You'd only want to consider something like this as a last resort -- if there's no option to tie into a callback method.
First, set up livequery watching the container where the updates will occur:
$('div#container').livequery( function(){
$(this).css('color','red'); // do something
});
And then use setInterval()
, here wrapped in a convenience function:
function pollUpdate( $el, freq ){
setInterval( function(){
$el.toggleClass('dummy');
}, freq);
};
So you can have:
$(document).ready( function(){
pollUpdate( $('div#container'), 500 );
});
Here's a working example. Click the button to add new DOM elements without jQuery, and you'll see they get picked up (eventually) and restyled by livequery. Not pretty, but it does work.
you can easily track on load for any element in the web page.
$(function(){$("#ele_id").bind("load", function () { alert('hurray!') });})
for more details see this thread :
jQuery How do you get an image to fade in on load?
elementReady: a jQuery plugin
Update in 2018, You can use new MutationObserver API for this, here is a plugin just for that:
(function($, ready) {
$.fn.ready = function(callback) {
var self = this;
callback = callback.bind(self);
if (self[0] == document) { // it will return false on document
ready.call(self, callback);
} else if (self.length) {
console.log('length');
callback();
} else {
if (!self.data('ready_callbacks')) {
var callbacks = $.Callbacks();
callbacks.add(callback);
var observer = new MutationObserver(function(mutations) {
var $element = $(self.selector);
if ($element.length) {
callbacks.fireWith($element);
observer.disconnect();
self.removeData('ready_callbacks');
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
} else {
self.data('ready_callbacks').add(callback);
}
}
return self;
};
})(jQuery, jQuery.fn.ready);
the limitation is that it only work for base use of jQuery with string as CSS selector.
If you don't need the same name as build in ready you can use different name and remove ready.call(self, callback);
.
Are you are trying to solve the wrong problem? IF it is just style: Try to add instead, css in the header so that the update does not impact the style. Note: Not exactly sure on your selectors based on your question for these examples.
$('head').append('<style type="text/css">body a{margin:0;}</style>');
OR
$('<style type="text/css">body a {margin: 0;}</style>').appendTo($('head'));
If you indeed need some event management you should be able to use the delegate using context. see notes here: http://brandonaaron.net/blog/2010/03/4/event-delegation-with-jquery
$('body div').delegate('a', 'change', function(event) {
// this == a element
$(this).addClass(class here);
});
or with a chain
$('body').children('div').delegate('a', 'change', function(event) {
// this == a element
$(this).addClass(class here);
});
Now for the real answer, since you have access to the event you can add it directly to your page with the pageLoad function; Add this:
function pageLoad(sender, args)
{
if (args.get_isPartialLoad())
{
//jQuery code for partial postbacks can go in here.
}
}
element rendered state can be detected using animation event as bellow, Example: TAB-C's image box will get updated in size from it's parent node
var $$ = (query)=>{ return document.querySelectorAll(query);}
var updateSize = (el)=>{
el.style.height = el.parentNode.getBoundingClientRect().height + "px";
}
$$(".img").forEach((el)=>{
updateSize(el);
if(el.classList.contains("rendering-check")){
el.addEventListener("animationend", ()=>{
updateSize(el);
}, false)
}
})
.h{min-height:30px;border-bottom:1px solid #DEDEDE}
h1{margin:5px;font-size:12px}
.h label{display:inline-block;padding:5px;cursor:pointer;}
.c>div{display:none;}
input[name="tabs"]{display:none}
input[name="tabs"]:checked+div{
display:block;
}
.img-parent{width:300px;height:100px;}
.img{
display:flex;
align-items:center;
min-height:50px;
width:100%;
color:#FFF;
font-size:15px;
justify-content:center;
box-sizing:border-box;
text-shadow:0 0 5px #000;
}
.img1{background-color:#F00;}
.img2{background-color:#0F0;}
.img3{background-color:#00F;}
.rendering-check{
animation:0.001s ease-in-out 0s 1 checkAnimation;
}
@keyframes checkAnimation {
from {color:#FFF;}
to {color:#000;}
}
<div class="tabs">
<div class="h">
<label for="item1">Tab A</label>
<label for="item2">Tab B</label>
<label for="item3">Tab C</label>
</div>
<div class="c">
<input type="radio" id="item1" name="tabs" checked="">
<div>
<h1>Tab A conetents</h1>
<div class="img-parent">
<div class="img img1">should be 300X100</div>
</div>
</div>
<input type="radio" id="item2" name="tabs">
<div>
<h1>Tab B conetents</h1>
<div class="img-parent">
<div class="img img2">fails to be 300X100</div>
</div>
</div>
<input type="radio" id="item3" name="tabs">
<div>
<h1>Content with rendering check</h1>
<div class="img-parent">
<div class="img img3 rendering-check">will be 300X100</div>
</div>
</div>
</div>
</div>