【问题标题】:jQuery events not happening after AJAX load?AJAX 加载后没有发生 jQuery 事件?
【发布时间】:2011-05-04 03:39:58
【问题描述】:

我有一个网站,它将淡出我网站的一部分、加载新内容并淡入。我有一个功能,当您单击它时图片会变大(这是一个 jQuery 事件)。

当我在加载时将它放在代码上时它可以工作,但是当我单击 AJAX 加载区域中的某些内容时没有任何反应。

这是我加载 AJAX 的方式:

  // If the user clicks the logo
$("#logo").click(function() {
$("#right_bar_wrapper").animate({ height: 'toggle', opacity: 'toggle' }, '200');
var thePostData = "username=c";
$.ajax({
  type: "POST",
  url: "http://myflashpics.com/v2/process_newsfeed.php",
  data: thePostData,
  success: function(theRetrievedData) {
    document.getElementById('right_bar_wrapper').innerHTML = theRetrievedData;
    $("#right_bar_wrapper").fadeIn("200");
  }
});
});

我是这样放大图片的:

// If the user makes a picture bigger
$(".makePictureBig").click(function() {
var theClassId = $(this).attr('id');  
var theID = theClassId.substring(6)
var bigPictureComment = "#bigpicture_comment_" + theID;
var littlePictureComment = "#littlepicture_comment_" + theID;
var ddd = document.getElementById(theClassId);
var getBig = document.getElementById(bigPictureComment);
var getLittle = document.getElementById(littlePictureComment);
if (ddd.style.width == "180px") {
    ddd.style.width="430px";
    ddd.style.marginBottom='10px';
    ddd.style.cssFloat="left";
    $(littlePictureComment).hide();
    $(bigPictureComment).show();
} else {
   ddd.style.width="180px";
   ddd.style.marginBottom='0px';
   $(bigPictureComment).hide();
   $(littlePictureComment).show();
}
});

这是我在显示时加载的代码:

<div class="sidebar_image_box_newsfeed">
<div class="sidebar_image_box_newsfeed_user_info makeProfileAppear"><img src="http://myflashpics.com/get_image.php?short_string=uxpi&size=thumbnail" />Brandon Vento</div>
<img src="http://myflashpics.com/get_image.php?short_string=o1sk&size=big" id="image_o1sk" class="makePictureBig" style="width: 180px; margin-bottom: 15px;" />
<div class="sidebar_image_box_newsfeed_user_info_comments" style="float: right; margin-top: -1px; margin-left: 20px; display: none;" id="bigpicture_comment_o1sk">9</div>
<div class="sidebar_image_box_newsfeed_caption">A cool caption will eventually go here.</div>
<div class="sidebar_image_box_newsfeed_user_info_comments" id="littlepicture_comment_o1sk">9</div>
<div style="clear: both;"></div>
</div>

以下是通过 AJAX 加载后未加载的内容:

<div class='sidebar_image_box_newsfeed'> 
<div class='sidebar_image_box_newsfeed_user_info makeProfileAppear' id='user_coultonvento'><img src='http://myflashpics.com/get_image.php?short_string=kmdp&size=thumbnail' />TheAmazingCoultoniusTheFourneeth...</div> 
<img src='http://myflashpics.com/get_image.php?short_string=6v9o&size=big' id='image_6v9o' class='makePictureBig' style='width: 180px;' /> 
<div class='sidebar_image_box_newsfeed_user_info_comments' style='float: right; margin-top: -1px; margin-left: 20px; display: none;' id='bigpicture_comment_6v9o'>9</div> 
<div class='sidebar_image_box_newsfeed_caption'>Usama bin laden? I believe that's a typo, Fox. </div> 
<div class='sidebar_image_box_newsfeed_user_info_comments' id='littlepicture_comment_6v9o'>9</div> 
<div style='clear: both;'></div> 
</div><div class='sidebar_image_box_newsfeed'> 
<div class='sidebar_image_box_newsfeed_user_info makeProfileAppear' id='user_BrandonVento'><img src='http://myflashpics.com/get_image.php?short_string=e4r7&size=thumbnail' />Brandon Vento</div> 
<img src='http://myflashpics.com/get_image.php?short_string=o1sk&size=big' id='image_o1sk' class='makePictureBig' style='width: 180px;' /> 
<div class='sidebar_image_box_newsfeed_user_info_comments' style='float: right; margin-top: -1px; margin-left: 20px; display: none;' id='bigpicture_comment_o1sk'>9</div> 
<div class='sidebar_image_box_newsfeed_caption'></div> 
<div class='sidebar_image_box_newsfeed_user_info_comments' id='littlepicture_comment_o1sk'>9</div> 
<div style='clear: both;'></div> 
</div>

对不起所有的代码。我觉得这一切都是必要的!

提前致谢!
库尔顿

