在'n'元素上使用纯javascript的CSS类之间切换

时间:2015-02-04 18:10:08

标签: javascript html css3 classiejs

创建功能,当用户点击其中一个产品(每个元素具有相同的分配ID card-reveal)时,它会向容器中添加CSS class特别点击(活动状态)显示该特定项目的信息,最后,当用户单击取消按钮时,CSS类被删除(激活状态消失)。

不幸的是,我遇到了一些小问题,当我点击第一个元素时,它将类添加到该元素,但我点击的其他元素不添加类,以及关闭按钮根本不起作用。我想在 Pure Javascript 中完成解决方案。另外,如果您看到一些classie()方法,我使用Classie.js来帮助CSS类切换。

任何帮助将不胜感激!谢谢!

HTML

<a  id="card-reveal" class="card-view" href="javascript:void(0)"><h3 class='hover-title'>View More</h3></a>
<div class="card-cover">
                            <span class="card-exit"></span>

                            <a class="card-follow" href="javascript:void(0)">Follow {{object.product_website_name}}.com</a>
                            <a class="card-buy" target="_blank" href="{{object.product_slug_url}}">Buy {{object.product_name }}</a>
                            <a id="card-close" class="card-info" href="javascript:void(0)"><span class="icon-indie_web-03"></span></a>
                            <ul class="card-social">
                                <label>Share</label>
                                <li><a href="#"><span  class="icon-indie_web-04"></span></a></li>
                                <li><a href="#"><span  class="icon-indie_web-05"></span></a></li> 
                            </ul>
                        </div> 

CSS

.card-cover {
    width:100%;
    height: 100%;
    background: none repeat scroll 0% 0% rgba(255, 91, 36, 0.9);
    color: #FFF;
    display: block;
    position: absolute;
    opacity: 0;
    z-index:200;
    overflow: hidden;
    -webkit-transform:translate3d(0, 400px, 0);
    transform:translate3d(0, 400px, 0);
    -webkit-backface-visibility:hidden;
     backface-visibility: hidden;
     -webkit-transition-property:opacity, transform;
    transition-property:opacity, transform;
    -webkit-transition-duration:0.2s;
    transition-duration:0.2s;
    -webkit-transition-timing-function:cubic-bezier(0.165, 0.84, 0.44, 1);
    transition-timing-function:cubic-bezier(0.165, 0.84, 0.44, 1);   
    -webkit-transition-delay: 0s;
    transition-delay: 0s;
}


 .card-cover.card--active {
    opacity: 1;
    -webkit-transform:translate3d(0, 0, 0);
    transform:translate3d(0, 0px, 0);   
}

JS下面:

var cardContainer = document.querySelector('.card-cover'),
                cardTargets = Array.prototype.slice.call( document.querySelectorAll( '#card-reveal' ) ),
                eventType =  mobilecheck() ? 'touchstart' : 'click',
                cardClose = document.getElementById('card-close'),
                resetMenu = function() {
                    classie.remove( cardContainer, 'card--active' );
                },
                resetMenuClick = function( ) {
                    cardCloseaddEventListener(globalMenuEventType, function() {
                        resetMenu();
                        document.removeEventListener(eventType, resetMenuClick);
                    }, false);      
                };

            cardTargets.forEach(function (element, index) {


                if( element.target ) {
                    element.addEventListener(eventType, function( event ) {
                        event.preventDefault();
                        event.stopPropagation();

                        classie.add(cardContainer, 'card--active');

                        document.addEventListener(eventType, resetMenuClick);
                    } ,false);
                }

            });

1 个答案:

答案 0 :(得分:2)

我可以通过两种简单的方式来做这样的事情。

首先,如果你不能为每张卡指定ID(听起来你不能),你将不得不按类名去。就像评论中提到的那样,你真的不想对多个元素使用相同的ID。

部分原因是,正如您从下面的示例中可以看到的那样,.getElementById()方法只是为了返回一个元素,其他方法如.getElementsByClassName()将返回一个元素数组

