首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JQuery UI (效果核心) addClass/removeClass在一个具有多个selectors...but的元素上有一个陷阱

JQuery UI (效果核心) addClass/removeClass在一个具有多个selectors...but的元素上有一个陷阱
EN

Stack Overflow用户
提问于 2012-09-19 02:55:37
回答 2查看 1.6K关注 0票数 3

谢谢你看一看。我正在尝试使用jQ UI addClass / remove方法在单击前面的同级div时展开hr元素。jQ UI效果核心支持两个类之间的平滑动画转换:http://jqueryui.com/demos/removeClass/。此外,人力资源必须与$动态添加,以实现更广泛的网站设计。

下面是拼图的几个部分:

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

我卡住了。我尝试过一些jQ函数组合,但是结果很奇怪。你看到的是我最近看到的。谢谢你给我一次机会。可以随意地添加到代码中,但是您可以这样做。

代码语言:javascript
复制
<!--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;

}

代码语言:javascript
复制
/*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)
        });

    });
});
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-09-20 17:34:46

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

演示:AMK/xm7Sk/

jQuery:

代码语言:javascript
复制
$(".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

票数 2
EN

Stack Overflow用户

发布于 2012-09-19 14:57:52

试一下这个尺寸:http://jsfiddle.net/Bv57T/3/

主要变化:

  1. 您有两个.click绑定到相同的选择器$('.main div')。我相信,这在技术上是支持的,但是没有理由这样做,这会使您的代码更难理解。
  2. .toggle()不以函数作为参数。检查一下文档,它不像hover()
  3. 没有理由为添加和删除设置单独的函数。您还需要删除两次类。你想让下一个人力资源部打开并保持开放吗?还是想让它立即打开和关闭?如果是后者,则没有理由使用这一行$('hr').removeClass('open', 1000);。如果是前者,则没有理由使用带有$(this).nextAll("hr").first().removeClass('open', 500)的第二个函数()。

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

代码语言: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将敲除和主干结合在一起。我知道我忘了一些其他流行的&好的.

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12487937

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档