【问题讨论】:

    标签: php javascript html jquery


    【解决方案1】:

    .click().bind('click') 的简写,它只绑定到页面中已经存在的元素

    要将事件绑定到当前和未来的元素,您必须使用 .live()

    // If the user makes a picture bigger
    $(".makePictureBig").live('click',function() {
         //code
    }); 
    

    编辑:

    从 jQuery 1.7 开始,不推荐使用 live。你可以使用jQuery on:

    $(".makePictureBig").on('click', function() {
        //code
    }); 
    

    或者,对于委托的事件处理程序:

    $("#wrapper").on('click', '.makePictureBig', function(){
        //code
    });
    

    【讨论】:

    • Live 无疑是一种解决方案,但我倾向于避免在不会在站点范围内使用的内部页面事件上使用“live”。如果您将 javascript 移动到单独的文件并且发现您已经重用了类名,这将防止出现问题。如果您在共享的 javascript 文件中大量使用它,您最终还会在很多页面上执行大量选择器。仍然是一个答案 (+1),但请谨慎使用。
    【解决方案2】:

    这是因为您在 document ready 中编写的所有事件将仅针对页面加载时可用的元素执行。

    您必须使用.live() 为所有当前和动态生成的元素绑定事件。

    或者您可以在 ajax 函数的成功回调中再次绑定事件。

    【讨论】:

      【解决方案3】:

      需要重新绑定加载元素的事件。

      类似:

      document.getElementById('right_bar_wrapper').innerHTML = theRetrievedData;
      $(".makePictureBig").click(picBigFunction);
      

      【讨论】:

      • 在你的例子中“picBigFuntion”到底是什么?
      【解决方案4】:

      您必须在已加载的任何新内容上重新绑定 ajax 事件。

      将初始化单击事件的代码(即其中包含 .click(...) 的部分)放入单独的函数中。

      例如:

      function initImage() {
        ....click(function() {
      
        }
      }
      

      然后在 document.ready 和您的 ajax 成功事件上调用该函数。

      可能还值得添加以下内容:

      $(".makePictureBig").unbind("click");
      

      就在之前:

      $(".makePictureBig").click(function() { ...
      

      为了确保您不会在每个 ajax 帖子上两次附加相同的事件。

      完整示例(此过程很快完成,您可能不需要重新初始化徽标,但如果您使用不同的 ajax 帖子更改其他任何内容,则在一个地方完成所有操作会更安全):

      $(document).ready(function() {
        initImages();
      }
      
      
      
      function initImages() {
      
      $(".makePictureBig").unbind("click");
      $(".makePictureBig").click(function() {
      var theClassId = $(this).attr('id');  
      var theID = theClassId.substring(6)
      var bigPictureComment = "#bigpicture_comment_" + theID;
      var littlePictureComment = "#littlepicture_comment_" + theID;
      var ddd = document.getElementById(theClassId);
      var getBig = document.getElementById(bigPictureComment);
      var getLittle = document.getElementById(littlePictureComment);
      if (ddd.style.width == "180px") {
          ddd.style.width="430px";
          ddd.style.marginBottom='10px';
          ddd.style.cssFloat="left";
          $(littlePictureComment).hide();
          $(bigPictureComment).show();
      } else {
         ddd.style.width="180px";
         ddd.style.marginBottom='0px';
         $(bigPictureComment).hide();
         $(littlePictureComment).show();
      }
      });
      $("#logo").unbind("click");
      $("#logo").click(function() {
      $("#right_bar_wrapper").animate({ height: 'toggle', opacity: 'toggle' }, '200');
      var thePostData = "username=c";
      $.ajax({
        type: "POST",
        url: "http://myflashpics.com/v2/process_newsfeed.php",
        data: thePostData,
        success: function(theRetrievedData) {
          document.getElementById('right_bar_wrapper').innerHTML = theRetrievedData;
          $("#right_bar_wrapper").fadeIn("200");
          initImages();
        }
      });
      });
      
      }
      

      【讨论】:

      • 所以我会在信息处理完后再放那个?我是否必须重新输入整个函数并将其放入用于获取数据的函数中?
      【解决方案5】:

      我建议查看一个名为 livequery 的 jquery 插件

      你可以替换:

      $(".makePictureBig").click(function() {
        //existing stuff
      

      $(".makePictureBig").livequery(function() {
         $(this).click(function() {
         //existing stuff
      

      使用 livequery,只要将元素放入与选择器匹配的 dom 中,就会触发回调函数。

      【讨论】:

      • 所以,我在安德烈之后大约 30 秒回答了这个问题。 Live 也是一个合适的解决方案,不同之处在于 live 只会让您将事件绑定到未来的元素,而 livequery 插件将允许您将任何内容绑定到选择器。不过,为 Andre +1,因为在这种情况下,这确实是您所需要的。
      • 源代码+1。直接放进去,还是不行: ` $(".makePictureBig").livequery(function() { $(this).click(function() { // 这里的内容(和上面的例子内容一样) ) }); });
      • livequery 需要和额外的插件,这对你需要的东西来说太过分了。只使用 live 是最好的解决方案。
      【解决方案6】:

      其他答案是正确的,但我会扩展。当您使用jQuery.bind 绑定事件时(注意click 等是bind 的宏),它只会将事件绑定到当前存在的DOM 元素。 jQuery 选择器扫描 DOM 以查找与选择器匹配的所有元素($("#hoo").click() 将事件处理程序绑定到 id="hoo" 的任何现有元素)。

      当元素通过 ajax 或其他方式添加到 DOM 时,它们不会自动获取绑定到它们的所有处理程序。为了做到这一点,jQuery 必须为每个事件扫描 DOM,并将处理程序应用于它随时找到的任何新元素。这是不切实际的。

      这两种解决方案是将处理程序应用于稍后加载到 DOM 的任何元素。例如,将上面的“点击”功能更改为实际功能:

      function makePictureBig() {
         var theClassId = this.id;
         ...
      }
      

      然后说$(".makePictureBig").click(makePictureBig); ...在您的 Ajax 中:$("#right_bar_wrapper").html(theRetrievedData) .find(".makePictureBig").click(makePictureBig);

      第二种选择是使用.live().delegate() 或像.livequery() 这样的插件。

      【讨论】:

        【解决方案7】:

        Delegate 是比 Live 更好的选择。您可以委托给更高级别的元素。你甚至可以这样做:

        $('body').delegate('.makePictureBig', 'click', function() {
          //code
        });
        

        【讨论】:

          【解决方案8】:

          使用

          $("****").live('click',function() {}); 
          

          【讨论】:

            猜你喜欢
            • 2021-05-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-04-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多