【项目】实现网页搜索框功能

一、实现搜索框的部分代码

【注:涉及api接口和中后台数据交互】
1. 最终呈现形式:
在这里插入图片描述
2. 代码实现:
HTML文件中:

<!--  搜索框部分 -->
      <div class="search-bar"  fxFlexAlign="center" style=" margin: 0 auto;max-width: 700px;">
        <div ngbDropdown fxLayout="row"
             style="border: none;padding: 0;margin: 0;width: 100%;">
            <button class="out-btn" id="dropdownBasic1" ngbDropdownToggle  fxFlex=18
                    style="border: none;margin-bottom: 7px;background-color: #fff;height: 36px;">
                    易出
            </button>
            <div ngbDropdownMenu aria-labelledby="dropdownBasic1" style="width: 100%;" >
                <ul class="history" fxLayout="column">
                    <li class="history-title">
                      最近搜索<button (click)="deleteHistory()" class="delete-all-btn" >清除</button>
                    </li>
                    <li  *ngFor="let item of historyList;let key=index;">
                        <a (click)="doSearch1(item)">{{item}}<button (click)="deleteOneHistory(key)" class="delete-btn"><i class="material-icons">remove_circle_outline</i></button></a>
                    </li>
                </ul>
            </div>
            <input  class="searcch-inp" type="text" [(ngModel)]="model" [ngbTypeahead]="search" [resultFormatter]="formatter" fxFlex
                   (keyup)="doAdd($event)" placeholder="{{ 'product-list.title3' | translate }}">
            <button class="search-btn" fxFlex="30 1 1" (click)="doSearch()" (click)="doStorage()">
                <i class="material-icons">search</i>搜索
            </button>
        </div>
      </div>

TS文件中:

export class ProductListComponent implements OnInit {
  //图片懒加载
  defaultImage = '../../../assets/img/ebarter.jpg';
  protected:any;
  rprice:any=[];
  price:any=[];
  title:any=[];
  rtitle:any=[];
  local:any=[];
  rlocal:any=[];
  bgPictrue:any=[];
  bgPictrue_raw:any=[];
  bgPictrue_rep:any=[];
  bgPictrue_str:any=[];
  bgPictrue_r:any=[];
  bgPictrue_raw_r:any=[];
  bgPictrue_rep_r:any=[];
  bgPictrue_str_r:any=[];
  awsImgUrl:string = 'https://s3.cn-north-1.amazonaws.com.cn/linda-trades-archive-1/';
  public list:any;
  //声明新的对象数组
  public productList:any=[];
  public currentPage:any;

  public rlist:any;
  public pObj:any=[];
  public temp:any=[];
  //搜索商品
  price_s:any=[];
  title_s:any=[];
  local_s:any=[];
  rlocal_s:any=[];
  bgPictrue_s:any=[];
  bgPictrue_raw_s:any=[];
  bgPictrue_rep_s:any=[];
  bgPictrue_str_s:any=[];
  public pObj_s:any=[];
  //搜索商品的定义
  public slist:any;
  //声明新的对象数组
  public searchList1:any=[];

  //2.搜索提示数组
  states:any= [];
  //3.定义属性进行双向数据绑
  public model: any;
  public historyList:any=[]; //定义的数组,存储输入的值

 //3.使用服务,实例化,即初始化
    // 初始化路由
  constructor(
    private product:ProductService,
    private storageServe: StorageService,
    private sanitizer:DomSanitizer,
    public storage:StorageService,
    private route: ActivatedRoute,
    private router: Router,
    private homeService: HomeService,
    //搜索框
    private http: HttpClient,
    @Inject(API_CONFIG) private uri: string,
    ) { }

