【问题标题】:Why isn't my text field being added to the page?为什么我的文本字段没有添加到页面中?
【发布时间】:2016-08-31 08:49:00
【问题描述】:

我正在研究一个简单的 HTML 表单的交互性。

具体来说,有一个用于工作角色的下拉选择框。如果选择“其他”,则应出现一个文本字段,要求用户更具体。

我是一个初学者,想在没有 jQuery 的情况下做到这一点。

这是我正在使用的 HTML 的 sn-p:

<fieldset class="basic">         
        <legend>Basic Info</legend>

        <label for="name">Name:</label>
        <input type="text" id="name" name="user_name">

        <label for="mail">Email:</label>
        <input type="email" id="mail" name="user_email">

        <label>Job Role</label>
        <select id="title" name="user_title">
          <option value="full-stack js developer">Full Stack JavaScript Developer</option>
          <option value="front-end developer">Front End Developer</option>
          <option value="back-end developer">Back End Developer</option>
          <option value="designer">Designer</option>          
          <option value="student">Student</option>
          <option value="other">Other</option>  
        </select>           
      </fieldset>

我的直觉告诉我首先构建文本字段并添加它的属性。

然后我将使用 if 条件来测试所选选项是否为“其他”。如果是,那么我会将新创建的文本字段附加到页面。

到目前为止,这还没有奏效。为了尝试调试它,我尝试使用控制台记录我正在尝试使用的元素。我不认为我理解它是如何工作的,因为它打印出 'undefined' 和 'null'。

这是我的 JS:

// 任务:向表单添加交互性

'use strict';

// Hold DOM elements for easy access
var pageBody = document.querySelector('body');
var jobRoleSelect = document.getElementById('title');
console.log(jobSelected);
var jobSelected = jobRoleSelect.options[jobRoleSelect.selectedIndex].value;
var basicSection = document.querySelector('basic');
console.log(basicSection);


// Job Role section of the form. Reveal a text field when the "Other" option is selected from the "Job Role" drop down menu
if(jobSelected === 'other') {
    var otherText = document.createElement('input');
    // Add an text input field. Use the id of "other-title" 
    otherText.setAttribute('id', 'other-title');
    otherText.setAttribute('type', 'text');
    otherText.setAttribute('name', 'other_field');
    otherText.setAttribute('placeholder', 'Your Title');

    var otherLabel = document.createElement('label');
    otherLabel.setAttribute('for', 'other_field');
    otherLabel.innerHTML = 'other';

    basicSelection.appendChild(otherLabel);
    basicSelection.appendChild(otherText);
}

【问题讨论】:

  • 你的JS代码是从哪里调用的?出于您的目的,它应该位于从 select 元素上的更改事件处理程序调用的函数中。要使用.querySelector() 选择类为'basic' 的元素,您需要在类名前加上.,例如document.querySelector('.basic')。此外,您可以更简单地获取选择元素的选定值:只需使用jobRoleSelect.value,无需通过.options 集合。 (另外,与您遇到的问题无关,标签中的for 属性应设置为关联元素的id,而不是name。)
  • 感谢您发现查询选择器缺少的.,我忘记了这一点。我在 HTML 的正文底部附加了 JS。我知道它可以连接,因为另一个功能可以正常工作。所以我可以使用:var jobSelected = jobRoleSelect.value' and then in the if condition, use if(jobSelected === 'other')`?

标签: javascript html forms dom drop-down-menu


【解决方案1】:

您需要设置一个事件侦听器来侦听当用户从下拉菜单中进行选择时触发的“更改”事件。此外,您在 if 语句中引用了“basicSelection”而不是“basicSection”。

'use strict';

var jobRoleSelect = document.getElementById('title');
var basicSection = document.getElementsByClassName('basic')[0];

document.getElementById("title").addEventListener("change", function(){
  var jobSelected = jobRoleSelect.options[jobRoleSelect.selectedIndex].value;
  console.log(jobSelected);
  
  if(jobSelected === 'other') {
    var otherText = document.createElement('input');
    // Add an text input field. Use the id of "other-title" 
    
    otherText.setAttribute('id', 'other-title');
    otherText.setAttribute('type', 'text');
    otherText.setAttribute('name', 'other_field');
    otherText.setAttribute('placeholder', 'Your Title');
    
    var otherLabel = document.createElement('label');
    otherLabel.setAttribute('for', 'other_field');
    otherLabel.innerHTML = 'Other:';

    basicSection.appendChild(otherLabel);
    basicSection.appendChild(otherText);
  }
});
<fieldset class="basic">         
        <legend>Basic Info</legend>

        <label for="name">Name:</label>
        <input type="text" id="name" name="user_name">

        <label for="mail">Email:</label>
        <input type="email" id="mail" name="user_email">

        <label>Job Role</label>
        <select id="title" name="user_title">
          <option value="full-stack js developer">Full Stack JavaScript Developer</option>
          <option value="front-end developer">Front End Developer</option>
          <option value="back-end developer">Back End Developer</option>
          <option value="designer">Designer</option>          
          <option value="student">Student</option>
          <option value="other">Other</option>  
        </select>           
      </fieldset>

