简单选项卡式div

时间:2018-08-22 22:06:57

标签: javascript html css

我有一个简单的任务网站,我想添加创建重复任务的功能。

  <label class = "formLabel">Recurring?</label>

  <div class = "radioWrap">
    <label for="once" id = "onceLabel" class="radioLabel">One Time</label>
    <label for="repeat" id = "repeatLabel" class="radioLabel">Repeat</label>
    <input id="once" style="display: none" name="recurring" value="once" type="radio" checked>
    <input id="repeat" style="display: none" name="recurring" value="repeat" type="radio">
  </div>

  <div id = "onceD">
    <label class = "formLabel">Deadline</label>
    <input type = "date" class = "inputText" name = "dateInput" minlength = "5" maxlength = "10" placeholder = "Deadline (MM/DD/YYYY)" required>
  </div>
  <div id = "repeatD">
    <label class = "formLabel">Frequency (days)</label>
    <input type = "number" class = "inputText" name = "freqInput" min = "1" max = "20" placeholder = "Repeat every x days" required>
    <label class = "formLabel">Start date</label>
    <input type = "date" class = "inputText" name = "startInput" placeholder = "Start date (MM/DD/YYYY)" required>
    <label class = "formLabel">End date</label>
    <input type = "date" class = "inputText" name = "endInput" placeholder = "End date (MM/DD/YYYY)" required>
  </div>

由于单选按钮周围的包装,CSS无法正常工作,因此如何使用纯Javascript创建基本的选项卡式浏览体验,用户可以单击一个单选按钮以显示#onceD并单击另一个隐藏#onceD并显示#repeatD,同时禁用隐藏的div的子输入(因为它们被标记为必填项)

3 个答案:

答案 0 :(得分:2)

假设您根本无法更改DOM,那么您是对的,CSS无法正常工作。但是,我建议,如果可以更改DOM,则可以这样做。无论如何,您已经将单选按钮设置为display: none,那么为什么不对要显示/隐藏的内容进行兄弟处理呢?这样,您就可以只使用CSS。

选项1

我真的希望您可以更改DOM,因为如果可以的话,仅使用CSS是非常简单的。查看以下代码段:

#once:checked ~ #repeatD, #repeat:checked ~ #onceD {
  display: none;
}
 <label class = "formLabel">Recurring?</label>

  <input id="once" style="display: none" name="recurring" value="once" type="radio" checked>
  <input id="repeat" style="display: none" name="recurring" value="repeat" type="radio">

  <div class = "radioWrap">
    <label for="once" id = "onceLabel" class="radioLabel">One Time</label>
    <label for="repeat" id = "repeatLabel" class="radioLabel">Repeat</label>
  </div>

  <div id = "onceD">
    <label class = "formLabel">Deadline</label>
    <input type = "date" class = "inputText" name = "dateInput" minlength = "5" maxlength = "10" placeholder = "Deadline (MM/DD/YYYY)" required>
  </div>
  <div id = "repeatD">
    <label class = "formLabel">Frequency (days)</label>
    <input type = "number" class = "inputText" name = "freqInput" min = "1" max = "20" placeholder = "Repeat every x days" required>
    <label class = "formLabel">Start date</label>
    <input type = "date" class = "inputText" name = "startInput" placeholder = "Start date (MM/DD/YYYY)" required>
    <label class = "formLabel">End date</label>
    <input type = "date" class = "inputText" name = "endInput" placeholder = "End date (MM/DD/YYYY)" required>
  </div>

选项2

无论如何,假设您不能一次更改DOM,则需要在CSS中添加一个hide类(javascript事件处理程序将调用该类以隐藏适当的标签)。然后,您将需要查看以下JavaScript代码,以了解如何将事件处理程序分配给单选按钮:

// Get your radio buttons to check if they are checked
let once = document.querySelector('#once');
let repeat = document.querySelector('#repeat');
// Get your content you want to show/hide
let onceD = document.querySelector('#onceD');
let repeatD = document.querySelector('#repeatD');