  ngOnInit(): void {
    //数据持久化
    console.log('页面刷新会触发这个生命周期函数');
    var searchlist:any=this.storage.get('searchlist');
    if(searchlist){
      this.historyList=searchlist;
    }

    //获得产品列表
    this.product.productlist().subscribe(product => {
      console.log('productlist',product);
      var re = /:/gi;
      this.list = product;
      this.list= this.list.filter(function(item){
        return JSON.parse(item.content.toString()).isOnSale == 'yes';
   })
      var listLength = this.list.length;
      var userID = this.storageServe.getStorage('UserID');
      for(var i = 0;i<listLength;i++){
        this.pObj[i] = JSON.parse(this.list[i].content.toString());
        this.title.push(this.pObj[i].supplierAds[0].m_title);
        this.price.push(this.pObj[i].supplierAds[0].m_price);
        this.local.push(this.pObj[i].supplierAds[0].m_supplierInfo.region);
        this.bgPictrue_raw.push(this.pObj[i].supplierAds[0].m_supplierOrderId);
        this.bgPictrue_rep[i] = this.bgPictrue_raw[i].replace(re,"-");
        this.bgPictrue_str[i] = this.awsImgUrl + this.bgPictrue_rep[i] + '1000.jpg';
        this.bgPictrue.push(this.bgPictrue_str[i])
      }
      console.log(111,this.title)
  //重新创建一含对象的数组,把原来的各个属性的数组动态循环进新数组的对象里
      //console.log(11,this.pObj[0])
      for(let i=0;i<this.local.length;i++){
          var item = {//创建新数组的对象属性
            bgPictrue: '',
            local: '',
            price: '',
            title: '',
            id: 0
          }
          //对对象属性进行实例化赋值
          item.bgPictrue = this.bgPictrue[i];
          item.local = this.local[i];
          item.price = this.price[i];
          item.title = this.title[i];
          item.id = this.list[i].id;
        //动态循环进数组里
        //全部商品列表
        this.productList.push(item);
        }

    //2.给搜索提示数组赋值
    for(var i = 0;i<this.title.length;i++){
      this.states[i] = this.title[i];
    }

    this.searchList1=this.productList;

    })

  }
  // 自定义方法

//1.改变页码触发的事件
  onPageChange(number: number){
    this.currentPage = number;
  }
  //2.关闭广告条
  public flag:boolean=false;
  close(){
    this.flag=true;
  }
  // 3.搜索框提示功能
  formatter = (result: string) => result.toUpperCase();
  search = (text$: Observable<string>) =>
    text$.pipe(
      debounceTime(200),
      distinctUntilChanged(),
      map(term => term === '' ? []
        : this.states.filter(v => v.toLowerCase().indexOf(term.toLowerCase()) > -1).slice(0, 10))
    )

