使用.delegate来包装通过AJAX加载的内容

时间:2016-02-10 09:53:08

标签: php jquery ajax iframe

我使用Buddypress构建了一个简单的社交网络,可以通过AJAX加载页面加载后发布的任何新状态更新。为了使时间轴视频响应(在iframe中),我使用以下内容:

的jQuery

jQuery(function($) {
  $( ".activity-inner p iframe" ).wrap( "<div class='embed-container'></div>" );
});

HTML(默认BuddyPress输出)

<div class="activity-inner">
  <div class="embed-container">
    <p><iframe width="500" height="281" frameborder="0" allowfullscreen="" src="https://www.youtube.com/embed/gvOx9VMZtBA?feature=oembed"></iframe></p>
  </div>
</div>

但是,当通过AJAX加载带有视频嵌入的新帖子时,这不再适用于iframe的任何新实例。根据我的理解,使用.delegate可以实现这一点,但如果我的逻辑有点偏离,我会接受任何其他建议。如果有人能够阐明如何用上面的代码包装通过AJAX加载的新iframe,我会非常感激。

*更新*

我已经修改了一个非常简单的方法来使用PHP执行此操作,以便使用“functions.php”中的以下代码段将生成的任何嵌入包装在源代码中:

add_filter('oembed_dataparse','oembed_add_wrapper',10,3);
function oembed_add_wrapper($return, $data, $url) {
  return "<div class='embed-container'>{$return}</div>";
}

感谢@Tomalak通过https://github.com/kapetan/jquery-observe(下方)提供了另一个有效的解决方案。

1 个答案:

答案 0 :(得分:1)

有三种不同的方法可以解决这个问题,具体取决于新元素如何到达您的网页。

  1. 如果你控制Ajax请求,那么在Ajax请求的成功回调中包装他们自己返回的iframe。这是最简单的解决方案。

  2. 如果第三方库控制Ajax请求并且该库提供了一个事件系统(请参阅该库的文档),那么对这些事件作出反应并在iframe包装时将其包装起来发生。这类似于选项1.

  3. 如果第三方库控制Ajax请求,并且此库不提供事件系统(极不可能),即您无法控制页面上何时出现新元素,然后(只有这样!)你可以诉诸于DOM的变化,如下所示。

  4. 如果您认为选项#3 是解决问题的唯一方式

    您可以使用Mutation Observers来监控DOM的更改。这是supported in all major browsers now

    请务必仔细阅读文档 ,以便了解他们可以做些什么,如何使用以及recordchildList的含义下面的代码。

    GitHub上有一个方便的jQuery插件,可以在jQuery使用模式中包含变异观察者:https://github.com/kapetan/jquery-observe

    你可以这样做:

    &#13;
    &#13;
    $(function () {
        // helper to find all unwrapped iframes and wrap them
        function enhancePost() {
            $(this).find("iframe").filter(function () {
                return $(this).parent(".embed-container").length === 0;
            }).wrap("<div class='embed-container'></div>");
        }
    
        // listen to DOM changes on the feedContainer
        $('#feedContainer').observe('childlist', '.activity-inner', function (record) {
            // a "#feedContainer > .activity-inner" has been added or removed
            console.log(record);
            $(record.addedNodes).each(enhancePost);
        });
    
    
        // example button and page init  
        $("#add").click(function () {
            $('<div class="activity-inner"></div>')
            .text("Post #" + ($(".activity-inner").length + 1))
            .append("<iframe></iframe>")
            .appendTo("#feedContainer");
        });
      
        $("#feedContainer .activity-inner").each(enhancePost);
    });
    &#13;
    #feedContainer {
      border: 1px solid red;
    }
    #feedContainer .activity-inner {
      border: 1px solid blue;
      margin: 5px;
      padding: 5px;
    }
    #feedContainer .embed-container {
      border: 1px solid green;
    }
    iframe {
      border: none;
      display: block;
      background-color: #efefef;
      height: 2em;
    }
    &#13;
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdn.rawgit.com/kapetan/jquery-observe/master/jquery-observe.js"></script>
    
    <div id="feedContainer">
      <div class="activity-inner">Post #1 <iframe></iframe></div>
      <div class="activity-inner">Post #2</div>
    </div>
    
    <button id="add">Add activity</button>
    &#13;
    &#13;
    &#13;