简体   繁体   English

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

[英]Toggling Between a CSS class with pure javascript on 'n' elements

Working on creating functionality where when the user clicks on one of the products (each of the elements have the same assigned ID card-reveal ) it adds a CSS class to the container specifically clicked (active state) to show information for that specific item and then finally, when the user clicks the cancel button the CSS class is removed (activate state gone). 致力于创建功能,当用户单击其中一个产品(每个元素具有相同的分配的ID card-reveal )时,它将向特定单击的容器(活动状态)添加CSS class以显示该特定商品的信息,最后,当用户单击“取消”按钮时,CSS类将被删除(激活状态消失了)。

Unfortunately I have run to a few hiccups where when I click on the 1st element it adds the class to that element but the other elements I click do not add the class, as well the close button does not function at all. 不幸的是,我遇到了一些麻烦,当我单击第一个元素时,它将类添加到该元素,但是我单击的其他元素却不添加类,并且关闭按钮根本不起作用。 I would like to finish the solution in Pure Javascript . 我想用Pure Javascript完成解决方案。 Also if you see a few classie() methods, I am using Classie.js to help with CSS class toggling. 另外,如果您看到一些classie()方法,那么我正在使用Classie.js来帮助进行CSS类切换。

Any help will be appreciated! 任何帮助将不胜感激! Thank You! 谢谢!

Html 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 的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 below: 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);
                }

            });

There are two simple ways I can think of doing something like this. 我可以想到两种简单的方法来做这样的事情。

First, if you can't designate ID's for each card (which it sounds like you can't), you're going to have to go by class names. 首先,如果您不能为每张卡都指定ID(这听起来好像不行),则必须按类名来命名。 Like it was mentioned in the comments, you really don't want to use the same ID for multiple elements. 就像注释中提到的一样,您真的不想对多个元素使用相同的ID。

Part of the reason for this is, as you can see from my examples below, that the .getElementById() method is only meant to return one element, where the other methods like .getElementsByClassName() will return an array of elements. 造成这种情况的部分原因是,如下面的示例所示,.getElementById()方法仅用于返回一个元素,而其他方法(如.getElementsByClassName())将返回一个元素数组。

The problem we're trying to solve is that the sub-content you want to display/hide has to be attached to the element you click somehow. 我们正在尝试解决的问题是,您要显示/隐藏的子内容必须附加到您以某种方式单击的元素上。 Since we're not using ID's and you can't really rely on class names to be unique between elements, I'm putting the div with the information inside a container with the element that toggles it. 由于我们没有使用ID,因此您不能真正依靠类名在元素之间唯一,因此,我将带有信息的div放入具有可切换元素的容器内。

Inside a container div, are two divs for content. 在容器div内,有两个div用于内容。 One is the main content that's always visible, the other is the sub-content that only becomes visible if the main content is clicked (and becomes invisible when clicked again). 一个是始终可见的主要内容,另一个是仅在单击主内容后才可见的子内容(在再次单击时不可见)。

The benefit of this method is that since there are no ID's to worry about, you can copy/paste the cards and they'll each show the same behaviour. 这种方法的好处是,由于无需担心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> 

The second method, would be to use one div for the content that you want to show/hide, and clicking on an element will toggle both its visibility and it's content. 第二种方法是对要显示/隐藏的内容使用一个div,单击元素将同时切换其可见性和内容。

I'll use the previous example as a base, but ideally you would have some kind of MVVM framework like react, knockout, or angular to help you with filling in the content. 我将以前面的示例为基础,但是理想情况下,您将具有某种MVVM框架,例如react,knockout或angular来帮助您填充内容。 For the sake of this example, I'm just going to use the text from the div of sub-content. 为了这个示例,我将使用子内容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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM