哪种JS技术:选择目标元素的父级?

时间:2018-04-03 16:47:09

标签: javascript html css

我不确定问题中的条款是否正确;但是我有一些HTML(不幸的是,我坚持使用它的结构):

<div>
  <ul>
    <li><a href="#turn-left">Turn left</a></li>
    <li><a href="#turn-right">Turn right</a></li>
  </ul>
</div>

<div class="possible-outcome">
  <span id="turn-left"></span>
  <p>You step into a puddle.</p>
</div>

<div class="possible-outcome">
  <span id="turn-right"></span>
  <p>You fall into a ditch.</p>
</div>

我希望所有possible-outcome div被隐藏起来:

div.non-actual-outcome {display: none;}

一旦用户选择其中一个超链接,

就会应用于这些超链接,但div包含span且目标为id的{​​{1}}除外,该actual-outcome应具有div.actual-outcome {display: block;} 由JS应用于它的类,因此只显示它:

span

当用户点击possible-outcome div中的div的其他链接时, {/ em> div.non-actual-outcome { display: none; } div.actual-outcome { display: block; }将成为唯一可见的链接(直到用户点击不属于其中一个跨度的链接)。

以下是一些示例代码:

<div>
  <ul>
    <li><a href="#turn-left">Turn left</a></li>
    <li><a href="#turn-right">Turn right</a></li>
  </ul>
</div>

<div class="possible-outcome">
  <span id="turn-left"></span>
  <p>You step into a puddle.</p>
</div>

<div class="possible-outcome">
  <span id="turn-right"></span>
  <p>You fall into a ditch.</p>
</div>
 @Styles.Render("~/Content/bootstrap.min.css")

<nav class="navbar navbar-inverse">
        <div class="container-fluid">
            <div class="navbar-header">
                <a class="navbar-brand" @Html.ActionLink("Our Church", "Index", "Home")</a>
            </div>
            <ul class="nav navbar-nav">
                <li>@Html.ActionLink("Home", "Index", "Home")</li>
                <li>@Html.ActionLink("About", "About", "Home")</li>

                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
                    <ul class="dropdown-menu">
                        <li><a href="#">MTB Link 1</a></li>
                        <li><a href="#">MTB Link 2</a></li>
                        <li><a href="#">MTB Link 3</a></li>
                        <li class="divider"></li>
                        <li class="dropdown-header">Nav header</li>
                        <li><a href="#">MTB Link 4</a></li>
                        <li><a href="#">MTB Link 5</a></li>
                    </ul>
                </li>

            </ul>
            <ul class="nav navbar-nav navbar-right">
                @Html.Partial("_LoginPartial")
            </ul>
        </div>
    </nav>
</header>

实现这一目标的最简单方法是什么(以及提出问题的正确术语)?

3 个答案:

答案 0 :(得分:1)

首先,为所有a元素添加一个公共类,以便区分它们,例如class="tab"

<a class="tab" href="#turn-left">Turn left</a>

其次,默认情况下隐藏所有div元素,方法是将display:none属性添加到CSS选择器.possible-outcome(所有div元素都有):

div.possible-outcome {
  display: none;
}

并仅使用actual-outcome隐藏/显示您想要的div。不需要使用两个类,只需要一个。如果div包含类actual-outcome,则会显示该类,如果没有,则会赢得(因为它具有类possible-outcome)。

第三,当点击.tab元素时,选择其目标span以及该span的父级并执行一些逻辑:如果span存在并且其父级当前未显示(没有类actual-outcome),然后隐藏实际显示的div(如果存在)并显示当前span的父级

注意:如果您希望默认显示div,只需将类actual-outcome添加到其中:

<div class="possible-outcome actual-outcome">

完整代码:

&#13;
&#13;
document.addEventListener("click", function(ev) {
  var target = ev.target;                                               // get the element that has been clicked
  if(target.classList.contains("tab")) {                                // if the clicked element is a .tab element
    var span = document.querySelector(target.getAttribute("href")),     // then select that .tab's span to show
        parent = span.parentElement;                                    // select the parent of that span (perhaps check if the span exists first to not get the "can't access property parentElement of null")
    if(span && !parent.classList.contains("actual-outcome")) {          // if the span exists and its parent is not currently shown (not having the class "actual-outcome")
      var visibleOutcome = document.querySelector(".actual-outcome");   // then select the current shown element (which we know will have the class "actuall-outcome")
      if(visibleOutcome) {                                              // if there is one
        visibleOutcome.classList.remove("actual-outcome");              // hide it by remove the class "actual-outcome" from its classList
      }
      parent.classList.add("actual-outcome");                           // and show the current span's parent by adding that same old class
    }
  }
});
&#13;
div.possible-outcome {
  display: none;
}

div.actual-outcome {
  display: block;
}
&#13;
<div>
  <ul>
    <li><a class="tab" href="#turn-left">Turn left</a></li>
    <li><a class="tab" href="#turn-right">Turn right</a></li>
  </ul>
</div>

<div class="possible-outcome">
  <span id="turn-left"></span>
  <p>You step into a puddle.</p>
</div>

<div class="possible-outcome">
  <span id="turn-right"></span>
  <p>You fall into a ditch.</p>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

仅仅为了完成,Divio Cloud interactive debugging checklist for deployments是我们对此问题的解决方案的实现。

它类似于我们的Sphinx文档中的choose your own adventure story,可帮助用户确定部署可能失败的原因。

它是基于Ibrahim Mahrir's answer

开发的

我们的一位真正的JS专家(即不是我)根据易卜拉欣的最终版本答案使用了我的工作概念验证。

JavaScript和CSS都嵌入在页面本身中。

HTML结构在很大程度上取决于Sphinx的输出,因此需要适应元素的排列。

答案 2 :(得分:0)

这是我能想到的最佳解决方案。这不会通过添加除提供的类之外的任何其他类来修改结构。

HTML:

div.non-actual-outcome {
  display: none;
}

div.actual-outcome {
  display: block;
}

CSS:

var outcomeDivs = document.getElementsByClassName('possible-outcome') // selects all divs and returns them as an array
var links = document.querySelectorAll('li') // selects all <li> and returns them as array


// This is turn left li, we will hide turn-right when clicking it.
links[0].addEventListener('click', function(){
  outcomeDivs[1].classList.add('non-actual-outcome'); // hides turn-right
  links[1].style.display = 'none'; // hides other link
});
// This is turn right li, we will hide turn-left when clicking it.
links[1].addEventListener('click', function(){
  outcomeDivs[0].classList.add('non-actual-outcome'); // hides turn-left
  links[0].style.display = 'none'; // hides other link
});

JS:

{{1}}

CodePen