  //4.搜索框历史记录显示和数据持久化方法
      //4.1 搜索函数
      //在搜素框里调用的搜索函数
      doSearch(){
        //console.log("输入的搜索词:",this.model);
      if(this.model == ''){
          this.price_s=[];
          this.title_s=[];
          this.local_s=[];
          this.bgPictrue_s=[];
          this.bgPictrue_raw_s=[];
          this.bgPictrue_rep_s=[];
          this.bgPictrue_str_s=[];
          this.searchList1=[];
          this.searchList1=this.productList;
      }else{
          this.price_s=[];
          this.title_s=[];
          this.local_s=[];
          this.bgPictrue_s=[];
          this.bgPictrue_raw_s=[];
          this.bgPictrue_rep_s=[];
          this.bgPictrue_str_s=[];
          this.searchList1=[];
        var temp = {parameters: {keyWord: this.model}}
          return this.http.get(this.uri + 'Product/Search?keyWord=' + JSON.stringify(temp)).subscribe(search => {
          this.slist = search;
          //console.log('slist搜索数组:',this.slist)
          var re = /:/gi;
          for(var i = 0;i< this.slist.length;i++){
              //把json字符串转成对象
                  this.pObj_s[i] = JSON.parse(this.slist[i].content.toString());
                  this.title_s.push(this.pObj_s[i].supplierAds[0].m_title);
                  this.price_s.push(this.pObj_s[i].supplierAds[0].m_price);
                  this.local_s.push(this.pObj_s[i].supplierAds[0].m_supplierInfo.region);
                  this.bgPictrue_raw_s.push(this.pObj_s[i].supplierAds[0].m_supplierOrderId);
                  this.bgPictrue_rep_s[i] = this.bgPictrue_raw_s[i].replace(re,"-");
                  this.bgPictrue_str_s[i] = this.awsImgUrl + this.bgPictrue_rep_s[i] + '1000.jpg';

                  for(let i=0;i<this.local_s.length;i++){
                  var item = {
                    bgPictrue: '',
                    local: '',
                    price: '',
                    title: '',
                    id: 0
                  }
                  item.bgPictrue = this.bgPictrue_str_s[i];
                  item.local = this.local_s[i];
                  item.price = this.price_s[i];
                  item.title = this.title_s[i];
                  item.id = this.slist[i].id;
                  this.searchList1.push(item);
                }
        }
        //console.log("输入的搜索词:",this.model);
      })
    }
  }
  //在历史记录里调用的搜索函数
      doSearch1(model:string){
        //console.log("输入的搜索词:", model);
          this.price_s=[];
          this.title_s=[];
          this.local_s=[];
          this.bgPictrue_s=[];
          this.bgPictrue_raw_s=[];
          this.bgPictrue_rep_s=[];
          this.bgPictrue_str_s=[];
          this.searchList1=[];
        var temp = {parameters: {keyWord: model}}
            return this.http.get(this.uri + 'Product/Search?keyWord=' + JSON.stringify(temp)).subscribe(search => {
          this.slist = search;
          //console.log('slist搜索数组:',this.slist)
          var re = /:/gi;
          for(var i = 0;i< this.slist.length;i++){
              //把json字符串转成对象
                  this.pObj_s[i] = JSON.parse(this.slist[i].content.toString());
                  this.title_s.push(this.pObj_s[i].supplierAds[0].m_title);
                  this.price_s.push(this.pObj_s[i].supplierAds[0].m_price);
                  this.local_s.push(this.pObj_s[i].supplierAds[0].m_supplierInfo.region);
                  this.bgPictrue_raw_s.push(this.pObj_s[i].supplierAds[0].m_supplierOrderId);
                  this.bgPictrue_rep_s[i] = this.bgPictrue_raw_s[i].replace(re,"-");
                  this.bgPictrue_str_s[i] = this.awsImgUrl + this.bgPictrue_rep_s[i] + '.jpg';

                  for(let i=0;i<this.local_s.length;i++){
                  var item = {
                    bgPictrue: '',
                    local: '',
                    price: '',
                    title: '',
                    id: 0
                  }
                  item.bgPictrue = this.bgPictrue_str_s[i];
                  item.local = this.local_s[i];
                  item.price = this.price_s[i];
                  item.title = this.title_s[i];
                  item.id = this.slist[i].id;
                  this.searchList1.push(item);
                }
        }
        //console.log("输入的搜索词:", model);
      })
    }


     //4.2 存储函数
      doStorage(){
        //if语句检查输入的值在列表中是否存在,如果=-1说明不存在,则需要push进去
        if(this.historyList.indexOf(this.model)==-1 && this.model!=''){
          this.historyList.push(this.model);//理解push是什么意思
        }
        //自动清空搜索框里填入的内容
          this.model='';
        //获取属性的值
          console.log(this.model);
        //缓存数据,实现数据持久化
        this.storage.set('searchlist',this.historyList);
      }

