【问题标题】:Is is possible to determine when an element has been rendered using JavaScript?是否可以确定何时使用 JavaScript 渲染了元素?
【发布时间】:2011-04-09 17:46:02
【问题描述】:

是否有 jQuery 等效于执行以下操作:

$(document).ready(function() {

对于一个元素:

$(a).ready(function() {

我在更新面板中有内容,我在一些锚元素上调用 jQuery UI 的 .button()。更新面板刷新后,锚点会重新渲染并失去 UI 样式。

我已经知道如何使用 .NET AJAX 的 add_endrequest(handler) 检测 ajax 请求的结束,但希望使用 jQuery.delegate 获得更简洁的解决方案。

例如

$('body').delegate('#mybutton', 'load', (function(){  //this doesnt work... }

【问题讨论】:

  • Updatepanel 不触发任何事件,或提供任何可以挂钩的回调?

标签: javascript asp.net jquery jquery-ui updatepanel


【解决方案1】:

您可以轻松跟踪网页中任何元素的加载情况。

$(function(){$("#ele_id").bind("load", function () { alert('hurray!') });})

更多细节请看这个帖子: jQuery How do you get an image to fade in on load?

【讨论】:

  • 其实加载事件只适用于imgobjectscriptwindow等少数元素。
  • 我不相信它适用于任何元素,只适用于加载内容的元素(img,iframe)
  • 我明白,我认为真正的解决方案是,如何在 js microsoft ajax javascript 框架中找到类似 UpdatePanleRendered 的东西
【解决方案2】:
【解决方案3】:

2018 年更新,您可以为此使用新的 MutationObserver API,这里有一个插件:

(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);

限制是它仅适用于使用字符串作为 CSS 选择器的 jQuery 的基本使用。

如果您不需要与已准备好的内置名称相同的名称,您可以使用不同的名称并删除 ready.call(self, callback);

【讨论】:

    【解决方案4】:

    如果我正确理解您的要求,一种方法是使用Live Query 插件。

    Live Query ...具有触发的能力 匹配时的函数(回调) 一个新元素和另一个功能 (回调)当元素为 no 时 更长的匹配

    例如:

    $('#someRegion a').livequery( function(){ 
      do_something();
    });
    


    更新: 由于 DOM 更改没有通过 jQuery 运行,不幸的是 livequery 没有看到它们。我之前考虑过这个问题,并在this answer 中考虑了基于轮询的解决方案。
    更新: 轮询有点难看,但如果真的没有其他选择,这里有一个基于轮询的解决方案,它使用 jQuery“虚拟”操作来使实时查询“看到”变化。你只想考虑这样的事情作为最后的手段——如果没有选择绑定到回调方法。

    首先,设置 livequery 监视将发生更新的容器:

    $('div#container').livequery( function(){ 
      $(this).css('color','red'); // do something
    });
    

    然后使用setInterval(),这里包装在一个便利函数中:

    function pollUpdate( $el, freq ){
      setInterval( function(){
        $el.toggleClass('dummy');
      }, freq); 
    };
    

    所以你可以拥有:

    $(document).ready( function(){
      pollUpdate( $('div#container'), 500 );
    });
    

    这是working example。单击按钮以添加不带 jQuery 的新 DOM 元素,您会看到它们(最终)被 livequery 拾取并重新设置样式。不漂亮,但确实有效。

    【讨论】:

    • 如果我使用 jquery.append() 添加新元素,我可以触发 livequery,但是刷新更新面板时它不会检测到添加到页面的新元素。
    • 我很抱歉——我现在看到这些更改不是由 jQuery 进行的。 Live Query 因此看不到它们。请参阅上面的编辑。
    【解决方案5】:

    您是否正在尝试解决错误的问题?如果只是样式:尝试在标题中添加 css,以便更新不会影响样式。注意:根据您对这些示例的问题,不确定您的选择器。

    $('head').append('<style type="text/css">body a{margin:0;}</style>'); 
    

    $('<style type="text/css">body a {margin: 0;}</style>').appendTo($('head'));
    

    如果您确实需要一些事件管理,您应该能够使用上下文来使用委托。在此处查看注释: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);
    });
    

    或者用链子

    $('body').children('div').delegate('a', 'change', function(event) {
        // this == a element
      $(this).addClass(class here);
    });
    

    现在是真正的答案,因为您可以访问该事件,您可以使用 pageLoad 函数将其直接添加到您的页面;添加这个:

    function pageLoad(sender, args) 
    { 
       if (args.get_isPartialLoad()) 
       { 
           //jQuery code for partial postbacks can go in here. 
       } 
    } 
    

    【讨论】:

    • 更新面板上的更多内容:stackoverflow.com/questions/256195/…
    • JQuery UI 的 .button() 方法不只是添加 css 样式。它还将行为添加到应用它的包装元素集。
    • @Daniel Dyson - 事实上,如果 .delegate 不适用于加载事件,那么 pageLoad 应该可以应用 .button 并捕获加载事件。
    • 是的,我的评论只是关于你答案的第一段。
    【解决方案6】:

    可以使用动画事件检测元素渲染状态,例如:TAB-C 的图像框将从其父节点更新大小

    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>

    【讨论】:

      猜你喜欢
      • 2012-01-25
      • 2020-08-10
      • 1970-01-01
      • 2021-12-19
      • 1970-01-01
      • 1970-01-01
      • 2020-06-03
      • 2020-01-15
      • 2013-03-30
      相关资源
      最近更新 更多