【问题标题】:Javascript hide/show with many elements带有许多元素的 Javascript 隐藏/显示
【发布时间】:2017-09-14 14:47:58
【问题描述】:

在我的 HTML 中,我有问题和解决方案。我想用不同的按钮隐藏和显示每个问题的解决方案。

这是我的问题:我正在为每个解决方案按钮编写一个新函数。例如,如果我有 100 个问题,那么我需要编写 100 个不同的 Javascript 函数。

有没有更好的方法来做到这一点。我可以为每个解决方案按钮只写一个函数吗?

非常感谢您。

这是我的html:

<li>Question 1. What is x?</li>
<button class="btn btn-outline-success" 
onclick="myFunction()">Solution</button>
<div id="Solution">
<div class="highlight">
<pre>
X is apple
</pre>

<li>Question 2. What is y?</li>
<button class="btn btn-outline-success" 
onclick="myFunction1()">Solution</button>
<div id="Solution1">
<div class="highlight">
<pre>
Y is orange
</pre>

这是我的 Javascript:

document.getElementById( 'Solution' ).style.display = 'none';

function myFunction() {
    var x = document.getElementById('Solution');
    if (x.style.display === 'none') {
        x.style.display = 'block';
    } else {
        x.style.display = 'none';
    }
}

document.getElementById( 'Solution1' ).style.display = 'none';

function myFunction1() {
    var x = document.getElementById('Solution1');
    if (x.style.display === 'none') {
        x.style.display = 'block';
    } else {
        x.style.display = 'none';
    }
}

注意:我看到很多关于隐藏和显示的问题,但我无法解决我的问题。如果这是一个重复的问题,请警告我,我可以删除。

【问题讨论】:

  • 这是“vanilla JavaScript”中的一个练习吗? e.您是否明确要避免使用 jquery?如果是这样,它可以完成,否则,使用 jquery 的解决方案几乎是微不足道的。
  • 这里没有理由提倡 jQuery。它与问题或解决方案完全无关。
  • 我同意,如果 OP 想要解决一个难题,那么没有 jquery 的答案是正确的。但是,如果他想在真实的单词上下文中实现某些目标,那么对 jquery 的提示可能会有所帮助。我不会强迫任何人。但是$('.Solution').hide() $('button').on('click',function(){$(this).next().show()}) 绝对比这里的所有其他解决方案都要短,请参阅下面的工作演示。
  • 再次您好,非常感谢您的建议。我想分享我对这个话题的看法。我是一个初学者,正在尝试制作一些基本的页面来练习。我猜这个平台上还有其他一些初学者。所以对我们来说有时候前辈的一些回答看起来很复杂。我知道这里不是一个教育平台,但我们需要更多解释性答案,就像 @Scott Marcus 在这个问题中所做的那样。
  • 因此,例如对于这个问题,我的主要问题是,我们的一些资深朋友说我可以使用 jquary(顺便说一句,我真的很感谢)并且他们编写了代码,但老实说我什至不知道在哪里编写该代码。因此,对于像我这样的初学者,如果您详细解释每种解决方案的优势是什么,或者我们如何练习它会非常有用,或者如果可能的话,至少有一位资深人士像@Scott Marcus 那样做,对我们来说非常有用.再次非常感谢您。

标签: javascript html show-hide


【解决方案1】:

您可以通过传递一个参数来重用单个函数,该参数标识应该显示/隐藏文档中的哪个元素:

document.getElementById( 'Solution' ).style.display = 'none';

// The function now expects to be passed the ID of the element
function myFunction(elementID) {
    var x = document.getElementById(elementID);
    if (x.style.display === 'none') {
        x.style.display = 'block';
    } else {
        x.style.display = 'none';
    }
}

现在,您可以重复调用该函数,每次只传递不同的元素id

 <li>Question 1. What is x?</li>
 <button class="btn btn-outline-success" onclick="myFunction('Solution')">Solution</button>
 <div id="Solution">
   <div class="highlight">
     <pre>X is apple</pre>
   </div>
 </div>

<li>Question 2. What is y?</li>
<button class="btn btn-outline-success" onclick="myFunction('Solution1')">Solution</button>
<div id="Solution1">
  <div class="highlight">
    <pre>Y is orange</pre>
  </div>
</div>

现在,话虽如此,您应该尽可能避免使用内联 HTML 事件属性(onclickonmouseover 等)。有many reasons为什么。此外,您可以通过切换使用预先存在的 CSS 类来简化设置,而不是重复设置内联样式。此外,您的 HTML 语法无效。

这就是您的代码经过整理、有效且现代的版本的样子。您所要做的就是复制问题的 HTML 结构,现有的 JavaScript 将立即为它工作。每个问题甚至不再需要名称(“Solution1”、“Solution2”等)。

// Get all the buttons in a node list
var theButtons = document.querySelectorAll(".btn-outline-success");

