将两个表单输入链接到彼此动态更新

时间:2015-08-19 11:01:54

标签: javascript css html5

只是学习Javascript所以请善待

背景:基于Bootstrap的网站有联系表格,我想使用html5 input type="range"元素。在codepen(original here)上使用modernizr找到了一个美化版本,基本上只是根据我的要求更新了CSS样式。

我需要滑块来更新'与下拉菜单相关并编写了一个实现此功能的基本javascript函数(有点)..请参阅下面的代码。

问题:'原作'滑块功能(在拖动时更新'工具提示'样式值)仍然存在。使用我自己的javascript函数,我可以使用下拉列表更改范围值但是不会更新-ms-fill-lower或工具提示值。

原始javascript有点超出我目前的能力;我不确定我应该尝试使用自己的功能等更新的价值。我认为这可能与输入元素焦点有关但是如果有人可以请指出我正确的方向我如何定位/链接正确的值/元素以创建所需的结果,以便范围滑块正确更新'当从下拉菜单中选择所需的值时,我将非常感激!



//ORIGINAL SLIDER JAVASCRIPT

var range_el = document.querySelector('input[type=range]'),
  style_el = document.createElement('style'),
  range_style = getComputedStyle(range_el),
  pad = range_style.paddingTop.split('px')[0],
  w = range_style.width.split('px')[0],
  fill_max_w = w - 2 * pad,
  messages = [
    'Making an enquiry',
    'Not sure its for me',
    'Want to know more',
    'Very interested',
    'I want to do this',
    'Ready to Start',
  ];

document.body.appendChild(style_el);

range_el.addEventListener('input', function() {
  var perc = this.value,
    dec = perc / 100,
    fill_w = Math.round(dec * fill_max_w),
    msg = messages[0];

  for (var i = 0; i < 4; i++) {
    if (perc > i * 25 && i <= (i + 1) * 25) {
      msg = messages[(perc == 100) ? 5 : ((perc == 50) ? 6 : (i + 1))];
    }
  }

  style_el.textContent =
    '.js input[type=range]::-webkit-slider-runnable-track:before,' +
    '.js input[type=range] /deep/ #track:before{width:' + fill_w + 'px}' +
    '.js input[type=range]::-webkit-slider-thumb:before,' +
    '.js input[type=range] /deep/ #thumb:before{content:"' + perc + '%"}' +
    '.js input[type=range]::-webkit-slider-thumb:after,' +
    '.js input[type=range] /deep/ #thumb:after{content:"' + msg + '"}';
}, false);

//MY JAVASCRIPT FUNCTION

