简体   繁体   English

在显示和隐藏文本之间切换(javascript)

[英]Toggle between showing and hiding text (javascript)

I have an html-document with 4 <p> -tags in the body. 我体内有4个<p> -tags的html文档。 I have a separate js-file and want to use javascript to: 我有一个单独的js文件,想使用javascript来:

  • Create and put links in the 1st and 3rd paragraphs. 在第一段和第三段中创建并放置链接。

  • Create a function that toggles between showing and hiding the text in the paragraph below each link when the corresponding link is activated. 创建一个函数,当激活相应的链接时,该函数在显示和隐藏每个链接下方的段落中的文本之间切换。 The paragraphs should be hidden from the start. 段落应从一开始就隐藏起来。

I can't get the toggle function to work. 我无法使用切换功能。 The page still displays all paragraphs from the start and when I click the links the page just flickers for a millisecond. 该页面仍然从一开始就显示所有段落,当我单击链接时,页面仅闪烁一毫秒。

Below is my code. 下面是我的代码。 I'm a beginner and I know it is bad code but I just want it to be a working script. 我是一个初学者,我知道这是错误的代码,但我只是希望它成为一个有效的脚本。 I can't figure out why it doesn't work so would greatly appreciate some help from someone who is good at this. 我无法弄清楚为什么它不起作用,因此非常感谢那些擅长此事的人的帮助。

<!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";
        }
    } 
<!doctype html>
<html>
   <head>
   <meta charset="utf-8"/>

This is not XML, there are no short tags. 这不是XML,没有短标签。 Use: 采用:

   <meta charset="utf-8">

The title element must have content: title元素必须具有以下内容:

   <title>Show Hide</title>

In the script: 在脚本中:

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

Function names starting with a capital letter are, by convention, reserved for constructors. 按照约定,以大写字母开头的函数名称保留给构造函数使用。 Also, a function's name should hint at what it does, so: 此外,函数的名称应提示其功能,因此:

function addLinks() {

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

Instead of using setAttribute , it's more convenient to set properties directly: 与使用setAttribute相比 ,直接设置属性更方便:

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

Presumably shoeHide.html is the name of the HTML file your code is in. So when the link is clicked, the page reloads. 大概shoeHide.html是代码所在的HTML文件的名称。因此,单击链接后,页面将重新加载。 Rather than using a link, which looks to the user like it should go to another page, you should use a button, which indicates that something will happen but likely not take the user anywhere. 您应该使用一个按钮,而不是使用一个链接,该链接看起来像用户应该转到另一个页面,而是应该使用一个按钮,该按钮表示将发生某些事情,但可能不会将该用户带到任何地方。 It also doesn't require a href attribute. 它还不需要href属性。

As Lior said, clicking on the link will reload the page, so whatever modifications the script might do, they are irrelevant since the original page is then reloaded. 正如Lior所说,单击链接将重新加载页面,因此脚本可能执行的任何修改都无关紧要,因为然后重新加载了原始页面。

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

The BR element is empty, it has no content and no closing tag, so: BR元素为空,没有内容且没有结束标记,因此:

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

But since I've suggested using a button instead, consider: 但是由于建议使用按钮代替,请考虑:

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

and rename the function addButtons. 并重命名功能addButtons。 Then there's: 然后是:

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

Which is fine. 没关系 Since you want an identical button on another P, you can clone the one you just made: 由于要在另一个P上使用相同的按钮,因此可以克隆刚创建的按钮:

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

The buttons don't need an ID. 这些按钮不需要ID。 But you might consider giving the paragraphs that need buttons a class so you can access them by className like the buttons below. 但是您可以考虑为需要按钮的段落提供一个类,以便您可以像下面的按钮一样通过className访问它们。

    }
    Links();

Now for the toggling code. 现在开始切换代码。 You can get the buttons using their class: 您可以使用它们的类来获取按钮:

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

Now add the same listener to each: 现在,将相同的侦听器添加到每个侦听器:

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

Now for the attachment. 现在为附件。

    a.onclick = function toggle() {

There is no need to give function expressions a name. 无需为函数表达式命名。 They are only there so the function can be referenced from inside the function (they're also handy for debugging). 它们仅在此处,因此可以从函数内部进行引用(它们对于调试也很方便)。 Some versions of IE create named function expressions as global functions, so best not to give them names unless you have a really good reason to do so. 某些版本的IE将命名函数表达式创建为全局函数,因此,除非有充分的理由,否则最好不要给它们命名。

    buttons[i].onclick = function() {

Now comes the tricky part, how to reference the related paragraph to hide or show? 现在来了棘手的部分,如何引用相关段落进行隐藏或显示? The paragraph of interest is the one that is the next sibling of the paragraph that the button is in, which is a bit tricky. 感兴趣的段落是该按钮所在的段落的下一个同级项,这有点棘手。 You should carefully consider the DOM layout before doing this as any change to the structure will break your function. 在执行此操作之前,您应该仔细考虑DOM布局,因为对结构的任何更改都会破坏您的功能。 So split out a function to get the next paragraph sibling that might look like: 因此,请拆分一个函数以获取下一段的同级内容,如下所示:

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;
}

So now in the main function... 所以现在在主要功能中...

    displayPara = getNextParaSibling(this.parentNode);

And because you can't be certain that worked, deal with it missing: 而且由于无法确定是否可行,因此应对它的缺失:

    if (!displayPara) return;

Now if the element has been hidden using CSS, that will not be reflected in the element's own style.display property. 现在,如果该元素已使用CSS隐藏,则不会反映在该元素自己的style.display属性中。 So you can use computedStyle , but then you don't know how to set it. 因此,您可以使用computeStyle ,但是您不知道如何设置它。 So things are messy. 所以事情很混乱。 In that case, it's much better to hide and show the element by using a class, then you just add or remove the class. 在这种情况下,最好使用类来隐藏和显示元素,然后只需添加或删除该类即可。 You should have some library functions to help with that, but for now you can assume that the elements only have one class. 您应该具有一些库函数来帮助解决此问题,但是现在您可以假定元素只有一个类。 So assume there is a class like: 因此,假设有一个类似的类:

.hideMe {display: none;}

and you add that to the paragraphs to be hidden like: 然后将其添加到要隐藏的段落中,如下所示:

<p class="hideMe" ...>

then you can do: 那么您可以执行以下操作:

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

and you're done. 到此为止。 In summary, the HTML can be: 总之,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>

and the script: 和脚本:

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';
    }
  }
}

though all of it should be run from inside an immediately invoked function expression (aka IIFE). 尽管所有这些都应从立即调用的函数表达式(即IIFE)内部运行。

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

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