更改任何形式的元素后显示div标语

时间:2018-10-26 16:10:27

标签: javascript

JS:

document.getElementsByTagName("input, select, textarea, option, optgroup, fieldset, label").onchange = function () {
     var updateRate = document.querySelector('.updateRate');    
     updateRate.style.display = "block";
};

标记和样式:

<div class="updateRate">Update Rate</div>

<style>
.updateRate { 
   display:none;
   top: 0px;
   position: fixed;
   width: 100%;
   left: 0px;
   z-index: 11111;
}
#rate, .updateRate { 
    background: #354563;
    color: #ffffff;
    cursor: pointer;
    text-align: center;
    padding: 10px;
}
</style>

以上是我的尝试;但是在任何表单元素状态更改后,横幅仍不显示。


更新:因此以下两个SO答案似乎都是正确的;但是也许我没有对上下文进行足够的解释-现在“横幅”会在第一次开始填写表格时立即显示;目标是在用户返回并更新表单元素(第二次或从初始更改)后显示横幅。


上下文: 这是一个内联报价工具;填写表单元素后,报价将生成内联。我正在尝试创建一个“横幅”,该横幅将询问用户是否第二次调整了任何Web表单元素。抱歉造成混乱。

2 个答案:

答案 0 :(得分:2)

您不能以这种方式附加事件,因为 getElementsByTagName方法只接受一个标签名 ,您可以使用 {{3} } 方法来获取元素,然后使用foreach在元素之间循环,并使用addEventListener()附加事件:

var fields = document.querySelectorAll("input, select, textarea, option, optgroup, fieldset, label");

[].forEach.call(fields, function(el) {
  el.addEventListener('change', showUpdateRate, false);
});

function showUpdateRate() {
  if (document.querySelector('.quote').textContent != "") {
    document.querySelector('.updateRate').style.display = "block";
  }
}

document.querySelector('.generate').addEventListener('click', function() {
  var quote = document.querySelector('[name="type"]:checked').value;
  document.querySelector('.quote').textContent = quote + " Quote";
});
.updateRate {
  display: none;
  top: 0px;
  position: fixed;
  width: 100%;
  left: 0px;
  z-index: 11111;
}

#rate,
.updateRate {
  background: #354563;
  color: #ffffff;
  cursor: pointer;
  text-align: center;
  padding: 10px;
}
<div class="updateRate">Update Rate</div>

<br><br><br>
<form>
  <input type="radio" name="type" value="Success">Success
  <input type="radio" name="type" value="Motivation">Motivation
  <input type="radio" name="type" value="Work">Work
  <br><br>
  <input type="button" class="generate" value="Generate">
</form>
<br>
<span class="quote"></span>

答案 1 :(得分:1)

.getElementsByTagName()返回节点列表(类似于数组的对象),而不是单个元素。因此,它没有onchange属性可以使用。获取节点列表后,您需要遍历列表中的所有项,并为每个项一次设置事件处理程序。

此外,.getElementsByTagName()仅允许传递单个标签名称,而不允许使用逗号分隔的列表。此外,它还会返回一个“活动节点列表”,这会影响性能,因此,如果您不是动态添加/删除元素,则应避免使用它,而应使用.querySelectorAll()

现在,optionoptgrouplabel元素只能通过代码进行更改,并且一开始就不会发出或接收change事件,因此您实际上不希望/不需要那些包含在节点列表中的对象。

下面有关如何使您的代码更现代,更有条理的更多注释:

// Get this reference just once and cache it in a variable
var updateRate = document.querySelector('.updateRate');  

// Gather up all the relevant elements into a node list
let elements = document.querySelectorAll("input, select, textarea, fieldset");

// Convert the node list into an Array so that .forEach() 
// can safely be used to loop in all modern browsers
Array.prototype.slice.call(elements).forEach(function(element){
  // Add event listeners the modern way, not with .onXyz properties
  element.addEventListener("change", function () {  
    // Just remove the hidden class already applied to the element
    // instead of working with inline styles
    updateRate.classList.remove("hidden");
  });
});
/*
   This is applied to the "Update Rate" element in HTML by default.
   It can be removed by the JavaScript when appropriate. 
*/
.hidden { display:none; }

.updateRate { 
   top: 0px;
   position: fixed;
   width: 100%;
   left: 0px;
   z-index: 11111;
}

#rate, .updateRate { 
    background: #354563;
    color: #ffffff;
    cursor: pointer;
    text-align: center;
    padding: 10px;
}
<form>
  <fieldset>
    <legend>This is the legend</legend>
    <input>
    <select>
      <option>choice 1</option>
      <option>choice 2</option>
      <option>choice 3</option>
    </select>
  </fieldset>
 <textarea></textarea>
</form>

<!-- Set this element to be hidden by default -->
<div class="updateRate" class="hidden">Update Rate</div>