function changeValueMobile() {
  var option = document.getElementById('commitmentmobile').value;

  if (option == "Ready to Start") {
    document.getElementById('commitmentdesktop').value = 100;
  } else if (option == "I want to do this") {
    document.getElementById('commitmentdesktop').value = 80;
  } else if (option == "Very interested") {
    document.getElementById('commitmentdesktop').value = 60;
  } else if (option == "I want to know more") {
    document.getElementById('commitmentdesktop').value = 40;
  } else if (option == "Not sure this is right for me") {
    document.getElementById('commitmentdesktop').value = 20;
  } else if (option == "Just making an enquiry") {
    document.getElementById('commitmentdesktop').value = 0;
  }
}
&#13;
/*CSS STYLES */
input[type='range'] {
  position: relative;
  margin: 100px auto 20px auto;
  padding: 0.75em 0 0.25em 0;
  max-width: 28em;
  width: 90%;
  height: 3em;
  opacity: .75;
  background: transparent;
  font-size: 1em;
  cursor: pointer;
}
input[type='range'],
input[type='range']::-webkit-slider-runnable-track,
input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none;
  border: none;
}
input[type='range']::-webkit-slider-runnable-track {
  position: relative;
  box-sizing: border-box;
  padding: 0;
  width: 300px;
  height: 1.5em;
  border-radius: 0.75em;
  box-shadow: 0 1px 1px #def3f8, inset 0 .125em .125em #0d1112;
  background: #ccc;
}
input[type='range']::-moz-range-track {
  box-sizing: border-box;
  padding: 0.25em;
  width: 28em;
  height: 1.5em;
  border-radius: 0.75em;
  box-shadow: 0 1px 1px #def3f8, inset 0 .125em .125em #0d1112;
  background: #ccc;
}
input[type='range']::-ms-track {
  border: none;
  box-sizing: border-box;
  padding: 0.25em;
  width: 28em;
  height: 1.5em;
  border-radius: 0.75em;
  box-shadow: 0 1px 1px #def3f8, inset 0 .125em .125em #0d1112;
  background: #ccc;
  color: transparent;
}
input[type='range']::-moz-range-progress {
  box-sizing: border-box;
  border-left: solid 0.25em transparent;
  height: 1em;
  border-radius: 0.5em 0.1875em 0.1875em 0.5em / 50%;
  box-shadow: inset 0 -1px 1px #09313d, inset 0 1px 1px #c0edf3;
  background: #e12726;
  background-clip: padding-box;
  border-radius: 0.75em 0.1875em 0.1875em 0.75em / 50%;
  background-clip: padding-box;
}
input[type='range']::-ms-fill-lower {
  height: 1em;
  border-radius: 0.5em 0.1875em 0.1875em 0.5em / 50%;
  box-shadow: inset 0 -1px 1px #09313d, inset 0 1px 1px #c0edf3;
  background: #e12726;
  background-clip: padding-box;
}
input[type='range']::-webkit-slider-thumb {
  position: relative;
  margin-top: -0.375em;
  box-sizing: border-box;
  border: solid 0.125em rgba(33, 33, 33, 0.5);
  width: 2.25em;
  height: 2.25em;
  border-radius: 50%;
  box-shadow: 0 .125em .125em #3b4547;
  background: $brandbasic;
  background-clip: border-box;
  background-origin: border-box;
  background-repeat: no-repeat;
  background-size: 100% .125em, .125em 100%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 115% 115%;
  filter: drop-shadow(0 1px #516570);
}
input[type='range']::-moz-range-thumb {
  box-sizing: border-box;
  border: solid 0.125em rgba(33, 33, 33, 0.5);
  width: 2.25em;
  height: 2.25em;
  border-radius: 50%;
  box-shadow: 0 .125em .125em #3b4547;
  background: radial-gradient(#777777, rgba(119, 119, 119, 0) 70%) 50% 50%, radial-gradient(#777777, rgba(119, 119, 119, 0) 70%) 50% 50%, radial-gradient(at 50% 0 at 50% 0, #777777, rgba(119, 119, 119, 0) 71%) 50% 0, radial-gradient(at 50% 100% at 50% 100%, #777777, rgba(119, 119, 119, 0) 71%) 50% 100%, radial-gradient(at 0 50% at 0 50%, #777777, rgba(119, 119, 119, 0) 71%) 0 50%, radial-gradient(at 100% 50% at 100% 50%, #777777, rgba(119, 119, 119, 0) 71%) 100% 50%, radial-gradient(rgba(59, 69, 71, 0) 50%, #3b4547 71%) 50% -0.25em #fff;
  background-clip: border-box;
  background-origin: border-box;
  background-repeat: no-repeat;
  background-size: 100% .125em, .125em 100%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 115% 115%;
}
input[type='range']::-ms-thumb {
  box-sizing: border-box;
  border: solid 0.125em rgba(33, 33, 33, 0.5);
  width: 2.25em;
  height: 2.25em;
  border-radius: 50%;
  box-shadow: 0 .125em .125em #3b4547;
  background: radial-gradient(#777777, rgba(119, 119, 119, 0) 70%) 50% 50%, radial-gradient(#777777, rgba(119, 119, 119, 0) 70%) 50% 50%, radial-gradient(at 50% 0 at 50% 0, #777777, rgba(119, 119, 119, 0) 71%) 50% 0, radial-gradient(at 50% 100% at 50% 100%, #777777, rgba(119, 119, 119, 0) 71%) 50% 100%, radial-gradient(at 0 50% at 0 50%, #777777, rgba(119, 119, 119, 0) 71%) 0 50%, radial-gradient(at 100% 50% at 100% 50%, #777777, rgba(119, 119, 119, 0) 71%) 100% 50%, radial-gradient(rgba(59, 69, 71, 0) 50%, #3b4547 71%) 50% -0.25em #fff;
  background-clip: border-box;
  background-origin: border-box;
  background-repeat: no-repeat;
  background-size: 100% .125em, .125em 100%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 115% 115%;
}
.js input[type='range']::-webkit-slider-runnable-track:before,
.js input[type='range'] /deep/ #track:before {
  position: absolute;
  top: 0.25em;
  left: 0.25em;
  width: 0em;
  height: 1em;
  border-radius: 0.5em 0.1875em 0.1875em 0.5em / 50%;
  box-shadow: inset 0 -1px 1px #09313d, inset 0 1px 1px #c0edf3;
  background: #e12726;
  background-clip: padding-box;
  content: '';
}
.js input[type='range']::-webkit-slider-thumb:before,
.js input[type='range']::-webkit-slider-thumb:after,
.js input[type='range'] /deep/ #thumb:before,
.js input[type='range'] /deep/ #thumb:after {
  position: absolute;
  bottom: 100%;
  left: 50%;
  color: #ebeef3;
  text-align: center;
  text-shadow: 1px 1px 1px rgba(211, 23, 22, 0.5);
}
.js input[type='range']::-webkit-slider-thumb:before,
.js input[type='range'] /deep/ #thumb:before {
  width: 4em;
  height: 2.25em;
  border-radius: 0.125em;
  transform: translate(-50%, -0.5em);
  box-shadow: inset 0 1px 1px #d1e4f9;
  background: #212121;
  clip-path: polygon(2.375em 1.875em, 2em 2.25em, 1.625em 1.875em, 0.125em 1.875em, 0.07716em 1.86548em, 0.03661em 1.83839em, 0.00952em 1.79784em, 0em 1.75em, 0em 0.125em, 0.00952em 0.07716em, 0.03661em 0.03661em, 0.07716em 0.00952em, 0.125em 0em, 3.875em 0em, 3.92284em 0.00952em, 3.96339em 0.03661em, 3.99048em 0.07716em, 4em 0.125em, 4em 1.75em, 3.99048em 1.79784em, 3.96339em 1.83839em, 3.92284em 1.86548em, 3.875em 1.875em);
  font: 2em/1.40625em trebuchet ms, verdana, arial, sans-serif;
  content: "0%";
}
.js input[type='range']::-webkit-slider-thumb:after,
.js input[type='range'] /deep/ #thumb:after {
  width: 9.6em;
  border-radius: 50%;
  transform: translate(-50%, -2.75em);
  box-shadow: 0 2.25em 0.625em -0.5em rgba(55, 84, 92, 0.75);
  font: 0.75em trebuchet ms, verdana, arial, sans-serif;
  white-space: nowrap;
  content: "Making an enquiry";
}
input[type='range']:focus {
  outline: none;
  opacity: .99;
  border: none;
  box-shadow: none;
}
&#13;
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script>
<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <input type='range' id="commitmentdesktop" class="form-control" name="commitmentdesktop" value='0' step="20">
    <select id="commitmentmobile" name="commitmentmobile" class="form-control smaller-select" onchange="changeValueMobile();">
      <option>&nbsp;</option>
      <option value="Ready to Start">I'm ready to Start</option>
      <option value="I want to do this">I want to do this</option>
      <option value="Very interested">I'm very interested</option>
      <option value="I want to know more">I want to know more</option>
      <option value="Not sure this is right for me">I'm not sure this is right for me</option>
      <option value="Just making an enquiry">Just making an enquiry</option>
    </select>
  </div>
  <!-- /.col-md-12 -->
