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

时间:2022-09-25 18:43:44

I'm having a little issue with an application I'm making. I have a page where the user edits a document via dragging modules into the page or "canvas" area.

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

http://thinktankdesign.ca/temp_img.jpg

When the page is loaded, javascript haves the modules collapsible (like above). However after the user drags in a new module the effect is applied again some new modules can collapse as well. here is the problem. each time a module loads the same effect gets applied to the modules that already can collapse. It ends up breaking their animations.

当加载页面时,javascript使模块可折叠(如上面所示)。然而,当用户在一个新的模块中拖拽之后,效果再次被应用,一些新的模块也会崩溃。问题是这样的。每次模块加载时,对已经崩溃的模块应用相同的效果。它最终破坏了他们的动画。

heres the code that gets executed on page load.

这是在页面加载时执行的代码。

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

and heres the code that gets executed in the creation of a module via ajax

下面是通过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");

        }
    );
}

I need a solid way of preventing the toggle effect to be applied to the same module twice

我需要一种可靠的方法来防止切换效果两次应用到同一个模块

3 个解决方案

#1


1  

Use jQuery 1.3 live events instead.

使用jQuery 1.3实时事件。

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

and then eliminate the click declaration in the second block of code, changing it to $("h1.handle").addClass("open");

然后消除第二个代码块中的单击声明,将其更改为$(“h1.handle”).addClass(“open”);

Live events bind all current and future matching elements with an event.

活动事件将当前和未来的所有匹配元素与事件绑定在一起。

#2


1  

In your Ajax success handler try the following:

在您的Ajax成功处理程序中,尝试以下步骤:

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

#3


1  

The best way to solve your problem is, instead of using $("h1.handle") on the AJAX callback, go for $(data).find("h1.handle"). Something like,

解决问题的最佳方法是,在AJAX回调中使用$(“h1.handle”)而不是使用$(data).find(“h1.handle”)。类似的,

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

Like that, only the newly added items will have the event bounded. The already present ones will not be touched.

这样,只有新添加的项才会对事件进行限制。已经存在的不会被碰。

If we want to answer your question instead of just solving your problem, then we have several alternatives, such as:

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

  • store, in your objects, that the onclick event handler has been set so that you don't set it twice
  • 将onclick事件处理程序设置在对象中,这样就不会设置两次
  • always bind the onclick event, but always unbind it first
  • 总是绑定onclick事件,但总是先解绑定它
  • use jQuery's live events and the addClass open only on the newly created items.
  • 使用jQuery的活动事件和只在新创建的项上打开的addClass。

IMO, the first one is the easiest. You can accomplish it by using jQuery's data(). Then you could do something like:

在我看来,第一个是最简单的。您可以通过使用jQuery的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');
}

The second alternative involves storing the function that you pass inline to the click event binder in a variable, and then using jQuery's unbind to disable it.

第二种方法是将传递给单击事件绑定器的函数存储在一个变量中,然后使用jQuery的unbind来禁用它。

#1


1  

Use jQuery 1.3 live events instead.

使用jQuery 1.3实时事件。

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

and then eliminate the click declaration in the second block of code, changing it to $("h1.handle").addClass("open");

然后消除第二个代码块中的单击声明,将其更改为$(“h1.handle”).addClass(“open”);

Live events bind all current and future matching elements with an event.

活动事件将当前和未来的所有匹配元素与事件绑定在一起。

#2


1  

In your Ajax success handler try the following:

在您的Ajax成功处理程序中,尝试以下步骤:

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

#3


1  

The best way to solve your problem is, instead of using $("h1.handle") on the AJAX callback, go for $(data).find("h1.handle"). Something like,

解决问题的最佳方法是,在AJAX回调中使用$(“h1.handle”)而不是使用$(data).find(“h1.handle”)。类似的,

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

Like that, only the newly added items will have the event bounded. The already present ones will not be touched.

这样,只有新添加的项才会对事件进行限制。已经存在的不会被碰。

If we want to answer your question instead of just solving your problem, then we have several alternatives, such as:

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

  • store, in your objects, that the onclick event handler has been set so that you don't set it twice
  • 将onclick事件处理程序设置在对象中,这样就不会设置两次
  • always bind the onclick event, but always unbind it first
  • 总是绑定onclick事件,但总是先解绑定它
  • use jQuery's live events and the addClass open only on the newly created items.
  • 使用jQuery的活动事件和只在新创建的项上打开的addClass。

IMO, the first one is the easiest. You can accomplish it by using jQuery's data(). Then you could do something like:

在我看来,第一个是最简单的。您可以通过使用jQuery的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');
}

The second alternative involves storing the function that you pass inline to the click event binder in a variable, and then using jQuery's unbind to disable it.

第二种方法是将传递给单击事件绑定器的函数存储在一个变量中,然后使用jQuery的unbind来禁用它。