JavaScript 点击输入框事件

3

绑定项目列表上的单击事件时,框会一直消失。有任何想法为什么在item-list > div上单击事件无效。

想法是获取被点击的文本(来自item-list)并将其放入输入字段中?

(function() {
  $(".input-msg").focus(function() {
    $(".item-list").css('display', 'block');
    $(".item-list div").click(function() {
      var inputValue = $('.input-msg');
      var data = $(this).text();
      inputValue.val(data);
    });
  }).blur(function() {
    $(".item-list").css('display', 'none');
  });
})();
.input-wrapper {
  width: 300px;
}

.item-list {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="input-wrapper">
  <input type="text" class="input-msg" placeholder="click me">
  <!-- input msg -->
  <div class="item-list">
    <div>This is item one</div>
    <div>This is item one</div>
    <div>This is item one</div>
    <div>This is item one</div>
  </div>
</div>


1
你的问题不清楚?你到底想要实现什么?你遇到了什么问题? - Alive to die - Anant
1
请解释一下你想做什么,因为从你的代码中,我仍然不确定你想做什么。 - Raymond Seger
不要在焦点处理程序中附加点击侦听器,否则每次元素获得焦点时都会添加一个新的侦听器。 - Teemu
点击项目列表时,它不会插入文本,点击函数无法工作?同时,在单击页面主体时隐藏项目列表。 - webmansa
4个回答

3
我想我理解了你的问题:
1. 删除 blur 代码。(因为它会在焦点从输入框移开时立即隐藏 div) 2. 将 click 放在 focus 外面。(只注册一次监听器就足够了) 3. 在 click 内部执行 hide 代码。(如果你想在点击文本 div 后隐藏 div) 工作示例:

(function() {
  $(".input-msg").focus(function() {
    $(".item-list").css('display', 'block');
    
  });
  $(".item-list div").click(function() {
      var inputValue = $('.input-msg');
      var data = $(this).text();
      inputValue.val(data);
      $('.item-list').hide();
  });
})();
$(document).mouseup(function(e) {
  if (!$(e.target).is('.item-list') && !$(e.target).is('.input-msg')) {
    $('.item-list').hide(1000);
  }
});
.input-wrapper {
  width: 300px;
}

.item-list {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="input-wrapper">
  <input type="text" class="input-msg" placeholder="click me">
  <!-- input msg -->
  <div class="item-list">
    <div>This is item one</div>
    <div>This is item Two</div>
    <div>This is item Three</div>
    <div>This is item Four</div>
  </div>
</div><br>


点击 div 外部时,不隐藏 div 容器,有什么想法为什么? - webmansa

1
项目列表消失了,因为在输入框触发的模糊事件上,列表被清除了。我已经注释掉了隐藏列表的代码,并将其移动到项目列表点击时发生。
我还将列表点击处理程序从您的模糊处理程序中移出。这将防止点击处理程序一遍又一遍地被安装。

(function() {
  $(".input-msg").focus(function() {
    $(".item-list").css('display', 'block');

  }).blur(function() {
 
    // THIS IS YOUR ISSUE.
    // We're going to move this line down to the 
    // `item-list` click handler.
    // $(".item-list").css('display', 'none');

  });

  // You want to register this listener once,
  // not every time user focuses on input box.
  $(".item-list div").click(function() {
    var inputValue = $('.input-msg');
    var data = $(this).text();
    inputValue.val(data);
  });

  $('.main-wrapper').children().not('.input-wrapper').click(function(){
    // Hide the item list on body click.
    // This was moved here from the `blur` handler above.
    $(".item-list").css('display', 'none');
  });

})();
.main-wrapper {
  float: left;
  width: 600px;
}
  
.other-wrapper {
 float: left;
 width: 300px;
}

.input-wrapper {
  float: left;
  width: 300px;
}

.item-list {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main-wrapper">
<div class="input-wrapper">
  <input type="text" class="input-msg" placeholder="click me">
  <!-- input msg -->
  <div class="item-list">
    <div>This is item one</div>
    <div>This is item one</div>
    <div>This is item one</div>
    <div>This is item one</div>
  </div>
</div>
<div class="other-wrapper">Other stuff.</div>
<div>


失去焦点时,我也想隐藏项目列表? - webmansa
我的意思是,在页面的任何地方点击后,隐藏item-list div。你明白吗? - webmansa
我认为是这样的,现在试一下。 - Ezra Chu

1
请看这个。

(function() {
  $(".item-list div").click(function() {
    var inputValue = $('.input-msg');
    var data = $(this).text();
    inputValue.val(data);
    $('.item-list').fadeOut('fast');
  });
  $(".input-msg").focus(function() {
    $(".item-list").fadeIn('fast');        
  })
  $(document).mouseup(function(e) {
    if (!$(e.target).is('.item-list') && !$(e.target).is('.input-msg')) {
      $('.item-list').fadeOut('fast');
    }
  });
})();
.input-wrapper {
  width: 300px;
}

.item-list {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="input-wrapper">
  <input type="text" class="input-msg" placeholder="click me">
  <!-- input msg -->
  <div class="item-list">
    <div>This is item one</div>
    <div>This is item two</div>
    <div>This is item three</div>
    <div>This is item four</div>
  </div>
</div>


1
@Webmansa 和 Kira San,为什么在focus事件处理程序中再次使用$(".item-list div").click(function() {?每次聚焦到元素上都注册侦听器真的是一种不好的做法。将其移到外面。我们已经在我们的答案中提到了这一点。 - Alive to die - Anant
@AlivetoDie 感谢您指出这个问题,我匆忙之间没有注意到。 - Ikbel
@KiraSan 现在答案完美无缺了。所以+1。 - Alive to die - Anant

0
const input = $("input")
const itemList = $(".item-list")
const items = $(".item-list > div")
const overlay = $(".overlay")

addClickTo(input, () => display(itemList, overlay))
addClickTo(items, (e) => {
  const itemText = e.currentTarget.textContent
  setValueOf(input, itemText)
  dontDisplay(itemList, overlay)
})
addClickTo(overlay, () => dontDisplay(itemList, overlay))


// helpers
function dontDisplay(...elements) { elements.forEach((element) => element.style.display = "none") }
function display(...elements) { elements.forEach((element) => element.style.display = "block") }
function $(selector) {
  const matchedElements = document.querySelectorAll(selector)
  return matchedElements && matchedElements.length > 1
  ? matchedElements
  : matchedElements[0]
}
function addClickTo(elements, handler) {
  elements.forEach || (elements = [elements])
  elements.forEach((element) => element.addEventListener("click", handler))
}
function setValueOf(input, text) {
    input.value = text
}

const input = $("input")
const itemList = $(".item-list")
const items = $(".item-list > div")
const overlay = $(".overlay")

addClickTo(input, () => display(itemList, overlay))
addClickTo(items, (e) => {
  const itemText = e.currentTarget.textContent
  setValueOf(input, itemText)
  dontDisplay(itemList, overlay)
})
addClickTo(overlay, () => dontDisplay(itemList, overlay))


// helpers
function dontDisplay(...elements) { elements.forEach((element) => element.style.display = "none") }
function display(...elements) { elements.forEach((element) => element.style.display = "block") }
function $(selector) {
  const matchedElements = document.querySelectorAll(selector)
  return matchedElements && matchedElements.length > 1
  ? matchedElements
  : matchedElements[0]
}
function addClickTo(elements, handler) {
  elements.forEach || (elements = [elements])
  elements.forEach((element) => element.addEventListener("click", handler))
}
function setValueOf(input, text) {
 input.value = text
}
.item-list {
  display: none;
  position: relative;
  cursor: pointer;
}

input {
  position: relative;
}

.overlay {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
<div class="input-wrapper">
  <div class="overlay"></div>
  <input type="text" class="input-msg" placeholder="click me">

  <!-- input msg -->
  <div class="item-list">
    <div>This is item one</div>
    <div>This is item two</div>
    <div>This is item three</div>
    <div>This is item four</div>
  </div>
</div>

https://jsfiddle.net/dvekrebv/6/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接