Преместване на голям набор от HTML обекти на страницата и повторно свързване на събития с jQuery

Имам DIV с много елементи, върху които може да се кликне. Всеки със своето уникално събитие. Този DIV има "закачен" режим, където се показва на друго място и оформление на страницата, когато режимът е превключен.

Трябва да отбележа, че основният ми целеви браузър е IE8. Много от проблемите, с които се сблъсквам тук (SSSSLLLLLOOOOWWWWW), просто изчезват, когато тествам в Chrome.

Опитвах се да използвам метода $(...).html(), за да преместя HTML съдържанието на новото място. Това работи, но събитията се губят. Мога да използвам .live() вместо .bind(), но това прави всички отговори на събития около 10 пъти по-бавни (не забравяйте, че имам МНОГО елементи в този DIV).

Друго нещо, което опитах, е просто да създам съдържание в двата DIV и да обвържа събития към двата. След това мога да превключа основната видимост на DIV. Това направи създаването на DOM много по-бавно от преди (все още момент в Chrome, но не и в IE).

Търся "класическия" начин (ако съществува) за извършване на това преместване на съдържание на страницата, като същевременно запазвам събитията непокътнати.

АКТУАЛИЗАЦИЯ Мислете за това действие за докинг като нещо подобно на закрепване на плаващ прозорец от едната страна на екрана във Visual Studio.


person Ron Harlev    schedule 11.02.2010    source източник
comment
съдържанието ще се показва ли няколко пъти едновременно?   -  person Soufiane Hassou    schedule 11.02.2010
comment
Не. Това е или или. Единият ще бъде скрит, когато се покаже другият.   -  person Ron Harlev    schedule 11.02.2010


Отговори (3)


Ако използвате jquery 1.4, можете да използвате detach:

The .detach() method is the same as .remove(), except that .detach() keeps all jQuery data associated with the removed elements. This method is useful when removed elements are to be reinserted into the DOM at a later time.
<body>
    <div id='container1'>...elements with bound events...</div>
    <div id='container2'></div>
</body>
<script>
    var divs = $("#container1").children().detach(); // removes the node from the DOM
    $("#container2").empty().append(divs);
</script>

или използвайте clone(true), ако искате и двата div да се показват едновременно:

var divs = $("#container1").clone(true);
$("#container2").empty().append(divs);

За това, че $.fn.live() е твърде бавен:
Можете да опитате да промените "live", за да бъде малко по-ефективен, така че да работи по следния начин:

// $.live(selector,    context,         event,   fn);
   $.live("a.explode", "div.container", "click", function(){
       alert("boom"); return false;
   });

Това, което трябва да направи, е да обвърже типа на събитието с контекстния елемент, БЕЗ първо да търси елементите на селектора. Не знам дали ще бъде полезно във вашия случай, но реших, че си струва да го спомена.

За да ускорите нещата още повече, използвайте mousedown вместо щракване:

$("a").mousedown(function(){
    // do stuff...
}).click(function(){return false;});
person David Murdoch    schedule 11.02.2010
comment
Благодаря. .detach() работи перфектно. Благодаря за страхотното обобщение на опциите. Страхотна информация. Бих гласувал повече от веднъж, ако беше възможно :) - person Ron Harlev; 11.02.2010

Ако сте загрижени за бавността, можете просто да използвате css и да преместите div наоколо, където искате?

person Soufiane Hassou    schedule 11.02.2010

Ако имате купища елементи, към които трябва да прикачите събития, тогава най-ефективният начин е да използвате делегиране на събития. .live() ще работи, но както видяхте, това може да е бавно с много елементи.

Ето прост пример за прослушване на събитие за щракване вътре в div и проверка дали котва го е задействала:

$("#container").click(function(e) {

  var $target = $(e.target);
  if ($target.is("a")) {
    // do some
  }

});
person ScottE    schedule 11.02.2010
comment
Имайте предвид, че използването на $target.closest(a,this)[0] вместо $target.is(a) може да е по-добро в някои случаи. - person David Murdoch; 11.02.2010