JQuery UI (效果核心) addClass/removeClass on 一个元素有多个选择器...但有一个问题



感谢您的光临。我试图在单击前面的同级div时使用jQ UI addClass/remove-Class方法来扩展hr元素。jQ UI特效核心实现了两个类之间的平滑动画转换:http://jqueryui.com/demos/removeClass/.此外,必须使用$动态添加hr,以实现更广泛的站点设计。

以下是拼图:

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

我被卡住了。我试过很多jQ函数组合,但结果都很糟糕。你看到的是我最接近的。谢谢你给这个机会。请随意添加到代码中,以使其正常工作。

<!--HTML...the children divs of ".main" can have their own unique classes if that helps-->
<div class="main">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
/*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 <hr> after every 4th div.
$(".main div:nth-child(4n)").after('<hr class="closed"></hr>');
//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(你提到这正是你想要的):

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

jQuery:

$(".main article:nth-child(4n)").after('<hr class="split"></hr>');
$(".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()不将函数作为参数。检查相关文件;它不像CCD_ 3
  3. 没有理由为添加和删除分别设置功能。您还删除了两个类。你是否希望下一个HR保持开放状态?或者希望它立即打开和关闭?如果是后者,则没有理由使用此行$('hr').removeClass('open', 1000);。如果是前者,则没有理由使用第二个函数(),其中包含$(this).nextAll("hr").first().removeClass('open', 500)

这是我在fiddle 中使用的javascript

$(document).ready(function() {
//dynamcally adds the <hr> after every 4th div.
$(".main div:nth-child(4n)").after('<hr class="closed"></hr>');
//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结合了淘汰和骨干。我知道我忘记了其他一些流行的&好的。。。

最新更新