    //4.3 接听回车事件,一按回车就把输入的内容push到列表中(此方法暂时不用)
    //了解对象怎么表示
      doAdd(e){
        if (e.keyCode==13) { //这里判断数据是否存在不可行,如果是一个对象,所以需要封装一个方法
          if(!this.historyListHasKeyword(this.historyList,this.model)){
          this.historyList.push(this.model)
          this.model='';
      }else{
        this.model='';
      }
    }
    //缓存数据,实现数据持久化
    this.storage.set('searchlist',this.historyList);//用到this一定要注意this的指向
  }
    //封装方法
    //如果数组里面有keyword返回true,否则返回false
      historyListHasKeyword(historyList:any,model:any){
        //用异步存在问题,所以用另一种方法,用到for循环
          if (!model) return false;
          for (var i=0;i<historyList.length;i++) {
            if (historyList[i]==model) {
              return true;
            }
          }
        return false;
      }

    //4.4 删除单个历史记录函数
      deleteOneHistory(key){
        this.historyList.splice(key,1);//splice可以在数组里删除,增加,修改一个值。在这里表示从key位置往后删除一个值。
        this.storage.set('searchlist',this.historyList);
      }
    //4.5 一次性删除历史记录
    deleteHistory(){
      alert("删除全部历史记录?")
      this.historyList.splice(0,this.historyList.length);//splice可以在数组里删除,增加,修改一个值。在这里表示从key位置往后删除一个值。
      this.storage.set('searchlist',this.historyList);
    }


}

CSS文件中:

/*  搜索框部分 */
    /* 设置搜索框的容器 */
      .search-bar{
        /* max-width: 400px; */
        height: 40px;
        background-color:#bbb;
        border: 2px solid  rgb(0, 99, 186) ;
      }
    /* 搜索文本框 */
      .search-bar .searcch-inp{
              min-width: 100px;
              /* min-width: 150px; */
              height: 36px;
              /* 去掉边框 */
              border: none;
              color:rgb(121, 121,121);
          }
    /* 易出按钮 */
       .search-bar .out-btn{
              color: rgb(0, 99, 186);
          }
    /* 搜索按钮 */
       .search-bar .search-btn{
              min-width: 100px;
              /* min-width: 120px; */
              height: 38px;
              padding: 0;
              border: none;
              color: #fff;
              background:rgb(0, 99, 186);
              text-align: center;
          }
       .search-bar .search-btn:hover{
              background:rgb(4, 51, 92);
          }
    /* 搜索图标样式 */
        .search-bar .search-btn .material-icons{
              vertical-align:bottom;
              margin-bottom: -1px;
              margin-right: 7px;
          }
    /* 清除整个历史记录按钮样式*/
        .search-bar .delete-all-btn{
              float: right;
              margin-right: 20px;
              color: rgb(0, 99, 186);
              background-color: #fff;
              border: none;
              font-weight: bold;
          }
  /* 清除单个历史记录按钮样式*/
        .search-bar .delete-btn{
              float: right;
              margin-right: 20px;
              background-color: #fff;
              color: rgb(112, 112, 112);
              border: none;
              padding: 0;
              width: 20px;
              height: 20px;
          }
        .search-bar .delete-btn .material-icons{
              vertical-align:bottom;
              color: rgb(202,202, 202);
          }
  /* 下拉框的列表样式 */
        .search-bar li{
              color:rgb(121, 121,121);
              font-size: 13px;
              line-height: 25px;
          }
        .search-bar .history-title{
              color:rgb(0, 99, 186);
              font-size: 18px;
              font-weight: bold;
              margin-bottom: 10px;
          }
        .search-bar ul{
              margin-left: 20px;
              margin-top: 15px;
          }


二、参考资料:

1. input搜索框实时检索功能实现(超简单,核心原理请看思路即可):https://blog.csdn.net/qq_39974331/article/details/80410032
2. 前端和中后台的数据交互(用到json数据)
参考资料如下:
「前端」Angular 中的数据交互(get jsonp post):https://zhuanlan.zhihu.com/p/147852215
angular2——前后端交互:http://www.voidcn.com/article/p-aiycehtq-bms.html
3. 需要熟练使用API接口
4. 搜索框搜索时候的搜索值存储问题,以及需要点击两次搜索按钮才能在前端页面显示搜索的商品(存在异步问题)
参考资料——面试精选之Promise:https://juejin.cn/post/6844903625609707534