</div>
<!-- /.row -->
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:3)

我做了以下更改:

  • 添加了对<SELECT>元素的引用。
  • 为选择<OPTIONS>创建了一个数据数组。
  • 使用JavaScript填充<SELECT>框。
  • 将样式元素添加到<HEAD>。 (仅限惯例)
  • 为保持一致性,请从select元素中删除onchange
  • 修正了将所选索引转换为百分比的比例逻辑。

代码

以下是external JSFiddle的链接(与下面相同的代码),但您可以在此页面上直接运行。

// Reference elements.
var range_el = document.querySelector('input[type=range]'),
    select_el = document.querySelector('select[name=commitmentmobile]'),
    style_el = document.createElement('style');

// Other variables.
var range_style = getComputedStyle(range_el),
    pad = range_style.paddingTop.split('px')[0],
    w = range_style.width.split('px')[0],
    fill_max_w = w - 2 * pad,
    options = [
        { val : 0,   msg : 'Making an enquiry',   text : "Just making an enquiry" },
        { val : 20,  msg : 'Not sure its for me', text : "I'm not sure this is right for me" },
        { val : 40,  msg : 'Want to know more',   text : "I want to know more" },
        { val : 60,  msg : 'Very interested',     text : "I'm very interested" },
        { val : 80,  msg : 'I want to do this',   text : "I want to do this" },
        { val : 100, msg : 'Ready to Start',      text : "I'm ready to Start" }
    ];