【讨论】:

    【解决方案2】:

    如果您显示的 JS 包含在文档正文的末尾,那么它将在页面首次加载时运行一次。我假设您真正想要的是让它运行以响应用户更改所选内容,在这种情况下,您需要将代码包装在一个函数中,并将其作为change 事件的事件处理程序。

    var jobRoleSelect = document.getElementById('title');
    jobRoleSelect.addEventListener('change', function() {
      // your other code here
    });
    

    还请注意,您需要允许用户将选择更改为“其他”,然后将其更改回其他内容,然后再次将其更改为“其他”,即您的功能如果当前选择不需要,则需要能够删除文本输入。

    但我认为只在 html 中包含文本元素和标签并根据需要隐藏和显示它们会简单得多:

       var jobRoleSelect = document.getElementById('title');
    
    jobRoleSelect.addEventListener('click', function() {
      var otherSelected = jobRoleSelect.value === 'other';
      var otherElements = document.querySelectorAll('.other');
    
      for (var i = 0; i < otherElements.length; i++) {
        if (otherSelected)
          otherElements[i].classList.remove('hidden');
        else
          otherElements[i].classList.add('hidden');
      }
    });
    label {
      display: block;
    }
    .hidden {
      display: none;
    }
    <fieldset class="basic">
      <legend>Basic Info</legend>
    
      <label for="name">Name:</label>
      <input type="text" id="name" name="user_name">
    
      <label for="mail">Email:</label>
      <input type="email" id="mail" name="user_email">
    
      <label>Job Role</label>
      <select id="title" name="user_title">
        <option value="full-stack js developer">Full Stack JavaScript Developer</option>
        <option value="front-end developer">Front End Developer</option>
        <option value="back-end developer">Back End Developer</option>
        <option value="designer">Designer</option>
        <option value="student">Student</option>
        <option value="other">Other</option>
      </select>
      <label class="other hidden" for="other-title">Other</label>
      <input class="other hidden" type="text" id="other-title" name="other-field" placeholder='Your title'>
    </fieldset>

    我已经给出了需要隐藏或显示other 类的所有(即两者)元素,这意味着我的代码必须循环它们。您可以改为将它们包装在 div 中并隐藏 div。

    请注意,我已经通过一个类完成了隐藏/显示,我通过元素的.classList 添加或删除了该类。不幸的是,IE.classList,但是有a polyfill,或者你当然可以直接设置style.display 或其他方式。

    【讨论】:

      【解决方案3】:

      您的代码中有很多错误。但我已经弄清楚了并提出了解决方案。使用这个

      <fieldset class="basic">         
              <legend>Basic Info</legend>
      
              <label for="name">Name:</label>
              <input type="text" id="name" name="user_name">
      
              <label for="mail">Email:</label>
              <input type="email" id="mail" name="user_email">
      
              <label>Job Role</label>
              <select id="title" name="user_title">
                <option value="full-stack js developer">Full Stack JavaScript Developer</option>
                <option value="front-end developer">Front End Developer</option>
                <option value="back-end developer">Back End Developer</option>
                <option value="designer">Designer</option>          
                <option value="student">Student</option>
                <option value="other">Other</option>  
              </select>           
            </fieldset>
            <script>
      'use strict';
      
      // Hold DOM elements for easy access
      var pageBody = document.querySelector('body');
      var jobRoleSelect = document.getElementById('title');
      //console.log(jobSelected);
      var basicSelection = document.querySelector('.basic');
      //console.log(basicSection);
      
      jobRoleSelect.onchange = function(){
          var jobSelected = jobRoleSelect.options[jobRoleSelect.selectedIndex].value;
      // Job Role section of the form. Reveal a text field when the "Other" option is selected from the "Job Role" drop down menu
      if(jobSelected == 'other') {
          console.log('nice');
          var otherText = document.createElement('input');
          // Add an text input field. Use the id of "other-title" 
          otherText.setAttribute('id', 'other-title');
          otherText.setAttribute('type', 'text');
          otherText.setAttribute('name', 'other_field');
          otherText.setAttribute('placeholder', 'Your Title');
      
          var otherLabel = document.createElement('label');
          otherLabel.setAttribute('for', 'other_field');
          otherLabel.innerHTML = 'other';
      
          basicSelection.appendChild(otherLabel);
          basicSelection.appendChild(otherText);
      }
      }
      </script>
      

      这是jsFiddle的作品

      【讨论】:

        猜你喜欢
        • 2022-01-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-05
        • 1970-01-01
        • 2016-02-15
        相关资源
        最近更新 更多