【问题标题】:Toggle between showing and hiding text (javascript)在显示和隐藏文本之间切换 (javascript)
【发布时间】:2015-02-23 03:49:13
【问题描述】:

我有一个 html 文档,正文中有 4 个 <p>-tags。我有一个单独的 js 文件并想使用 javascript 来:

  • 在第 1 和第 3 段中创建和放置链接。

  • 创建一个在显示和隐藏文本之间切换的函数 每个链接下面的段落,当对应的链接是 活性。段落应该从一开始就隐藏起来。

我无法使用切换功能。该页面仍然显示从一开始的所有段落,当我单击链接时,页面只会闪烁一毫秒。

下面是我的代码。我是初学者,我知道这是不好的代码,但我只想让它成为一个工作脚本。我不知道为什么它不起作用,因此非常感谢擅长此操作的人的帮助。

<!doctype html>
<html>
   <head>
   <meta charset="utf-8"/>
   <title></title>

 </head>  
 <body>
 <p>When this link is activated..</p>
 <p id="displayPara">..I want this hidden paragraph to be revealed.</p>
 <p>And if the link below is clicked..</p>
 <p>..this paragraph should be revealed.</p>

 <script type="text/javascript" src="showHide.js"></script>
 </body>
</html>


         The JS-file:
//Creates the 2 links and puts them where I want them in the document body.
function Links() {                                          
        a = document.createElement("a");
        a.setAttribute("href", "showHide.html");
        a.setAttribute("id", "firstLink");                             
        a.innerHTML = "<br></br>Show paragraph";
        document.getElementsByTagName("p")[0].appendChild(a);

        a2 = document.createElement("a");
        a2.setAttribute("href", "showHide.html");
        a2.setAttribute("id", "secondLink");                        
        a2.innerHTML = "<br></br>Show paragraph";
        document.getElementsByTagName("p")[2].appendChild(a2);

    }
    Links();

    /*I want this function to toggle between showing and hiding the 2nd and 4th paragraphs when the links are clicked. 
    I tried with the first link first and it doesn't work.*/
    a.onclick = function toggle() {
         displayPara = document.getElementById("displayPara");
         firstLink = document.getElementById("firstLink");
        if(displayPara.style.display == "block") {
                displayPara.style.display = "none";
            firstLink.innerHTML = "Show paragraph"
        }
        else {
            displayPara.style.display = "block";
            firstLink.innerHTML = "Hide paragraph";
        }
    } 

【问题讨论】:

  • &lt;br&gt; 是一个空标签,&lt;/br&gt; 是一个被忽略的幻影。 title 元素不能为空。

标签: javascript onclick toggle show-hide


【解决方案1】:
<!doctype html>
<html>
   <head>
   <meta charset="utf-8"/>

这不是 XML,没有短标签。使用:

   <meta charset="utf-8">

title 元素必须有内容:

   <title>Show Hide</title>

在脚本中:

