使用javascript显示或隐藏多个表单

7xllpg7q  于 2023-03-06  发布在  Java
关注(0)|答案(5)|浏览(155)

我正在尝试创建一段javascript代码,它只会隐藏和显示页面上与其id属性相对应的每个表单。所以想象一下,页面上有4个按钮可见,表单元素默认为隐藏,一旦点击了一个与表单id相匹配的按钮,它只会切换该表单。下面是我尝试过的代码

function _(x) {
  return document.getElementById(x);
}

const catBtn = _("catBtn");
const blogBtn = _("blogBtn");
const videoBtn = _("VideoBtn");
const prodBtn = _("prodBtn");

const catForm = _("catForm");
const blogForm = _("blogForm");
const videoForm = _("VideoForm");
const prodForm = _("prodForm");

document.addEventListener('click', function(e) {
  if (e.target.id === catBtn) {
    // catForm.classList.toggle("showHide");
    console.log("you clicked the cat btn");
  } else if (e.target.id === blogBtn) {
    // blogForm.classList.toggle("showHide");
    console.log("you clicked the blog btn");
  } else if (e.target.id === videoBtn) {
    // videoForm.classList.toggle("showHide");
    console.log("you clicked the video btn");
  } else if (e.target.id === prodForm) {
    // prodForm.classList.toggle("showHide");
    console.log("you clicked the product btn");
  }
})
<div class="new__btn">
  <button id="catBtn">New Category</button>
</div>
<div class="new__btn">
  <button id="blogBtn">New Blog</button>
</div>
<div class="new__btn">
  <button id="videoBtn">New Video</button>
</div>
<div class="new__btn">
  <button id="prodBtn">New Product</button>
</div>

<div id="catForm">
  Hide or show this div for the categories
  <div class="panel">
    <div class="panel__head">Panel Head</div>
    <div class="panel__body">Panel Body</div>
    <div class="panel__footer">Panel Footer</div>
  </div>
</div>

<div id="blogForm">
  Hide or show this div for the blogs
  <div class="panel">
    <div class="panel__head">Panel Head</div>
    <div class="panel__body">Panel Body</div>
    <div class="panel__footer">Panel Footer</div>
  </div>
</div>

<div>
  <div id="videoForm">
    Hide or show this div for the videos
    <div class="panel">
      <div class="panel__head">Panel Head</div>
      <div class="panel__body">Panel Body</div>
      <div class="panel__footer">Panel Footer</div>
    </div>
  </div>

  <div id="prodForm">
    Hide or show this div for the products
    <div class="panel">
      <div class="panel__head">Panel Head</div>
      <div class="panel__body">Panel Body</div>
      <div class="panel__footer">Panel Footer</div>
    </div>
  </div>
8ftvxx2r

8ftvxx2r1#

如果你用containing元素 Package 你的按钮和表单,并且给按钮和表单都添加数据属性,你可以使用event delegation,这样你就可以给按钮容器附加一个监听器,当它的子元素在DOM中"冒泡"时,它会捕捉事件。
然后,处理程序可以检查被单击的是按钮,提取其数据id(它将对应于表单上的相同数据id),并在选择器中使用该id来定位该表单。
然后,只需使用CSS切换"show"类即可。
从示例中可以看到,也可以使用相同的方法将活动类切换到单击的按钮。

// Cache the forms and buttons containers
const forms = document.querySelector('.forms');
const buttons = document.querySelector('.buttons');

// Add one listener to the buttons container
buttons.addEventListener('click', handleButton);

// Utility helper to remove classes from a set of elements
function removeClasses(context, selector, classname) {
  context.querySelectorAll(selector).forEach(el => {
    el.classList.remove(classname);
  });
}