我们要解决的问题是,您要显示/隐藏的子内容必须以某种方式附加到您单击的元素上。由于我们没有使用ID,并且你不能真正依赖类名在元素之间是唯一的,所以我将带有信息的div放在容器中,并使用切换它的元素。

在容器div中,内容是两个div。一个是始终可见的主要内容,另一个是仅在单击主要内容时变为可见的子内容(再次单击时变为不可见)。

这种方法的好处在于,由于无需担心ID,您可以复制/粘贴卡片,并且每个卡片都会显示相同的行为。

var maincontent = document.getElementsByClassName("main-content");
// Note: getElemenstByClassName will return an array of elements (even if there's only one).

for (var i = 0; i < maincontent.length; i++) {
  //For each element in the maincontent array, add an onclick event.
  maincontent[i].onclick = function(event) {

    //What this does is gets the first item, from an array of elements that have the class 'sub-content', from the parent node of the element that was clicked:
    var info = event.target.parentNode.getElementsByClassName("sub-content")[0];

    if (info.className.indexOf("show") > -1) { // If the 'sub-content' also contains the class 'show', remove the class.
      info.className = info.className.replace(/(?:^|\s)show(?!\S)/g, '');
    } else { // Otherwise add the class.
      info.className = info.className + " show";
    }
  }
}
.container {
  border: 1px solid black;
  width: 200px;
  margin: 5px;
}
.main-content {
  margin: 5px;
  cursor: pointer;
}
.sub-content {
  display: none;
  margin: 5px;
}
.show {
  /* The class to toggle */
  display: block;
  background: #ccc;
}
<div class="container">
  <div class="main-content">Here is the main content that's always visible.</div>
  <div class="sub-content">Here is the sub content that's only visible when the main content is clicked.</div>
</div>
<div class="container">
  <div class="main-content">Here is the main content that's always visible.</div>
  <div class="sub-content">Here is the sub content that's only visible when the main content is clicked.</div>
</div>
<div class="container">
  <div class="main-content">Here is the main content that's always visible.</div>
  <div class="sub-content">Here is the sub content that's only visible when the main content is clicked.</div>
</div>

第二种方法是对要显示/隐藏的内容使用一个div,单击一个元素将切换其可见性和内容。

我将使用前面的示例作为基础,但理想情况下,您可以使用某种MVVM框架(如react,knockout或angular)来帮助您填写内容。为了这个例子,我将使用子内容div中的文本。

var info = document.getElementById("Info");
var maincontent = document.getElementsByClassName("main-content");

for (var i = 0; i < maincontent.length; i++) { //getElemenstByClassName will return an array of elements (even if there's only one).
  maincontent[i].onclick = function(event) { //For each element in the maincontent array, add an onclick event. 

    //This does the same as before, but I'm getting the text to insert into the info card.
    var text = event.target.parentNode.getElementsByClassName("sub-content")[0].innerHTML;
    info.innerHTML = text; // Set the text of the info card.

    info.style.display = "block"; //Make the info card visible.
  }
}

info.onclick = function(event) {
  info.style.display = "none"; // If the info card is ever clicked, hide it.
}
.container {
  border: 1px solid black;
  width: 200px;
  margin: 5px;
  padding: 5px;
}
.main-content {
  margin: 5px;
  cursor: pointer;
}
.sub-content {
  display: none;
  margin: 5px;
}
#Info {
  cursor: pointer;
  display: none;
}
<div id="Info" class="container">Here is some test information.</div>
<div class="container">
  <div class="main-content">Link 1.</div>
  <div class="sub-content">You clicked link 1.</div>
</div>
<div class="container">
  <div class="main-content">Link 2.</div>
  <div class="sub-content">You clicked link 2.</div>
</div>
<div class="container">
  <div class="main-content">Link 3.</div>
  <div class="sub-content">You clicked link 3.</div>
</div>