强制javascript onload处理程序到队列的后面

时间:2014-01-31 12:20:33

标签: javascript php wordpress event-handling

我想用wordpress插件将一个javascript文件添加到footer.php的最后。我尝试使用'add_action'Hook。但是这个钩子在</body>标签附近添加了javascript。

add_action('wp_footer', 'my_fucntion()');

如何将我的javascript推到footer.php的最后?

1 个答案:

答案 0 :(得分:1)

更新
有一个更好的方法,下面的一个应该工作,但这个应该更安全,仍然(并且它更容易,IMO)。
鉴于JS是单线程的,事件会将处理程序推送到队列的后面,所以如果你的onload处理程序最终在另一个处理程序之前被调用,则调度一个新的事件,调用一个处理程序实际上你想要/需要做的工作可能是你最好的选择:

window.addEventListener('load', function rmMe()
{
    var handler = function()
    {
        window.removeEventListener('click', handler, false);//remove this listener, too
        var i, links = document.querySelectorAll('a');
        for (i=0;i<links.length;++i)
        {
            //do stuff with links
        }
    };
    window.removeEventListener('load', rmMe, false);
    window.addEventListener('click', handler, false);//bind new listener
    window.dispatchEvent(new Event('click'));//calls handler, last handler in queue
},false);

这可能是你最好的选择......


在那些无休止的评论之后,你会想到一种方法来保证在页面加载后你的JS被执行,并且所有其他可能的onload事件处理程序都被调用了。
简单的答案是:你做不到。并不是的。 JS的事件循环超出了你的控制范围,但在大多数情况下,有一些技巧:

  1. 将您的脚本添加到正文标记的底部
  2. 绑定您的事件侦听器,但将其包装在setTimeout中,延迟为零或1毫秒
  3. 为了安全起见,让事件处理程序设置另一个实际调用该函数的函数的超时,这次使用允许调用排队处理程序的超时。这是可选的,因为队列可能已经是空的
  4. 重要 确保(或希望)其他处理程序不会在事件上调用stopPropagation:这将导致您的侦听器没有被叫。这就是为什么第一种方法更可取的原因:它将一个新的处理程序推送到队列的后面,允许你先绑定你的监听器。
  5. 代码示例:

    setTimeout(function()
    {
        window.onload = function()
        {
            var handler = function()
            {
                var i, links = document.querySelectorAll('a');
                for (i=0;i<links.length;++i)
                {
                    //do stuff with links
                }
            };
            return function()
            {//fake, initial handler
                setTimeout(handler, 40);//optional, return handler; should suffice
            };
        };
    },1);
    

    这就是全部。这个代码很清楚,在DOM中:

            <script>
                //code here
            </script>
        </body>
    </html>
    

    这不是100%可靠,但是大多数浏览器在绑定事件处理程序时对其进行排队:

    window.addEventListener('load', function(){}, false);//likely to be called first
    window.addEventListener('load', function(){}, false);//likely to be called second
    

    等等。不确定这一点,但如果使用window.addEventListener绑定的侦听器更有可能被附加到队列的末尾,我不会感到惊讶,因为addEventListener调用可能会导致开销。可能使用:

    setTimeout(function()
    {
        window.addEventListener('load', function tmpLoad()
        {
            var handler = function()
            {
                var i, links = document.querySelectorAll('a');
                for (i=0;i<links.length;++i)
                {
                    //do stuff with links
                }
            };
            return function()
            {//fake, initial handler
                window.removeEventListener('load', tmpLoad, false);//adds overhead and time
                setTimeout(handler, 40);//optional, return handler; should suffice
            };
        },false);
    },1);
    

    您还可以考虑手动调度事件,在超时后绑定新的侦听器,然后执行:window.dispatchEvent(new Event('load'));来调用处理程序。