// Get your inputs so you can add event listeners to them
let inputs = document.querySelectorAll('#once, #repeat');

// A function that will check both of your radio buttons, and take
// appropriate action based on the status of its 'checked' state
const selectActive = (e) => {
  once.checked ? onceD.classList.remove('hide') : onceD.classList.add('hide');
  repeat.checked ? repeatD.classList.remove('hide') : repeatD.classList.add('hide');
}

// Add the event listeners to the group of inputs we gathered above
// Note we are passing in the function we just defined as the handler
inputs.forEach(input => input.addEventListener('change', selectActive));

// Since the function was externall defined (outside of the event
// handeler) we can use it to set up a default status
selectActive();
.hide {
  display: none;
}
 <label class = "formLabel">Recurring?</label>

  <div class = "radioWrap">
    <label for="once" id = "onceLabel" class="radioLabel">One Time</label>
    <label for="repeat" id = "repeatLabel" class="radioLabel">Repeat</label>
    <input id="once" style="display: none" name="recurring" value="once" type="radio" checked>
    <input id="repeat" style="display: none" name="recurring" value="repeat" type="radio">
  </div>

  <div id = "onceD">
    <label class = "formLabel">Deadline</label>
    <input type = "date" class = "inputText" name = "dateInput" minlength = "5" maxlength = "10" placeholder = "Deadline (MM/DD/YYYY)" required>
  </div>
  <div id = "repeatD">
    <label class = "formLabel">Frequency (days)</label>
    <input type = "number" class = "inputText" name = "freqInput" min = "1" max = "20" placeholder = "Repeat every x days" required>
    <label class = "formLabel">Start date</label>
    <input type = "date" class = "inputText" name = "startInput" placeholder = "Start date (MM/DD/YYYY)" required>
    <label class = "formLabel">End date</label>
    <input type = "date" class = "inputText" name = "endInput" placeholder = "End date (MM/DD/YYYY)" required>
  </div>

希望这些答案之一适合您的需求。我是只支持CSS的方法的个人拥护者,因为就像我说过的那样,您还是隐藏了那些单选按钮:)

答案 1 :(得分:1)

以下应使用Vanilla JS达到目的。它也是动态的,因为它允许您在顶部的数组中添加更多单选按钮/标签ID。如果您对代码有任何疑问,请告诉我。

实现这一目标的主要步骤是:

  1. 在单选按钮上为更改事件添加事件监听器

    radioButton.addEventListener('change', (e) => activated(e), false);

    这会将事件侦听器添加到单个单选按钮。从本质上讲,只要激活先前未选择的单选按钮,就会导致activated函数被调用。 e是对传递给函数的事件的引用。

  2. 隐藏所有与选中的单选按钮不对应的标签

    activated函数中:currentTab.classList.add('hide');

    这将添加css类hide,该类将设置css属性display: none

  3. 显示与选中的单选按钮相对应的一个标签

    activated函数中:currentTab.classList.remove('hide');

    这将删除该类,即使该标签再次可见。

  4. 适当设置默认值

    在HTML中:<div id="repeatD" class="hide">,以便在加载第一页时隐藏此div。

  5. 可选:使其更通用...

    const tabConfiguration = ...

    ...通过将所有ID存储在一个数组中,然后在该数组上循环而不是使用静态/单个ID。像这样一般地这样做至少避免了一些重复(由于DRY)。

/* didn't include an IIFE wrapper here for brevity */

/* all ids in one place for easy-to-change and adaptable configuration
 * the tabs/toggles should are treated as mutually exclusive, i.e. no two
 * tabs are displayed at the same time */
const tabConfiguration = [{
    togglerId: 'once',
    tabId: 'onceD',
  },
  {
    togglerId: 'repeat',
    tabId: 'repeatD',
  }
]

/* loop over configuration and
 * add an event listener to each radio button that fires when the button is checked */
