JQuery UI(效果核心)addClass / removeClass在一个元素上有多个选择器……但是有一个问题

谢谢参观。 我正在尝试使用jQ UI addClass / remove类方法在单击前面的兄弟div时扩展hr元素。 jQ UI效果核心可以在两个类之间实现平滑的动画过渡: http : //jqueryui.com/demos/removeClass/ 。 此外,必须使用$动态添加hr才能实现更广泛的网站设计。

以下是这个难题的部分:

  1. 我的代码呈现四个100x100px兄弟div的行。 这些div没有课程,但如果它有帮助,请随意添加它们 – 每个div最终都会有一个独特的课程。 在每第4个div之后,有一个动态添加的hr。
  2. 单击任何给定的div后,紧接的下一个hr必须切换到“open”类,这会导致行展开。 如果再次单击此div,它必须从hr切换/删除“打开”类,导致hr缩小到原始大小。
  3. 如果单击一个div以展开hr然后单击另一个div,则必须触发两个动画:首先,必须删除“open”类,导致行缩小,然后必须重新添加该类重新开行。 但是,例如,如果单击div打开第二行,然后单击第一个hr之前的第二个div,则此操作必须先关闭第二个hr,然后打开第二个div的相应hr。

我被卡住了。 我已经尝试了一些jQfunction组合,但结果很糟糕。 你看到的是我得到的最接近的。 谢谢你给这一个人一个机会。 随意添加到代码中,但您可以使其工作。

 
/*CSS-some of this creates other events not mentioned above. These are simplified versions of what I need for my final site design*/ .main { width: 450px; } .main div { height: 100px; width: 100px; background-color: #000; margin: 3px; float:left; } div.select { background-color: #f00; border: 2px solid #00F; margin: 3px; float:left; display: block; } div.active { background-color: #f00; margin: 3px; float:left; display: block; } hr { background-color: #FF0; float: left; display: block; height: 20px; width: 450px; } hr.open { float: left; display: block; height: 300px; width: 450px;

}

 /*the JS - sorry about the double quotes. I'm using Dreamweaver, which seems to add them to everything*/ $(document).ready(function() { //dynamcally adds the 
after every 4th div. $(".main div:nth-child(4n)").after('
'); //puts a blue border on the squares $('.main div').hover(function() { $(this).addClass('select'); }, function() { $(this).removeClass('select') }); //changes the color of the active square to red and "deactivates" the previous one. $('.main div').click(function() { $(this).toggleClass('active').siblings().removeClass('active'); }); //here in lies the problem...??? $('.main div').click(function() { $('hr').removeClass('open', 1000); $(this).toggle (function() { $(this).nextAll("hr").first().addClass('open', 500); }, function() { $(this).nextAll("hr").first().removeClass('open', 500) }); }); });

我很确定这就是你想要的,我从http://makr.com复制了一般的HTML布局(你提到那就是你想要的):

演示: http : //jsfiddle.net/SO_AMK/xm7Sk/

jQuery的:

 $(".main article:nth-child(4n)").after('
'); $(".main > article .slidedown").click(function(e) { e.stopPropagation(); }); // If you click on the slidedown, it won't collapse var canAnimate = true, slideIsOpen = false, animateSpeed = 1000; $(".main > article").hover(function() { $(this).addClass("hover"); }, function() { $(this).removeClass("hover"); }).click(function() { if (canAnimate) { canAnimate = false; var article = $(this), isThisOpen = article.hasClass("active"); if (isThisOpen) { $(".main").queue(function () { hideSlide($(this)) }); } else { if (slideIsOpen) { $(".main").queue(function () { hideSlide($(this)); }).queue(function () { positionPage(article, $(this)); }).queue(function () { showSlide(article, $(this)); }).queue(function () { positionPage(article, $(this)); }); } else { $(".main").queue(function () { positionPage(article, $(this)); }).queue(function () { showSlide(article, $(this)); }).queue(function () { positionPage(article, $(this)); }); } } } }); function showSlide(elm, main) { canAnimate = false; slideIsOpen = true; elm.nextAll("hr.split").first().addClass("active", animateSpeed); elm.children(".slidedown").css("top", (elm.offset().top + 114)).addClass("active").slideToggle(animateSpeed); elm.addClass("active"); main.dequeue(); canAnimate = true; } function hideSlide(main) { canAnimate = false; $(".main article.active").nextAll("hr.split.active").removeClass("active", animateSpeed); $(".main article.active").children(".slidedown").removeClass("active").slideToggle(animateSpeed); $(".main article.active").removeClass("active"); $(main).dequeue(); canAnimate = true; slideIsOpen = false; } function positionPage(elm, main) { canAnimate = false; var body; if ($.browser.safari) { body = $("body"); } else { body = $("html"); } var elmTop = elm.offset().top, bodyScroll = body.scrollTop(); if (bodyScroll - elmTop == 0) { var speed = 0; } else { var speed = animateSpeed; } body.animate({ scrollTop: elmTop }, speed, function () { main.dequeue(); canAnimate = true; }) }​

对于这么小的东西来说,这可能看起来像一个大脚本,但它有一些失败保险。 唯一的错误是,如果你在转换过程中开始快速点击,有时候队列会以错误的顺序结束。 但是,普通用户在动画期间不会快速点击:D

试试这个大小: http : //jsfiddle.net/Bv57T/3/

主要变化:

  1. 你有2个.click绑定到同一个选择器$('.main div') 。 我相信这在技术上是受支持的,但是没有理由这样做,这使得你的代码更难以遵循。
  2. .toggle()不将函数作为参数。 检查文档 ; 它不像hover()
  3. 没有理由为添加和删除提供单独的function。 你也要两次删除课程。 您是否希望下一个HR能够开放并保持开放? 或者希望它立即打开和关闭? 如果是后者,则没有理由将此行$('hr').removeClass('open', 1000); 。 如果是前者,那么第二个函数()没有理由使用$(this).nextAll("hr").first().removeClass('open', 500)

这是我在小提琴中使用的javascript

 $(document).ready(function() { //dynamcally adds the 
after every 4th div. $(".main div:nth-child(4n)").after('
'); //puts a blue border on the squares $('.main div').hover( function() { $(this).addClass('select'); }, function() { $(this).removeClass('select') }); //changes the color of the active square to red and "deactivates" the previous one. $('.main div').click(function() { $('hr.open').removeClass('open', 1000); if(!$(this).hasClass('active')) { $(this).nextAll("hr").first().addClass('open', 500); } $(this).toggleClass('active').siblings().removeClass('active'); }); });​

如果那不是你想要的并且无法从这里弄清楚,那就继续发回去,我可以再拿一个它。

编辑新的和改进的版本: http : //jsfiddle.net/Bv57T/4/也更新了上面的js。

如果在动画正在进行时点击第二个div,它仍然可以伪造出来。 你可以通过在动画的持续时间内将(全局)bool设置为true并在开始下一个动画之前检查它来解决这个问题。

但问题的根源在于你试图将UI的状态(换句话说,DOM)作为应用程序的状态加倍。 即使是简单的操作,这也会变得非常毛茸茸(你也看到过)。 我喜欢这种方法的首选方法是使用一个将UI与应用程序分开的库。 这些通常被称为MVC(模型 – 视图 – 控制器)或MVVM(模型 – 视图 – 视图模型 – 我讨厌的名字,因为它感觉有意混淆)。 我最喜欢的是knockout.js 。 它与jQuery和jQuery UI完全兼容; 看看这个例子: 动画过渡 。

还有更多这样的图书馆。 Backbone.js是一个,knockback.js结合了淘汰赛和骨干。 我知道我忘了其他一些受欢迎的好人……