// Turn node list into a JS Array
var buttonArray = Array.from(theButtons);

// Loop over the buttons and give each its click event handler
buttonArray.forEach(function(button){
  button.addEventListener("click", function(){ 
    // We will pass a reference to the current button to the function
    myFunction(this); 
  });
});

// The function now expects to be passed a reference to the button that was clicked
function myFunction(element) { 
  // Get a reference to div that follows the button and then search that div
  // for the first pre element inside of it:
  var answer = element.nextElementSibling.querySelector("pre");
  
  // All we need to do is toggle the visibility of that pre element
  answer.classList.toggle("hidden");
}
/* This class will simply be added or removed to show/hide elements */
/* All answers have this applied by default*/
.hidden {
  display:none;
}

li { margin-bottom:10px; }
<!--
    NOTES:
           1. The onclick has been removed (it is now handled in JavaScript) 
           2. The quesiton names ("Solution", "Solution1", etc.) are no longer needed
           3. Your HTML structure was invalid. Here is the proper way to make bulleted lists.
-->

<ul>
  <li>Question 1. What is x?
      <button class="btn btn-outline-success">Solution</button>
      <div>
        <div class="highlight">
          <pre class="hidden">X is apple</pre>
        </div>
      </div>
  </li>
    
  <li>Question 2. What is y?
      <button class="btn btn-outline-success">Solution</button>
      <div>
        <div class="highlight">
          <pre class="hidden">Y is orange</pre>
        </div>
      </div>
  </li>

  <li>Question 3. What is z?
      <button class="btn btn-outline-success">Solution</button>
      <div>
        <div class="highlight">
          <pre class="hidden">z is mango</pre>
        </div>
      </div>
  </li>
</ul>

【讨论】:

  • 一个解释清楚的答案 ;-), +1
  • 非常感谢.. 这在我的代码中运行良好,将为我节省大量时间。我将此答案标记为已接受。所以再次非常感谢你。
【解决方案2】:

如果我明白你想要什么,你可以使用参数。

HTML

<li>Question 1. What is x?</li>
<button class="btn btn-outline-success" onclick="myFunction(1)">Solution</button>
<div id="Solution"></div>
<div class="highlight"></div>
<pre>
    X is apple
</pre>

JS

function myFunction(var solNumber = 1) {
    var x = document.getElementById('Solution'+solNumber);
    if (x.style.display === 'none') {
        x.style.display = 'block';
    } else {
        x.style.display = 'none';
    }
}

如果所有问题同时出现,您也可以使用for 循环来显示所有问题。

【讨论】:

    【解决方案3】:

    你可以这样做:

    • 将问题放在div 中,并用“问题”类括起来,类似的解决方案用“解决方案”类括起来。
    • 还定义了一个单独的显示函数,参数为单击的按钮元素,在按钮的单击时使用this作为参数传递。
    • 该函数只是找到具有类“解决方案”的同级 div,并通过设置 display: block 使其可见

    function show_solution(buttonElement) {
      questionDiv = buttonElement.parentNode;
      
      if (questionDiv.querySelector('.solution').style.display == 'none') {
        questionDiv.querySelector('.solution').style.display = 'block';
      } else {
        questionDiv.querySelector('.solution').style.display = 'none';
      }
      
    }
    .solution {
      display: none;
    }
    
    .highlight {
      background: #FF0;
    }
    <div class="question">
      &bull; Question 1. What is x?
      <button class="btn btn-outline-success" onclick="show_solution(this)">Solution</button>
      <div class="solution">
        <div class="highlight">
          <pre> X is apple </pre>
        </div>
      </div>
    </div>
    
    <div class="question">
      &bull; Question 2. What is y?
      <button class="btn btn-outline-success" onclick="show_solution(this)">Solution</button>
      <div class="solution">
        <div class="highlight">
          <pre> Y is orange </pre>
        </div>
      </div>
    </div>

    【讨论】:

      【解决方案4】:

      好吧,如果 jquery 被允许,解决方案可能如下所示:

      $('.Solution').hide()
      $('button').on('click',function(){$(this).next().show()})
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <li>Question 1. What is x?</li>
      <button class="btn btn-outline-success">Solution</button>
      <div class="Solution">
      <div class="highlight">
      <pre>
      X is apple
      </pre>
      </div></div>
      <li>Question 2. What is y?</li>
      <button class="btn btn-outline-success">Solution</button>
      <div class="Solution">
      <div class="highlight">
      <pre>
      Y is orange
      </pre>
      </div></div>

      注意:这也将简化您的 html...但是,当然,选择权在您手中!

      【讨论】:

      • 您好,谢谢您的回答,我真的对jquary一无所知。在您回答后,我将开始学习基础知识并练习您的解决方案。再次非常感谢。
      猜你喜欢
      • 2015-01-02
      • 1970-01-01
      • 1970-01-01
      • 2016-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-07
      • 1970-01-01
      相关资源
      最近更新 更多