I h*_*ode 34 javascript ajax wordpress listener dom-events
我使用ajax来获取新内容.提取内容并将其添加到页面中.但是,脚本不会"重新启动",因为它们的调用不在ajaxed之外div.
脚本加载和触发初始页面加载没有任何问题,但是当我通过ajax添加新内容时没有.我没有控制台错误,如果我直接访问URL,则没有问题.
我在WordPress网站上使用Ajaxify WordPress站点(AWS).
该插件允许您div通过其id 选择a ,然后div使用ajax 在其中获取新内容
HTML标记
<html>
<head></head>
<body>
<div id="page">
<header></header>
<main id="ajax"> <!-- This is what I want to ajaxify -->
<div class="container">
main page content
</div>
</main> <!-- end of ajaxfied content -->
<footer></footer>
</div> <!-- #page -->
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
插件工作,我得到新鲜的内容加载和样式,但有一个问题.我的一些页面脚本和函数调用不在我使用ajax的div之外.我有两个例子
1-砌体装载并调用 <footer>
<html>
<head></head>
<body>
<div id="page">
<header></header>
<main id="ajax"> <!-- This is what I want to ajaxify -->
<div class="container">
main page content
</div>
</main> <!-- end of ajaxfied content -->
<footer></footer> <!-- Masonry script is loaded and called here -->
</div> <!-- #page -->
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
2-谷歌地图呼叫在 <head>
<html>
<head></head> <!-- Google maps is called here -->
<body>
<div id="page">
<header></header>
<main id="ajax"> <!-- This is what I want to ajaxify -->
<div class="container">
main page content
</div>
</main> <!-- end of ajaxfied content -->
<footer></footer>
</div> <!-- #page -->
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
这只是两个例子.其他地方还有其他人.正如您所知,这些脚本不会被重新调用,因为在页面上重新加载的唯一内容就是<main id="ajax">.虽然里面的新内容<main>是存在的,但是没有重新调用正确呈现它所需的一些脚本,因此我最终缺少元素/破坏布局.
我不是唯一一个遇到这个问题的人; 快速浏览一下wordpress.org上的插件支持论坛,可以看出这个问题很常见.
注意:如果插件有许多其他问题,我不会尝试修复此问题.它对我有用我只需要脚本重新启动.
官方的回答是,可以通过在插件的php文件中添加以下内容来重新加载/重新激活脚本:
$.getScript(rootUrl + 'PATH TO SCRIPT');
Run Code Online (Sandbox Code Playgroud)
哪个有效.它运作良好.例如,如果我添加
$.getScript(rootUrl + '/Assets/masonry.js');
Run Code Online (Sandbox Code Playgroud)
然后,即使在ajaxed之外加载了masonry.js,也会在获取ajaxed内容时重新触发砌体函数调用 div
我将你引用到github上的插件文件,以便更清楚地了解修复实际做了什么(我无法理解$.getScript使用时会发生什么)
如果您有3-4个需要在ajaxed内容上重新触发的脚本,那么官方修复工作正常.
这对我的目标不起作用,因为
一个可能的解决方案可能涉及添加一个模仿触发器的事件,该事件会导致脚本在ajaxed的底部触发 div
当只通过ajax重新加载页面的某个部分时,如何强制所有脚本(包括动态添加的脚本)重新触发?
笔记:
我试图避免逐个调用脚本,因为这需要事先知道他们的调用.我可能在谈论我的头脑但是......
我试图模仿页面加载和/或文档就绪事件 - 大多数条件脚本被触发(如果我错了就纠正我) - <main>在我的html结尾处添加新的ajaxed内容但不影响文档通过直接使用URL加载页面...或任何其他类似的方法.
只是为了一些上下文,这里是插件关闭时页面上的一些事件监听器的列表.我知道那里有些东西我不必触发.我刚刚添加了这个作为参考.另请注意,这是从其中一个页面中提取的样本.其他页面可能不同.
DOMContentLoaded
beforeunload
blur
click
focus
focusin
focusout
hashchange
keydown
keyup
load
message
mousedown
mousemove
mouseout
mouseover
mouseup
mousewheel
orientationchange
readystatechange
resize
scroll
submit
touchscreen
unloadRun Code Online (Sandbox Code Playgroud)
cjg*_*cjg 15
您在此处选择的解决方案必须依赖于脚本的初始化方式.有几种常见的可能性:
加载脚本后立即激活脚本的操作.在这种情况下,脚本可能如下所示:
(function() {
console.log('Running script...');
})();
Run Code Online (Sandbox Code Playgroud)响应某些事件(例如文档就绪(JQuery)或窗口载入(JavaScript)事件)而引发脚本的动作.在这种情况下,脚本可能如下所示:
$(window).on('load', function() {
console.log('Running script...');
});
Run Code Online (Sandbox Code Playgroud)下面考虑这两种可能性的一些选择.
一种选择是<script>从DOM中删除要触发的元素,然后重新附加它们.使用JQuery,你可以做到
$('script').remove().appendTo('html');
Run Code Online (Sandbox Code Playgroud)
当然,如果上面的代码片段本身就是一个<script>标记,那么你将创建一个无限循环,不断分离并重新附加所有脚本.此外,可能还有一些您不想重新运行的脚本.在这种情况下,您可以向脚本添加类以正面或负面地选择它们.例如,
// Positively select scripts with class 'reload-on-ajax'
$('script.reload-on-ajax').remove().appendTo('html');
// Negatively select scripts with class 'no-reload'
$('script').not('no-reload').remove().appendTo('html')
Run Code Online (Sandbox Code Playgroud)
在您的情况下,您可以将上述代码段中的一个放在事件处理程序中以完成AJAX.以下示例使用按钮单击代替AJAX完成事件,但概念是相同的(请注意,此示例在StackOverflow沙箱中不能很好地工作,因此请尝试将其作为单独的页面加载以获得最佳结果) :
<html>
<head></head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script class="reload-on-ajax">
console.log('Script after head run.');
</script>
<body>
<button id="reload-scripts-button">Reload Scripts</button>
</body>
<script class="reload-on-ajax">
console.log('Script after body run.');
</script>
<script>
$('#reload-scripts-button').click( () => $('script.reload-on-ajax').remove().appendTo('html') );
</script>
</html>Run Code Online (Sandbox Code Playgroud)
请注意,如果脚本不是内联的(例如,通过src属性获取),则它们将从服务器重新加载或从浏览器缓存中检索,具体取决于浏览器和设置.在这种情况下,最好的方法可能是删除所有对<script>加载AJAX的内容进行操作的s,并通过getScript()AJAX完成事件处理程序中的JQuery 函数加载/运行它们.这样,您只需在适当的时间(即加载AJAX内容后)加载/运行脚本一次:
// In AJAX success event handler
$.getScript('script1.js');
$.getScript('script2.js');
Run Code Online (Sandbox Code Playgroud)
这种方法的两种变体的潜在问题是脚本的异步加载受到跨源限制.因此,如果脚本托管在不同的域上,并且不允许跨源请求,则它将不起作用.
如果脚本是在窗口加载时触发的,那么您可以触发此事件:
$(window).trigger('load');
Run Code Online (Sandbox Code Playgroud)
不幸的是,如果脚本本身使用JQuery的文档就绪事件,那么我不知道一种简单的手动触发它的方法.脚本也可能响应其他事件而运行.
显然,您可以根据需要组合上述方法.并且,正如其他人所提到的,如果脚本中有一些初始化函数可以调用,那么这是最干净的方法.
如果您可以在外部脚本中识别全局初始化函数或代码块,则可以看看'ajaxComplete'事件。您可以将此代码放在页眉中,并将初始化函数调用或代码块放在ajaxComplete回调中。
$(document).ajaxComplete(function(){
module1.init();
$('#my_id').module2_init({
foo : 'bar',
baz : 123
});
});
Run Code Online (Sandbox Code Playgroud)
当您正在谈论的脚本没有这样易于使用的公开初始化功能,而是在scriptload上进行初始化时,我认为不会有适用于所有脚本的开箱即用的方法。
小智 5
这是你可以尝试的 -
大多数脚本(如砌体或Google Map)都设置为在窗口大小调整时重新初始化.因此,如果在ajax完成后触发resize事件,将有助于自动重新触发这些脚本.
请尝试以下代码 -
$( document ).ajaxComplete( function() {
$( window ).trigger('resize');
} );
Run Code Online (Sandbox Code Playgroud)
这将强制脚本在ajax完成后重新初始化,因为它现在将在加载内容后触发resize事件.
| 归档时间: |
|
| 查看次数: |
2011 次 |
| 最近记录: |