【前端 HTML/JSX】在Input框内部加上Icon?除了使用Bootstrap、Semantic或Material

相信像下列的输入框需求,在前端开发的时候很容易遇到
http://img2.58codes.com/2024/20135750NExEwy3izI.png

菜鸟前端的第一直觉大概就会想要这样写... 把icon的部分直接放在 <input>里面

<input>    <svg/></input>

如果运气好一点,你写的是直接的html的话,会发现贴心的浏览器帮你变成这样
http://img2.58codes.com/2024/20135750ORlMZPzAkT.png

但是运气不好的话,或是写的是React的JSX的话,就会收到以下警讯,然后什么东西都没跑出来

Uncaught Error: input is a void element tag and must neither have children nor use dangerouslySetInnerHTML.

简单来说,<input>里面不能放子元素!

好der,所以到底该怎么做呢?
除了直接使用Boostrap、Semantic或Material提供的样板之外
其实HTML应该要拆成这样才对:
http://img2.58codes.com/2024/201357508NwYk2SKce.png

这边附上纯HTML的写法与使用React Hook 和Function Component的写法!

纯HTML写法

<div     style="        width: 200px;        height: 30px;        background: #FaFaFa 0% 0% no-repeat padding-box;        border: 1px solid #989898;        border-radius: 2px;        padding: 0px;        display: flex;        align-items: center;    ">    <input        style="            border: none;            outline: none;            background: #FaFaFa 0% 0%  padding-box;            margin: 0px 0px 0px 10px;            padding: 0px;            width: 162px;        "    />    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-search" viewBox="0 0 16 16"><path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z"></path></svg></div>

React写法

export function MySearchBar(){  const [searchBarValue, setSearchBarValue] = useState('');  function searchBarInputChangeHandler(event: React.ChangeEvent<HTMLInputElement>): void   {    setSearchBarValue(event.target.value);  }   const searchBarDivStyle: CSSProperties = {    width: '200px',    height: '30px',    background: '#FaFaFa 0% 0% no-repeat padding-box',    border: '1px solid #989898',    borderRadius: '2px',    padding: '0px',    display: 'flex',    alignItems: 'center',  }  const searchBarInputStyle: CSSProperties = {    border: 'none',    outline: 'none',    background: '#FaFaFa 0% 0% no-repeat padding-box',    margin: '0px 0px 0px 10px',    padding: '0px',    width: '162px'  }  return (      <div style={searchBarDivStyle}>        <input           style={searchBarInputStylr}           value={searchBarValue}           onChange={(event) => { searchBarInputChangeHandler(event); }}        />         <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-search" viewBox="0 0 16 16"><path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z"></path></svg>      </div>  );}

小结

<input>内不管是要包Icon,还是包按钮
都可以用<div>+CSS包装的方式来达成,也就是

外层 <div>:
border: 1px solid #989898; // 边框
border-radius: 2px; // 圆角
background: #FaFaFa; // 背景色
display: flex; // 方便内容可以用align-items定位
align-items: center; // 内容物置中内层 <input>:
border: none // 不要有任何边框
outline: none // input被foucs时不要有周围的蓝框
background: #FaFaFa; // 与外层一致的背景色内层 icon:
/* 看高兴怎么放、放哪里 */

假如还是不想自己刻,还是可以参考现成工具:
Bootstrap: https://getbootstrap.com/docs/4.0/components/input-group/
Semantic-UI: https://react.semantic-ui.com/elements/input/#input-example-action
Material-UI: https://material-ui.com/components/text-fields/

以上!


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章