每当我开始输入时,如何添加禁用的搜索图标?

How can I add disabled search icon, whenever I start typing?

如何在搜索栏左侧添加禁用的搜索图标,就像我们开始输入时 google 在其搜索栏中使用的那样。

google 搜索图标显示在焦点上,而不是在输入更改时。它也会隐藏在模糊中。 要复制该行为,请向输入添加 focusblur 事件侦听器。

<input type="text" id="myinput" />

const myInput = document.getElementById("myinput");
myInput.addEventListener("focus", toggleSearchIcon);
myInput.addEventListener("blur", toggleSearchIcon);

function toggleSearchIcon() {
    // code to show/hide the icon
}

如果您想等待用户输入内容,请向输入添加一个 change 事件侦听器,并在输入值的长度更大时显示图标比 0.

<input type="text" id="myinput" />

const myInput = document.getElementById("myinput");
myInput.addEventListener("change", toggleSearchIcon);

function toggleSearchIcon(e) {
    const shouldShowSearchIcon = e.target.value.length > 0;
    // code to show/hide the icon
}

您可以使用 CSS 和 focus-within

来显示和隐藏它

.search-bar {
  position: relative;
}

.search-bar label {
  display: none;
  font-size: 12px;
  position: absolute;
  top: 2px;
  left: 5px;
  color: #999;
}

.search-bar:focus-within label {
  display: inline-block;  
}

.search-bar input {
  padding-left: 20px;
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<span class="search-bar">
  <label for="search"><i class="fa fa-search"></i></label>
  <input tpe="text" id="search"/>
 </span>

或有焦点

.search-bar {
  position: relative;
}

.search-bar label {
  display: none;
  font-size: 12px;
  position: absolute;
  top: 2px;
  left: 5px;
  color: #999;
}

.search-bar input:focus + label {
  display: inline-block;  
}

.search-bar input {
  padding-left: 20px;
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<span class="search-bar">
  <input tpe="text" id="search"/>
  <label for="search"><i class="fa fa-search"></i></label>
 </span>

如 nip 所述,您可以在搜索组件上添加 focus/blur 个事件。

下面的插件会将所有 .search-bar 包装器 DOM 元素转换为搜索栏“组件”,这些组件将监听焦点和模糊以添加或删除焦点 class。

const main = () => {
  new SearchBarManager({
    /*
     * If false, the search icon will be hidden,
     * but it will remain as-is in the DOM.
     */
    collapse: true /* default */
  });
};

class ComponentManager {
  constructor() {
    this._listeners = {};
  }

  _addListeners(selector, listeners) {
    for (let listener in listeners) {
      this._listeners[listener] = function(e) {
        listeners[listener].call(this, e);
      }.bind(this)
    }
    [...document.querySelectorAll(selector)].forEach(el => {
      for (let listener in listeners) {
        el.addEventListener(listener, this._listeners[listener], true);
      }
    });
  }
  
  _removeListeners(selector, listeners) {
    [...document.querySelectorAll(selector)].forEach(el => {
      listeners.forEach(listener => {
         el.removeEventListener(listener, this._listeners[listener], true);
      });
    });
    listeners.forEach(listener => {
       delete this._listeners[listener];
    });
  }
}

class SearchBarManager extends ComponentManager {
  constructor(options) {
    super();
    let opts = { ...SearchBarManager.defaultOptions, ...options };
    this.className = opts.className;
    this.focusClassName = opts.focusClassName;
    this.collapse = opts.collapse;
    this.init();
  }
  
  onSearchFocus(e) {
    this._toggleSearchIcon(e.currentTarget, true);
  }

  onSearchBlur(e) {
    this._toggleSearchIcon(e.currentTarget, false);
  }
  
  init() {
    this._addListeners(`.${this.className}`, {
      focus: this.onSearchFocus,
      blur: this.onSearchBlur
    })
  }
  
  destroy() {
    this._removeListeners(`.${this.className}`, [ 'focus', 'blur' ])
  }

  _toggleSearchIcon(search, show) {
    search.classList.toggle(this.focusClassName, show);
    if (this.collapse) {
      search.classList.toggle(`${this.focusClassName}-collapse`, show);
    }
  }
}
SearchBarManager.defaultOptions = {
  className: 'search-bar',
  focusClassName: 'search-focused',
  collapse: false
};

main();
:root {
  --search-bar-outline: #BBB;
  --search-bar-shadow: #DDD;
}

hr {
  border: none;
  margin: 0.5em;
}

.search-bar {
  display: flex;
  flex-direction: row;
  border: thin solid var(--search-bar-outline);
  padding: 0.667em;
  border-radius: 1.33em;
}

.search-bar:hover {
  box-shadow: 0 0 0.25em var(--search-bar-shadow);
}

.search-bar input[type="search"] {
  border: none;
  flex: 1;
  margin-left: 0.25em;
}

.search-bar input[type="search"]:focus {
  outline: none;
}

.search-bar .fa-search {
  color: var(--search-bar-outline);
}

.search-bar.search-focused .fa-search {
  visibility: hidden;
}

.search-bar.search-focused.search-focused-collapse .fa-search {
  display: none;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" rel="stylesheet"/>

<div class="search-bar">
  <i class="fas fa-search"></i>
  <input type="search" placeholder="Search...">
</div>

<hr />

<div class="search-bar">
  <i class="fas fa-search"></i>
  <input type="search" placeholder="Search...">
</div>

更新: 我喜欢 Epascarello 的 CSS-only 方法,所以我稍微修改了它。

看来 :focus-within 目前所有的浏览器都支持。

.search-bar {
  display: flex;
  flex-direction: row;
  border: thin solid #999;
  border-radius: 1em;
  padding: 0.5em;
}

.search-bar .fa-search {
  color: #999;
  margin-right: 0.33em;
}

.search-bar:focus-within .fa-search {
  display: none;
}

.search-bar input {
  flex: 1;
  border: none;
}

.search-bar input:focus {
  outline: none;
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<span class="search-bar">
  <i class="fa fa-search"></i>
  <input type="search" />
</span>