function handleButton(e) {
  
  // If the clicked element that the listener catches
  // is a button
  if (e.target.matches('button')) {
    
    // Destructure its id from its dataset
    const { id } = e.target.dataset;

    // Create a selector using a template string which
    // will find a form with a matching data-id attribute
    const selector = `.form[data-id="${id}"]`;

    // Find the corresponding form in the forms container
    const form = forms.querySelector(selector);

    // If the button is active, remove the active
    // class, and remove the show class from the form
    if (e.target.classList.contains('active')) {
      e.target.classList.remove('active');
      form.classList.remove('show');

    // Otherwise remove all the active classes from the buttons,
    // and all the show classes from the forms, and then add the
    // active class to the button, and the show class to the
    // selected form.
    } else {
      removeClasses(buttons, 'button', 'active');
      removeClasses(forms, '.form', 'show');
      e.target.classList.add('active');
      form.classList.add('show');
    }

  }

}
.forms { margin-top: 1em; }
.form { display: none; border: 1px solid lightgray; padding: 0.5em; }
.form { margin-top: 0.5em; }
.show { display: block; }
button:hover { cursor: pointer; }
button:hover:not(.active) { background-color: #fffff0; }
.active { background-color: #ffff00; }
<div class="buttons">
  <button type="button" data-id="cat">New Category</button>
  <button type="button" data-id="blog">New Blog</button>
  <button type="button" data-id="video">New Video</button>
  <button type="button" data-id="prod">New Product</button>
</div>

<section class="forms">
  <div class="form" data-id="cat">
    Hide or show this div for the categories
    <div class="panel">
      <div class="panel__head">Panel Head</div>
      <div class="panel__body">Panel Body</div>
      <div class="panel__footer">Panel Footer</div>
    </div>
  </div>
  <div class="form" data-id="blog">
    Hide or show this div for the blogs
    <div class="panel">
      <div class="panel__head">Panel Head</div>
      <div class="panel__body">Panel Body</div>
      <div class="panel__footer">Panel Footer</div>
    </div>
  </div>
  <div>
    <div class="form" data-id="video">
      Hide or show this div for the videos
      <div class="panel">
        <div class="panel__head">Panel Head</div>
        <div class="panel__body">Panel Body</div>
        <div class="panel__footer">Panel Footer</div>
      </div>
    </div>
  </div>
  <div class="form" data-id="prod">
    Hide or show this div for the products
    <div class="panel">
      <div class="panel__head">Panel Head</div>
      <div class="panel__body">Panel Body</div>
      <div class="panel__footer">Panel Footer</div>
    </div>
  </div>
</section>

附加文件

sqxo8psd

sqxo8psd2#

对于这个问题,我会采取一种完全不同的方法。我建议使用数据属性标记按钮和表单,然后根据单击的按钮动态显示和隐藏表单。这将允许您轻松添加新表单。
下面是我的方法的一个实现,它使用了querySelectory和数据属性。如果你有任何问题,请随时提问,我会尽我所能为你详细阐述我的解决方案。

(function(){

    // find all the buttons with a data-target-form attribute 
    const buttons = document.body.querySelectorAll('button[data-target-form]')
    
  // loop over each button
  buttons.forEach((btn) => {
    // wire up the event handler for each button
    btn.onclick = (e) => {
        // get the target form name
      let formName = e.target.dataset.targetForm;
      // hide forms that aren't the desired one
      document.body.querySelectorAll(`div[data-form-id]:not([data-form-id="${formName}"])`).forEach((form) => form.style.display = 'none');
      // show the desired form
      document.body.querySelector(`div[data-form-id="${formName}"]`).style.display = 'block';
    }
  });
  
})()
/* Hide all forms at first until a button is clicked */
div[data-form-id]{
  display: none;
}

/* just putting all the buttons in a row */

.new__btn {
  display: inline-block;
}
<div class="new__btn">
  <button id="catBtn" data-target-form="categories">New Category</button>
</div>
<div class="new__btn">
  <button id="blogBtn" data-target-form="blogs">New Blog</button>
</div>
<div class="new__btn">
  <button id="videoBtn" data-target-form="videos">New Video</button>
</div>
<div class="new__btn">
  <button id="prodBtn" data-target-form="products">New Product</button>
</div>

<div id="catForm" data-form-id="categories">
  Hide or show this div for the categories
  <div class="panel">
    <div class="panel__head">Panel Head</div>
    <div class="panel__body">Panel Body</div>
    <div class="panel__footer">Panel Footer</div>
  </div>
</div>

<div data-form-id="blogs">
  Hide or show this div for the blogs
  <div class="panel">
    <div class="panel__head">Panel Head</div>
    <div class="panel__body">Panel Body</div>
    <div class="panel__footer">Panel Footer</div>
  </div>
</div>

<div>
  <div data-form-id="videos">
    Hide or show this div for the videos
    <div class="panel">
      <div class="panel__head">Panel Head</div>
      <div class="panel__body">Panel Body</div>
      <div class="panel__footer">Panel Footer</div>
    </div>
  </div>

  <div data-form-id="products">
    Hide or show this div for the products
    <div class="panel">
      <div class="panel__head">Panel Head</div>
      <div class="panel__body">Panel Body</div>
      <div class="panel__footer">Panel Footer</div>
    </div>
  </div>
wbrvyc0a

wbrvyc0a3#

前面的答案包含了解决这个问题的一个选项,但是点击也可以用你之前使用的方法检测,通过在文档中附加一个事件监听器,你所需要做的就是用e.target替换e.target.id,因为代码应该比较元素和元素,而不是id和元素。

document.addEventListener('click', function(e){
    if(e.target === catBtn) {
        // catForm.classList.toggle("showHide");
        console.log("you clicked the cat btn");
    } else if(e.target === blogBtn) {
        // blogForm.classList.toggle("showHide");
        console.log("you clicked the blog btn");
    } else if(e.target === videoBtn) {
        // videoForm.classList.toggle("showHide");
        console.log("you clicked the video btn");
    } else if(e.target === prodForm) {
        // prodForm.classList.toggle("showHide");
        console.log("you clicked the product btn");
    }
})
r7knjye2

r7knjye24#

首先,您将比较Nodes和字符串(e.target.id返回string),字符串总是返回false。
第二,将事件侦听器应用于文档,这意味着将eventListener添加到整个文档,无论您在何处单击它都将触发。
您需要为每个按钮添加一个eventListener。您可以这样做:

button.addEventListener('click', (event) => {
      show(getForm(button.id))
    })

你也可以做一个document.querrySelectAll('button')并在元素上循环,应用上面的事件监听器。
这是多么有用啊!

toe95027

toe950275#

好吧,我解决了这个问题,通过一点研究和微调,我能够使用它来使一切工作,因为我需要它。所以,如果其他人面临这个问题,这里是我使用的代码

function toggle_form(id) {
    var e = document.getElementById(id);    
    var allForms = document.querySelectorAll('div[id^=new]');
    
    [].forEach.call(allForms, function(div) {  
        if (div != e) {
            div.style.display = 'none';
        }
        else {
            e.style.display = e.style.display == 'none' ? 'block' : 'none';
        }
    });
}

相关问题