三、后续完善搜索框功能

1.前端搜索模糊搜索提示框:
功能参考链接:https://material.angular.io/components/autocomplete/examples

2.搜索框按照商品标题进行搜索:
使用indexof函数进行筛选;

  • 6
    点赞
  • 110
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以考虑使用常见的前端框架,如React、Vue或Angular,配合后端框架,如Node.js、Django或Flask,来构建一个完整的网页项目框架。此外,还可以考虑使用UI框架,如Bootstrap或Material UI,来提高网页的美观度和用户体验。 ### 回答2: 给你一个网页项目的框架,可以使用以下几个主要组件: 1. 前端框架:可以选择流行的前端框架如React、Angular或Vue.js。通过这些框架可以构建出良好的用户界面,并提供数据驱动和组件化的开发方式。 2. 后端开发框架:可以选择Node.js的Express框架或Python的Django框架。这些框架能够提供强大的后端功能,包括路由管理、数据库访问、用户认证和API开发等。 3. 数据库:可以选择关系型数据库如MySQL或PostgreSQL,或者非关系型数据库如MongoDB或Redis。根据项目需求选择适合的数据库来存储和管理数据。 4. 服务器:可以选择云服务提供商如AWS、Azure或Google Cloud Platform,或者自建服务器。配置服务器环境,将网页项目部署到服务器上进行访问。 5. 前端UI库:可以选择Bootstrap或Material-UI等,这些库提供了丰富的CSS样式和响应式设计,使网页在不同设备上都能有良好的显示效果。 6. 权限认证与安全:可以使用JWT(JSON Web Token)来实现用户身份验证和授权,确保只有授权用户才能访问网页的敏感信息。 7. 版本控制:使用Git进行版本控制,通过GitHub或GitLab等平台来管理项目的代码和版本。 以上是一个基本的网页项目框架,根据项目的具体需求和规模,还可以根据需要引入其他组件和技术。在开发过程中,注意良好的代码规范和架构设计,结合项目需求,使得网页项目能够高效、稳定地运行。 ### 回答3: 当设计和开发一个网页项目时,一个基本的框架可以包括以下几个关键点: 1. 网站结构和导航:首先确定网站的整体结构,包括页面的层次结构和导航方式。可以考虑使用导航栏、面包屑导航或侧边栏等方式来帮助用户浏览网站。 2. 布局和排版:确定网页的整体布局,例如使用栅格系统等方式来划分不同部分的位置和大小。此外,还需要考虑页面元素的排版和对齐方式,使得整体页面具有良好的视觉层次和可读性。 3. 色彩和样式:选择合适的色彩搭配和配色方案,确保网页的视觉效果美观和一致。还可以定义统一的字体和文字样式,以及按钮、链接等交互元素的样式,提升用户体验。 4. 图片和多媒体:根据项目需求,考虑合适的图片和多媒体元素的使用。可以使用优化后的图片来提升加载速度,同时确保多媒体元素的自适应性和可访问性。 5. 响应式设计:确保网页在不同设备和屏幕尺寸下的自适应性。使用CSS媒体查询来针对不同屏幕尺寸应用不同的样式和布局,以确保用户在不同设备上都可以获得良好的使用体验。 6. 浏览器兼容性:在开发过程中,需要考虑各类浏览器的兼容性。使用渐进增强和优雅降级的策略,在保证基本功能可用的同时,尽可能提供更好的用户体验。 7. SEO优化:优化网页的代码结构和内容,以提高搜索引擎对网站的收录和排名。使用合适的标签、关键词等,确保网页具备良好的搜索可见性。 总之,一个网页项目的框架应该从网站结构和导航开始,考虑布局、样式、多媒体、响应式设计、浏览器兼容性和SEO优化等方面,以构建出用户友好、功能完备且高性能的网站。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值