RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 808689
Accepted
siberian
siberian
Asked:2020-04-03 13:37:45 +0000 UTC2020-04-03 13:37:45 +0000 UTC 2020-04-03 13:37:45 +0000 UTC

单击 +/- 按钮更改输入中的值并从 div 中获取值

  • 772

如果页面上可以有多组按钮和输入,如何通过单击按钮 (+/-) 更改输入值并从现有表中获取值?

$(function() {
      var countInputs = document.getElementsByClassName('count-buttons');

      for (var input in countInputs) {
        if (!countInputs.hasOwnProperty(input)) {
          continue;
        }

        var butM = input.getElementsByClassName('btn-minus');
        var butP = input.getElementsByClassName('btn-plus');

        var units = countInput.value.replace(/\d/g, '');

        butP.onclick = function() {
          countInput.value = parseInt(countInput.value) + 1 + units;
        };

        butM.onclick = function() {
          if (parseInt(countInput.value) > 1) {
            countInput.value = parseInt(countInput.value) - 1 + units;
          }
        };


        $(function() {
          document.querySelector('.count-buttons').onmouseover = (function() {
            document.querySelector('.count-buttons__table').style.display = 'table';
          });
          document.querySelector('.count-buttons__table').onmouseout = (function() {
            document.querySelector('.count-buttons__table').style.display = 'none';
          });

          var elems = document.querySelectorAll('.count-buttons__table-td');

          for (var i = elems.length - 1; i >= 0; i--) {
            elems[i].addEventListener('click', myFunc, false);
          }

          function myFunc() {
            document.getElementsByClassName('qty').value = this.innerHTML;
          }
        });
<div class="count-buttons">
  <button type="button" class="btn ctrl btn-minus">
         <span>−</span></button>
  <input name="" value="" size="4" title="" class="input-text qty" maxlength="12" />
  <button type="button" class="btn ctrl btn-plus"><span>+</span></button>
  <div class="count-buttons__table">
    <div class="count-buttons__table-tr">
      <div class="count-buttons__table-td">6</div>
      <div class="count-buttons__table-td">12</div>
      <div class="count-buttons__table-td">18</div>
    </div>
    <div class="count-buttons__table-tr">
      <div class="count-buttons__table-td">24</div>
      <div class="count-buttons__table-td">30</div>
      <div class="count-buttons__table-td">36</div>
    </div>
  </div>
</div>

jsfiddle

UPD

归根结底,value 的取值有两种方式:

  1. 通过按+或按钮-(分别增加1或减少数字)示例
  2. 从下拉表中选择数字(数字永远不会改变)示例
javascript
  • 3 3 个回答
  • 10 Views

3 个回答

  • Voted
  1. dmitryshishkin
    2020-04-03T15:29:28Z2020-04-03T15:29:28Z

    有可能以某种方式解决这个问题。

    var Counter = function(counter) {
      // Сохраняем все, чтобы можно было использовать в методах
    
      // Счетчик
      this.counter = counter;
      
      // Ячейки таблицы
      this.cells = counter.querySelectorAll('.table__td');
      this.cells = Array.prototype.slice.call(this.cells);
      
      // Кнопку «минус»
      this.minus = counter.querySelector('.counter__minus');
      
      // Кнопку «плюс»
      this.plus = counter.querySelector('.counter__plus');
      
      // Инпут
      this.field = counter.querySelector('.counter__input');
      
      // Инициализируем события
      this.events();
    }
    
    // Метод отвечающий за вызов слушателей
    Counter.prototype.events = function() {
      // Обработчик кнопки «плюс»
      this.plus.addEventListener('click', this.increment.bind(this));
      
      // Обработчик кнопки «минус»
      this.minus.addEventListener('click', this.decrement.bind(this));
      
      // Пробегаемся по ячейкам таблицы
      for(var cell in this.cells) {
        // и на каждый навешиваем обработчик
        this.cells[cell].addEventListener('click', this.changeFromTable.bind(this, this.cells[cell]));
      }
    }
    
    // Берет значение из ячейки и ставит его в инпут
    Counter.prototype.changeFromTable = function(cell) {
      this.field.value = cell.textContent;
    }
    
    // Метод увеличивает значение в поле на 1
    Counter.prototype.increment = function() {
      this.field.value = parseInt(this.field.value) + 1;
    }
    
    // Метод уменьшает значение в поле на 1
    Counter.prototype.decrement = function() {
      // Сохраняем новое значение в переменную
      var newValue = parseInt(this.field.value) - 1;
      
      // Если оно меньше нуля - делаем нулем
      if(newValue < 0) {
        newValue = 0;
      }
      
      // Меняем значение в инпуте
      this.field.value = newValue;
    }
    
    // Собираем список всех счетчиков на странице
    var counters = document.querySelectorAll('.counter');
    
    // Превращаем в массив
    counters = Array.prototype.slice.call(counters);
    
    // Проблегаемся по счетчикам
    counters.forEach(function(counter) {
      // И инициализируем каждый
      new Counter(counter);
    });
    .table {
      font-size: 0;
      margin-top: 5px;
    }
    .table__td {
      cursor: pointer;
      font: 14px sans-serif;
      display: inline-block;
      padding: 2px 5px;
      border-radius: 3px;
      border: 1px solid #ccc;
    }
    
    .table__td + .table__td {
      margin-left: 5px;
    }
    
    .table__td:hover {
      background-color: #f5f5f5;
    }
    
    hr {
      height: 1px;
      margin: 15px 0;
      background-color: #ccc;
      color: #ccc;
      border: none;
    }
    <div class="counter">
      <button class="counter__minus">−</button>
      
      <!-- Устанавливаем readonly потому что вручную значение менять нельзя -->
      <input class="counter__input" type="text" readonly value="0">
      <button class="counter__plus">+</button>
      
      <div class="table">
        <div class="table__td">6</div>
        <div class="table__td">12</div>
        <div class="table__td">18</div>
        <div class="table__td">24</div>
        <div class="table__td">30</div>
        <div class="table__td">36</div>
      </div>
    </div>
    
    <hr>
    
    <div class="counter">
      <button class="counter__minus">−</button>
      
      <!-- Устанавливаем readonly потому что вручную значение менять нельзя -->
      <input class="counter__input" type="text" readonly value="0">
      <button class="counter__plus">+</button>
      
      <div class="table">
        <div class="table__td">6</div>
        <div class="table__td">12</div>
        <div class="table__td">18</div>
        <div class="table__td">24</div>
        <div class="table__td">30</div>
        <div class="table__td">36</div>
      </div>
    </div>

    如果你不明白我为什么使用 this、prototype 和 new,那么请阅读“原型风格中的 OOP ”和“对象方法和调用上下文”章节。

    • 6
  2. Best Answer
    siberian
    2020-04-03T18:30:59Z2020-04-03T18:30:59Z

    不幸的是,@dmitryshishkin 建议的答案对我不起作用,因为 发生了一个奇怪的错误-单击按钮+/-时,值一次增加/减少了两个数字...

    最后,我得到了这个代码:

    counters = [].slice.call(document.querySelectorAll('.count-buttons'));
    
        counters.forEach(function(counter) {
            var input = counter.querySelector('.input-text');
    
            counter.querySelector('.btn-minus').onclick = function () {
                var newValue = +input.value - 1;
    
                if (newValue >= 1) {
                    input.value = newValue;
                }
            };
    
            counter.querySelector('.btn-plus').onclick = function () {
                input.value = +input.value + 1;
            };
    
            counter.querySelector('.count-buttons__table').onclick = function (evt) {
                input.value = evt.target.textContent;
                this.style.display = 'none';
            }
        });
    
    • 0
  3. yar85
    2020-04-03T20:25:07Z2020-04-03T20:25:07Z

    任务并不完全清楚。
    如果您想要一个带有按钮-/+和弹出选项的输入字段,那么在这里:

    var $d = document, 
        cbsTable,
        callerEl; 
    
    $d.addEventListener('DOMContentLoaded', () => {
      cbsTable = $d.createElement('table'); 
      cbsTable.id = 'cbtn-table'; 
      cbsTable.addEventListener('click', onTableClick); 
      $d.body.appendChild(cbsTable); 
      
      let cbs = $d.getElementsByClassName('cbtn-combobox'); 
      for (let cb of cbs) {
        cb.addEventListener('click', onCbClick); 
        cb.addEventListener('input', onCbInput); 
        cb.addEventListener('blur', () => setTimeout(() => {
          if (!$d.activeElement.classList.contains('cbtn-combobox'))
            cbsTable.style.visibility = 'hidden'; 
        }, 150)); 
        cb.contentEditable = true; 
      }
      console.log('Клик по значению вызывает всплывающую таблицу.');
    });
    
    function onCbInput(e) {
      let cPos   = getCaretPosCe(this, true),
          newVal = +(this.textContent.match(/\d/g) || [0]).join(''); 
      this.textContent = Math.min(99999, newVal); 
      setCaretPosCe(this, cPos, true); 
    }
    
    function onCbClick(e) {
      let cs   = getComputedStyle(this), 
          btnW = parseInt(cs.getPropertyValue('--btn-width')),
          mX   = e.clientX - this.getBoundingClientRect().left, 
          crrVal = parseInt(this.textContent) || 0, 
          newVal = null; 
      newVal = (mX < btnW) ? --crrVal :
        (mX > this.offsetWidth - btnW) ? ++crrVal : null; 
      if (newVal !== null) {
        this.textContent = Math.min(99999, Math.max(0, newVal)); 
        setCaretPosCe(this, 0, true); 
      }
      callerEl = this; 
      showPopupTable(); 
    }
    
    function showPopupTable() {
      let tDataStr = callerEl.dataset.table; 
      if (!tDataStr)
        return; 
      cbsTable.innerHTML = ''; 
      let row; 
      tDataStr.split('|').forEach(rowStr => {
        row = cbsTable.insertRow(); 
        rowStr.split(',').forEach(cellValue => {
          row.insertCell().textContent = cellValue; 
        }); 
      }); 
      let bcr = callerEl.getBoundingClientRect(); 
      cbsTable.style.top = (bcr.bottom + 2) + 'px'; 
      cbsTable.style.left = bcr.left + 
        (callerEl.offsetWidth - cbsTable.offsetWidth)  / 2 + 'px'; 
      cbsTable.style.visibility = 'visible'; 
    }
    
    function onTableClick(e) {
      let clckd = e.target; 
      if (clckd.tagName.toLowerCase() === 'td')
        callerEl.textContent = parseInt(clckd.textContent) || 0; 
    }
    
    function getCaretPosCe(el, fromEnd = false) {
      let pos = 0, 
          sel = window.getSelection(); 
      if (sel.rangeCount) {
        let rng = sel.getRangeAt(0); 
        if (rng.commonAncestorContainer.parentNode === el) {
          pos = !fromEnd ? rng.endOffset : 
            el.textContent.length - rng.endOffset; 
        }
      }
      return pos; 
    }
    
    function setCaretPosCe(el, pos, fromEnd = false) {
      let sel = window.getSelection(),
          rng = document.createRange();  
      if (fromEnd)
        pos = Math.max(0, el.textContent.length - pos); 
      else
        pos = Math.min(pos, el.textContent.length); 
      rng.setStart(el.childNodes[0], pos); 
      rng.collapse(true); 
      sel.removeAllRanges(); 
      sel.addRange(rng); 
    }
    #container {
      display: flex; 
      justify-content: space-around; 
      margin: 25vh 10vw; 
    }
    
    .cbtn-combobox, 
    #cbtn-table td {
      background-color: #fff; 
      font: 16px monospace; 
    }
    
    .cbtn-combobox {
      --btn-width: 20px; 
      width: calc(3ch + var(--btn-width) * 2 + 24px); 
      display: inline-flex; 
      line-height: 1.8em; 
      text-align: center; 
      border: 1px solid #ccc; 
    }
    
    .cbtn-combobox:before,
    .cbtn-combobox:after {
      display: inline-block; 
      flex: 0 0 var(--btn-width); 
      background-color: #eee; 
      cursor: pointer; 
      visibility: hidden; 
    }
    .cbtn-combobox:before { content: '-'; margin-right: auto; }
    .cbtn-combobox:after  { content: '+'; margin-left: auto; }
    
    .cbtn-combobox:focus:before,
    .cbtn-combobox:focus:after,
    .cbtn-combobox:hover:before,
    .cbtn-combobox:hover:after {
      visibility: visible; 
    }
    
    #cbtn-table {
      position: absolute; z-index: 99;
      border-collapse: collapse; 
      background-color: #eee; 
      box-shadow: 0 2px 5px 0 #0002; 
      visibility: hidden; 
    }
    
    #cbtn-table td {
      width: calc(3ch + 10px); 
      line-height: 1.8em; 
      text-align: center; 
      border: 1px solid #ccc; 
    }
    <div id="container">
      <div class="cbtn-combobox" data-table="6,212,18|24,30,36">42</div>
      <div class="cbtn-combobox" data-table="5,10,25,50 | 100,,,500 | 600,700,800,900">123</div>
      <div class="cbtn-combobox" data-table="1, 2, 3 | 10">1</div>
    </div>


    加上一个选项,一个自定义“输入”表:

    var $d = document; 
    
    $d.addEventListener('DOMContentLoaded', () => {
      let tds = $d.getElementsByClassName('cbtn-table-td'); 
      for (let td of tds) {
        td.addEventListener('click', onTdClick); 
        td.addEventListener('input', onTdInput); 
        td.contentEditable = true; 
      }
      console.log('Кнопки показываются при наведении на ячейку')
    });
    
    function onTdInput(e) {
      let cPos   = getCaretPosCe(this, true),
          newVal = +(this.textContent.match(/\d/g) || [0]).join(''); 
      this.textContent = Math.min(999, newVal); 
      setCaretPosCe(this, cPos, true); 
    }
    
    function onTdClick(e) {
      let cs   = getComputedStyle(this), 
          btnW = parseInt(cs.getPropertyValue('--btn-width')),
          mX   = e.clientX - this.getBoundingClientRect().left, 
          crrVal = parseInt(this.textContent) || 0, 
          newVal = null; 
      newVal = (mX < btnW) ? --crrVal :
        (mX > this.offsetWidth - btnW) ? ++crrVal : null; 
      if (newVal !== null) {
        this.textContent = Math.max(0, newVal); 
        setCaretPosCe(this, 0, true); 
      }
    }
    
    function getCaretPosCe(el, fromEnd = false) {
      let pos = 0, 
          sel = window.getSelection(); 
      if (sel.rangeCount) {
        let rng = sel.getRangeAt(0); 
        if (rng.commonAncestorContainer.parentNode === el) {
          pos = !fromEnd ? rng.endOffset : 
            el.textContent.length - rng.endOffset; 
        }
      }
      return pos; 
    }
    
    function setCaretPosCe(el, pos, fromEnd = false) {
      let sel = window.getSelection(),
          rng = document.createRange();  
      if (fromEnd)
        pos = Math.max(0, el.textContent.length - pos); 
      else
        pos = Math.min(pos, el.textContent.length); 
      rng.setStart(el.childNodes[0], pos); 
      rng.collapse(true); 
      sel.removeAllRanges(); 
      sel.addRange(rng); 
    }
    .cbtn-table {
      --btn-width: 20px; 
      --td-width: calc(3ch + var(--btn-width) * 2 + 8px); 
      font: 16px monospace; 
    }
    
    .cbtn-table-tr, 
    .cbtn-table-td {
      margin: 0; padding: 0;
    }
    
    .cbtn-table-tr {
      display: flex; 
      line-height: 1.8em; 
      padding: 0; margin-top: -1px; 
      white-space: nowrap; 
    }
    .cbtn-table-td:first-child {
      margin: 0;
    }
    
    .cbtn-table-td {
      display: inline-flex; 
      min-width: var(--td-width); 
      margin-left: -1px; 
      text-align: center; 
      border: 1px solid #ccc; 
    }
    .cbtn-table-td:first-child {
      margin: 0;
    }
    
    .cbtn-table-td:before,
    .cbtn-table-td:after {
      display: inline-block; 
      flex: 0 0 var(--btn-width); 
      cursor: pointer; 
      visibility: hidden; 
    }
    .cbtn-table-td:before { content: '-'; margin-right: auto; }
    .cbtn-table-td:after  { content: '+'; margin-left: auto; }
    
    .cbtn-table-td:hover:before,
    .cbtn-table-td:hover:after {
      visibility: visible; 
      background-color: #ddd; 
    }
    <div class="cbtn-table">
      <div class="cbtn-table-tr">
        <div class="cbtn-table-td">6</div>
        <div class="cbtn-table-td">212</div>
        <div class="cbtn-table-td">18</div>
      </div>
      <div class="cbtn-table-tr">
        <div class="cbtn-table-td">24</div>
        <div class="cbtn-table-td">30</div>
        <div class="cbtn-table-td">36</div>
      </div>
    </div>


    代码远非跨浏览器,这些只是示例。

    • 0

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5