//Creates the 2 links and puts them where I want them in the document body.
function Links() {

按照惯例,以大写字母开头的函数名称是为构造函数保留的。此外,函数的名称应该暗示它的作用,所以:

function addLinks() {

        a = document.createElement("a");
        a.setAttribute("href", "showHide.html");
        a.setAttribute("id", "firstLink");                             

不用setAttribute,直接设置属性更方便:

    a.href = 'showHide.html';
    a.id = 'firstLink';                             

大概 shoeHide.html 是您的代码所在的 HTML 文件的名称。因此,当单击链接时,页面会重新加载。您应该使用一个按钮,而不是使用一个在用户看来应该转到另一个页面的链接,这表明某些事情将会发生,但可能不会将用户带到任何地方。它也不需要 href 属性。

正如 Lior 所说,单击链接将重新加载页面,因此无论脚本可能进行何种修改,它们都无关紧要,因为随后会重新加载原始页面。

        a.innerHTML = "<br></br>Show paragraph";

BR元素是空的,没有内容也没有结束标签,所以:

        a.innerHTML = "<br>Show paragraph";

但既然我建议改用按钮,请考虑:

    var a = document.createElement('input');
    a.type = 'button';
    a.className = 'openCloseButton';
    a.value = 'Show paragraph';

并将函数重命名为 addButtons。然后是:

       document.getElementsByTagName("p")[0].appendChild(a);

这很好。由于您想在另一个 P 上使用相同的按钮,您可以克隆您刚刚制作的按钮:

        document.getElementsByTagName("p")[2].appendChild(a.cloneNode());

按钮不需要 ID。但是你可以考虑给需要按钮的段落一个类,这样你就可以像下面的按钮一样通过 className 访问它们。

    }
    Links();

现在是切换代码。您可以使用他们的类来获取按钮:

var buttons = document.querySelectorAll('.openCloseButton');

现在为每个监听器添加相同的监听器:

for (var i=0, iLen=buttons.length; i<iLen; i++) {

现在是附件。

    a.onclick = function toggle() {

没有必要给函数表达式命名。它们只是在那里,因此可以从函数内部引用该函数(它们也便于调试)。某些版本的 IE 将命名函数表达式创建为全局函数,因此最好不要给它们命名,除非您有充分的理由这样做。

    buttons[i].onclick = function() {

现在到了棘手的部分,如何引用相关段落来隐藏或显示?感兴趣的段落是按钮所在段落的下一个兄弟,这有点棘手。在执行此操作之前,您应该仔细考虑 DOM 布局,因为对结构的任何更改都会破坏您的功能。所以拆分出一个函数来获取下一个段落兄弟,如下所示:

function getNextParaSibling(el) {
  var next;

  // Search siblings until a P is found
  while (el.nextSibling) {
    next = el.nextSibling;
    if (next.tagName && next.tagName.toLowerCase() == 'p') {
      return next;
    }
    el = next;
  }
  // If a next sibling P isn't found, return null
  return null;
}

所以现在在 main 函数中...

    displayPara = getNextParaSibling(this.parentNode);

因为你不能确定它是否有效,所以处理它缺失:

    if (!displayPara) return;

现在,如果元素已使用 CSS 隐藏,则不会反映在元素自己的 style.display 属性中。所以你可以使用computedStyle,但是你不知道如何设置它。所以事情一团糟。在这种情况下,最好使用类隐藏和显示元素,然后添加或删除类。你应该有一些库函数来帮助解决这个问题,但现在你可以假设元素只有一个类。所以假设有一个类:

.hideMe {display: none;}

然后将其添加到要隐藏的段落中,例如:

<p class="hideMe" ...>

那么你可以这样做:

    // If element is hidden
    if (displayPara.className == 'hideMe') {
      displayPara.className = '';
    } else {
      displayPara.className = 'hideMe';
    }

你就完成了。总之,HTML 可以是:

<p>When this link is activated..</p>
<p class="hideMe">..I want this hidden paragraph to be revealed.</p>
<p>And if the link below is clicked..</p>
<p class="hideMe">..this paragraph should be revealed.</p>

和脚本:

function addButtons() {
  var a = document.createElement('input');
  a.type = 'button';
  a.className = 'openCloseButton';
  a.value = 'Show paragraph';
  document.getElementsByTagName("p")[0].appendChild(a);
  document.getElementsByTagName("p")[2].appendChild(a.cloneNode());
}
addButtons();

function getNextParaSibling(el) {
  var next;

  // Search siblings until a P is found
  while (el.nextSibling) {
    next = el.nextSibling;
    if (next.tagName && next.tagName.toLowerCase() == 'p') {
      return next;
    }
    el = next;
  }
  // If a next sibling P isn't found, return null
  return null;
}

var buttons = document.querySelectorAll('.openCloseButton');
for (var i=0, iLen=buttons.length; i<iLen; i++) {
  buttons[i].onclick = function() {
  displayPara = getNextParaSibling(this.parentNode);

  if (!displayPara) return;

    // If element is hidden
    if (displayPara.className == 'hideMe') {
      displayPara.className = '';

    } else {
      displayPara.className = 'hideMe';
    }
  }
}

尽管所有这些都应该从立即调用的函数表达式(又名 IIFE)中运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-26
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    相关资源
    最近更新 更多