for (let i = 0; i < tabConfiguration.length; i += 1) {
  const radioButton = document.getElementById(tabConfiguration[i].togglerId);
  /* add event listeners that fire when the radio button is checked */
  radioButton.addEventListener('change', (e) => {
    activated(e)
  }, false);
}

/* event listener function called by each event listener when an event is fired */
function activated(e) {
  /* match against the id*/
  for (let i = 0; i < tabConfiguration.length; i += 1) {
    const currentTab = document.getElementById(tabConfiguration[i].tabId);
    console.log(currentTab.id);
    if (e.target.id === tabConfiguration[i].togglerId) {
      /* if it matches show it, i.e. remove the hide class */
      currentTab.classList.remove('hide');
    } else {
      /* all other ones should be hidden (as mentioned tabs are mutually exclusive) */
      currentTab.classList.add('hide');
    }
  }
}
.hide {
  display: none;
}
<label class="formLabel">Recurring?</label>

<div class="radioWrap">
  <label for="once" id="onceLabel" class="radioLabel">One Time</label>
  <input id="once" name="recurring" value="once" type="radio" checked>
  <label for="repeat" id="repeatLabel" class="radioLabel">Repeat</label>
  <input id="repeat" name="recurring" value="repeat" type="radio">
</div>

<div id="onceD">
  <label class="formLabel">Deadline</label>
  <input type="date" class="inputText" name="dateInput" minlength="5" maxlength="10" placeholder="Deadline (MM/DD/YYYY)" required>
</div>
<div id="repeatD" class="hide">
  <label class="formLabel">Frequency (days)</label>
  <input type="number" class="inputText" name="freqInput" min="1" max="20" placeholder="Repeat every x days" required>
  <label class="formLabel">Start date</label>
  <input type="date" class="inputText" name="startInput" placeholder="Start date (MM/DD/YYYY)" required>
  <label class="formLabel">End date</label>
  <input type="date" class="inputText" name="endInput" placeholder="End date (MM/DD/YYYY)" required>
</div>

答案 2 :(得分:0)

我这样做是为了使单选按钮正常工作。

html

<input id="swap1" type="radio"  name="rad" value="onceD" onclick="">OnceD</input>
<input id="swap2" type="radio" name="rad" value="repeatD"  onclick="">repeatD</input>


<input id="testButton" type="button" onclick="swap();">Test</input>


<div id = "onceD">
<label class = "formLabel">Deadline</label>
<input type = "date" class = "inputText" name = "dateInput" minlength = "5" maxlength = "10" placeholder = "Deadline (MM/DD/YYYY)" required>
</div>
<div id = "repeatD">
<label class = "formLabel">Frequency (days)</label>
<input type = "number" class = "inputText" name = "freqInput" min = "1" max = "20" placeholder = "Repeat every x days" required>
<label class = "formLabel">Start date</label>
<input type = "date" class = "inputText" name = "startInput" placeholder = "Start date (MM/DD/YYYY)" required>
<label class = "formLabel">End date</label>
<input type = "date" class = "inputText" name = "endInput" placeholder = "End date (MM/DD/YYYY)" required>
</div>

javascript

var x=document.getElementById("swap1");
var y=document.getElementById("swap2");
var onceD = document.getElementById("onceD");
var repeatD = document.getElementById("repeatD");


function swap()
{

if(x.checked == true)
 {
  onceD.style.display = 'block';
  repeatD.style.display = 'none';
 }

if(y.checked == true)
 {
  onceD.style.display = 'none';
  repeatD.style.display = 'block';
 }

}

不幸的是,在使单选按钮仅使用单选按钮更新div时出现问题。因此,我添加了一个按钮来检查选中了哪个单选按钮。我本来可以共享JSFiddle,但在那里无法正常工作。

您可能只使用单选按钮就可以使用它,但我认为您需要使用jQuery。

使用其他输入类型也可以并且可能更容易做到这一点。