// Populate select box.
for (var i = options.length - 1; i >= 0; i--) {
    var option_el = document.createElement('option');
    option_el.value = i;
    option_el.innerHTML = options[i].text;
    select_el.appendChild(option_el);
}

// Add style element to the head.
document.head.appendChild(style_el);

// Event listeners.
range_el.addEventListener('input', function (e) {
    updateSlider();
}, false);

select_el.addEventListener('change', function(e) {
    var option = Number(select_el.value);
    range_el.value = options[option].val;
    updateSlider();
});

// Update function which binds the range slider to the select box.
function updateSlider() {
    var perc = range_el.value,
        step = range_el.step,
        index = Math.floor(perc / step),
        msg = options[index].msg,
        scale = (perc - 1) / 100,
        fill_w = Math.round(scale * fill_max_w);

    style_el.textContent = [
        '.js input[type=range]::-webkit-slider-runnable-track:before,',
        '.js input[type=range] /deep/ #track:before{width:' + fill_w + 'px}',
        '.js input[type=range]::-webkit-slider-thumb:before,',
        '.js input[type=range] /deep/ #thumb:before{content:"' + perc + '%"}',
        '.js input[type=range]::-webkit-slider-thumb:after,',
        '.js input[type=range] /deep/ #thumb:after{content:"' + msg + '"}',
    ].join(' ');
    
    select_el.value = index;
}
input[type='range'] {
    position: relative;
    margin: 100px auto 20px auto;
    padding: 0.75em 0 0.25em 0;
    max-width: 28em;
    width: 90%;
    height: 3em;
    opacity: .75;
    background: transparent;
    font-size: 1em;
    cursor: pointer;
}
input[type='range'], input[type='range']::-webkit-slider-runnable-track, input[type='range']::-webkit-slider-thumb {
    -webkit-appearance: none;
    border: none;
}
input[type='range']::-webkit-slider-runnable-track {
    position: relative;
    box-sizing: border-box;
    padding: 0;
    width: 300px;
    height: 1.5em;
    border-radius: 0.75em;
    box-shadow: 0 1px 1px #def3f8, inset 0 .125em .125em #0d1112;
    background: #ccc;
}
input[type='range']::-moz-range-track {
    box-sizing: border-box;
    padding: 0.25em;
    width: 28em;
    height: 1.5em;
    border-radius: 0.75em;
    box-shadow: 0 1px 1px #def3f8, inset 0 .125em .125em #0d1112;
    background: #ccc;
}
input[type='range']::-ms-track {
    border: none;
    box-sizing: border-box;
    padding: 0.25em;
    width: 28em;
    height: 1.5em;
    border-radius: 0.75em;
    box-shadow: 0 1px 1px #def3f8, inset 0 .125em .125em #0d1112;
    background: #ccc;
    color: transparent;
}
input[type='range']::-moz-range-progress {
    box-sizing: border-box;
    border-left: solid 0.25em transparent;
    height: 1em;
    border-radius: 0.5em 0.1875em 0.1875em 0.5em / 50%;
    box-shadow: inset 0 -1px 1px #09313d, inset 0 1px 1px #c0edf3;
    background: #e12726;
    background-clip: padding-box;
    border-radius: 0.75em 0.1875em 0.1875em 0.75em / 50%;
    background-clip: padding-box;
}
input[type='range']::-ms-fill-lower {
    height: 1em;
    border-radius: 0.5em 0.1875em 0.1875em 0.5em / 50%;
    box-shadow: inset 0 -1px 1px #09313d, inset 0 1px 1px #c0edf3;
    background: #e12726;
    background-clip: padding-box;
}
input[type='range']::-webkit-slider-thumb {
    position: relative;
    margin-top: -0.375em;
    box-sizing: border-box;
    border: solid 0.125em rgba(33, 33, 33, 0.5);
    width: 2.25em;
    height: 2.25em;
    border-radius: 50%;
    box-shadow: 0 .125em .125em #3b4547;
    background: $brandbasic;
    background-clip: border-box;
    background-origin: border-box;
    background-repeat: no-repeat;
    background-size: 100% .125em, .125em 100%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 115% 115%;
    filter: drop-shadow(0 1px #516570);
}
input[type='range']::-moz-range-thumb {
    box-sizing: border-box;
    border: solid 0.125em rgba(33, 33, 33, 0.5);
    width: 2.25em;
    height: 2.25em;
    border-radius: 50%;
    box-shadow: 0 .125em .125em #3b4547;
    background: radial-gradient(#777777, rgba(119, 119, 119, 0) 70%) 50% 50%, radial-gradient(#777777, rgba(119, 119, 119, 0) 70%) 50% 50%, radial-gradient(at 50% 0 at 50% 0, #777777, rgba(119, 119, 119, 0) 71%) 50% 0, radial-gradient(at 50% 100% at 50% 100%, #777777, rgba(119, 119, 119, 0) 71%) 50% 100%, radial-gradient(at 0 50% at 0 50%, #777777, rgba(119, 119, 119, 0) 71%) 0 50%, radial-gradient(at 100% 50% at 100% 50%, #777777, rgba(119, 119, 119, 0) 71%) 100% 50%, radial-gradient(rgba(59, 69, 71, 0) 50%, #3b4547 71%) 50% -0.25em #fff;
    background-clip: border-box;
    background-origin: border-box;
    background-repeat: no-repeat;
    background-size: 100% .125em, .125em 100%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 115% 115%;
}
input[type='range']::-ms-thumb {
    box-sizing: border-box;
    border: solid 0.125em rgba(33, 33, 33, 0.5);
    width: 2.25em;
    height: 2.25em;
    border-radius: 50%;
    box-shadow: 0 .125em .125em #3b4547;
    background: radial-gradient(#777777, rgba(119, 119, 119, 0) 70%) 50% 50%, radial-gradient(#777777, rgba(119, 119, 119, 0) 70%) 50% 50%, radial-gradient(at 50% 0 at 50% 0, #777777, rgba(119, 119, 119, 0) 71%) 50% 0, radial-gradient(at 50% 100% at 50% 100%, #777777, rgba(119, 119, 119, 0) 71%) 50% 100%, radial-gradient(at 0 50% at 0 50%, #777777, rgba(119, 119, 119, 0) 71%) 0 50%, radial-gradient(at 100% 50% at 100% 50%, #777777, rgba(119, 119, 119, 0) 71%) 100% 50%, radial-gradient(rgba(59, 69, 71, 0) 50%, #3b4547 71%) 50% -0.25em #fff;
    background-clip: border-box;
    background-origin: border-box;
    background-repeat: no-repeat;
    background-size: 100% .125em, .125em 100%, 50% 50%, 50% 50%, 50% 50%, 50% 50%, 115% 115%;
}
.js input[type='range']::-webkit-slider-runnable-track:before, .js input[type='range'] /deep/ #track:before {
    position: absolute;
    top: 0.25em;
    left: 0.25em;
    width: 0em;
    height: 1em;
    border-radius: 0.5em 0.1875em 0.1875em 0.5em / 50%;
    box-shadow: inset 0 -1px 1px #09313d, inset 0 1px 1px #c0edf3;
    background: #e12726;
    background-clip: padding-box;
    content:'';
}
.js input[type='range']::-webkit-slider-thumb:before, .js input[type='range']::-webkit-slider-thumb:after, .js input[type='range'] /deep/ #thumb:before, .js input[type='range'] /deep/ #thumb:after {
    position: absolute;
    bottom: 100%;
    left: 50%;
    color: #ebeef3;
    text-align: center;
    text-shadow: 1px 1px 1px rgba(211, 23, 22, 0.5);
}
.js input[type='range']::-webkit-slider-thumb:before, .js input[type='range'] /deep/ #thumb:before {
    width: 4em;
    height: 2.25em;
    border-radius: 0.125em;
    transform: translate(-50%, -0.5em);
    box-shadow: inset 0 1px 1px #d1e4f9;
    background: #212121;
    clip-path: polygon(2.375em 1.875em, 2em 2.25em, 1.625em 1.875em, 0.125em 1.875em, 0.07716em 1.86548em, 0.03661em 1.83839em, 0.00952em 1.79784em, 0em 1.75em, 0em 0.125em, 0.00952em 0.07716em, 0.03661em 0.03661em, 0.07716em 0.00952em, 0.125em 0em, 3.875em 0em, 3.92284em 0.00952em, 3.96339em 0.03661em, 3.99048em 0.07716em, 4em 0.125em, 4em 1.75em, 3.99048em 1.79784em, 3.96339em 1.83839em, 3.92284em 1.86548em, 3.875em 1.875em);
    font: 2em/1.40625em trebuchet ms, verdana, arial, sans-serif;
    content:"0%";
}
.js input[type='range']::-webkit-slider-thumb:after, .js input[type='range'] /deep/ #thumb:after {
    width: 9.6em;
    border-radius: 50%;
    transform: translate(-50%, -2.75em);
    box-shadow: 0 2.25em 0.625em -0.5em rgba(55, 84, 92, 0.75);
    font: 0.75em trebuchet ms, verdana, arial, sans-serif;
    white-space: nowrap;
    content:"Making an enquiry";
}
input[type='range']:focus {
    outline: none;
    opacity: .99;
    border: none;
    box-shadow: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>

<div class="row">
    <div class="col-md-6 col-md-offset-3">
        <input type='range' id="commitmentdesktop" class="form-control" name="commitmentdesktop" value='0' step="20">
        <select id="commitmentmobile" name="commitmentmobile" class="form-control smaller-select">
            <option>&nbsp;</option>
            <!-- NOTE: These are now generated in JavaScript.
            <option value="5">I'm ready to Start</option>
            <option value="4">I want to do this</option>
            <option value="3">I'm very interested</option>
            <option value="2">I want to know more</option>
            <option value="1">I'm not sure this is right for me</option>
            <option value="0">Just making an enquiry</option>
            -->
        </select>
    </div>
</div>