在使用ajax添加对象时,防止将效果应用于同一对象两次

时间:2010-01-29 20:02:41

标签: javascript jquery ajax

我正在制作一个应用程序的问题。我有一个页面,用户通过将模块拖动到页面或“画布”区域来编辑文档。

http://thinktankdesign.ca/temp_img.jpg

加载页面时,javascript使模块可折叠(如上所述)。但是,在用户拖动新模块后,再次应用效果,一些新模块也会崩溃。这是问题所在。每次模块加载时,相同的效果都会应用于已经崩溃的模块。它最终打破了他们的动画。

表示在页面加载时执行的代码。

//make colapsible
$("h1.handle").click(function() {
    var object = $(this);
    v$(this).next().toggle("fast", colapsible_class(object));
    vreturn false;
}).addClass("open");

并且是通过ajax

创建模块时执行的代码
function get_module(id){
    var template = $('input[name=template]').val();
    $.post(window.location.href, { template: template, module: id, mode: 'create' },
        function(data){
            $(data).insertBefore(".target_wrapper");

            //enable deletion of module
            $(".js_no_modules").slideUp("slow");
            $(enable_module_deletion());

            //show delete button
            $("button[name=delete]").show();

            //make colapsible
            $("h1.handle").click(function() {
                var object = $(this);
                $(this).next().toggle("fast", colapsible_class(object));
                return false;
            }).addClass("open");

        }
    );
}

我需要一种可靠的方法来阻止将切换效果应用于同一模块两次

3 个答案:

答案 0 :(得分:1)

在Ajax成功处理程序中尝试以下操作:

//make collapsible
        $("h1.handle:not(.open)").click(function() {
            var object = $(this);
            $(this).next().toggle("fast", colapsible_class(object));
            return false;
        }).addClass("open");

答案 1 :(得分:1)

使用jQuery 1.3 live events代替。

//make colapsible
$("h1.handle").live("click", function() {
    var object = $(this);
    v$(this).next().toggle("fast", colapsible_class(object));
    vreturn false;
}).addClass("open");

然后删除第二个代码块中的click声明,将其更改为$("h1.handle").addClass("open");

直播活动会将所有当前和未来匹配元素与事件绑定。

答案 2 :(得分:1)

解决问题的最佳方法是,不要在AJAX回调中使用$("h1.handle"),而是转到$(data).find("h1.handle")。像,

var x = $(data);
x.insertBefore(...);
/* your other code */
x.find('h1.handle').click(...).addClass(...);

就像那样,只有新添加的项目才会有事件限制。已经存在的那些将不会被触及。

如果我们想回答您的问题而不仅仅是解决您的问题,那么我们有几种选择,例如:

  • 在您的对象中存储已设置 onclick 事件处理程序,以便您不会将其设置为两次
  • 始终绑定 onclick 事件,但始终先取消绑定
  • 使用jQuery的直播事件,addClass仅对新创建的项目打开。

IMO,第一个是最简单的。您可以使用jQuery's data()完成此操作。然后你可以做类似的事情:

$("h1.handle").each(function() {
  var me = $(this);

  // if already has click handler, don't do anything
  if (me.data('click_set') != null) { return true; }
  // otherwise, store the data and bind the click event
  me.data('click_set', true).click(function() {
   /* the code you already have on the click handler */
  }).addClass('open');
}

第二种方法是将您内联传递的函数存储到变量中的click事件绑定器,然后使用jQuery's unbind禁用它。