Javascript 基于algolia自动完成场的聚焦事件检测

Javascript 基于algolia自动完成场的聚焦事件检测,javascript,autocomplete,algolia,Javascript,Autocomplete,Algolia,我的模板中有algolia autocomplete的输入: <form action="/search" method="get"> <div class="input-group"> <span class="input-group-addon"> <button type="submit" class="search-button"> <i cla

我的模板中有algolia autocomplete的输入:

     <form action="/search" method="get">
       <div class="input-group">
         <span class="input-group-addon">
           <button type="submit" class="search-button">
             <i class="ion-ios-search-strong"></i>
           </button>
         </span>
         <input type="text" name="q" class="search-input search-input-small-js form-control aa-input-search" placeholder="Search for players and videos ..." aria-describedby="basic-addon1">
       </div>
     </form>
这是我的js文件:

var client = algoliasearch('myKey', 'myValue');
var players = client.initIndex('players');
var videos = client.initIndex('videos');

var timeAgo = function(selector) {

    var templates = {
        prefix: "",
        suffix: " ago",
        seconds: "less than a minute",
        minute: "about a minute",
        minutes: "%d minutes",
        hour: "about an hour",
        hours: "about %d hours",
        day: "a day",
        days: "%d days",
        month: "about a month",
        months: "%d months",
        year: "about a year",
        years: "%d years"
    };
    var template = function (t, n) {
        return templates[t] && templates[t].replace(/%d/i, Math.abs(Math.round(n)));
    };

    var timer = function (time) {
        if (!time) return;
        time = time.replace(/\.\d+/, ""); // remove milliseconds
        time = time.replace(/-/, "/").replace(/-/, "/");
        time = time.replace(/T/, " ").replace(/Z/, " UTC");
        time = time.replace(/([\+\-]\d\d)\:?(\d\d)/, " $1$2"); // -04:00 -> -0400
        time = new Date(time * 1000 || time);

        var now = new Date();
        var seconds = ((now.getTime() - time) * .001) >> 0;
        var minutes = seconds / 60;
        var hours = minutes / 60;
        var days = hours / 24;
        var years = days / 365;

        return templates.prefix + (
        seconds < 45 && template('seconds', seconds) || seconds < 90 && template('minute', 1) || minutes < 45 && template('minutes', minutes) || minutes < 90 && template('hour', 1) || hours < 24 && template('hours', hours) || hours < 42 && template('day', 1) || days < 30 && template('days', days) || days < 45 && template('month', 1) || days < 365 && template('months', days / 30) || years < 1.5 && template('year', 1) || template('years', years)) + templates.suffix;
    };

    var elements = document.getElementsByClassName('timeago');
    for (var i in elements) {
        var $this = elements[i];
        if (typeof $this === 'object') {
            $this.innerHTML = timer($this.getAttribute('title') || $this.getAttribute('datetime'));
        }
    }
    // update time every minute
    setTimeout(timeAgo, 60000);
};

autocomplete('.search-input', {
    templates: {
        footer: '<div class="powered-by-algolia"><div class="pull-right"><img src="/imagecache/xs/Algolia_logo_bg-white.jpg" /></div></div>'
      }
    },
    [{
      source: autocomplete.sources.hits(players, { hitsPerPage: 5 }),
      displayKey: 'first_name',
      templates: {
        header: '<div class="aa-suggestions-category"><span>Players</span></div>',
        suggestion: function(suggestion) {
          var birthday = suggestion.birthday;
          var birthdayArray = birthday.split('/');
          var age = function (birthDay, birthMonth, birthYear) {
            var todayDate = new Date();
            var todayYear = todayDate.getFullYear();
            var todayMonth = todayDate.getMonth();
            var todayDay = todayDate.getDate();
            var age = todayYear - birthYear;

            if (todayMonth < birthMonth - 1){
              age--;
            }

            if (birthMonth - 1 == todayMonth && todayDay < birthDay){
              age--;
            }

            return age;
          }

          var old = age(birthdayArray[0], birthdayArray[1], birthdayArray[2]);

          return '<span>'
                + '<a href="/player/' + suggestion.id + '/' + suggestion.first_name.toLowerCase() + '-' + suggestion.last_name.toLowerCase() + '">'
                +   '<div class="media">'
                +     '<div class="media-left">'
                +       '<img class="media-object" src="/imagecache/small/' + suggestion.image_filename + '">'
                +     '</div>'
                +     '<div class="media-body">'
                +       '<p>' + suggestion._highlightResult.first_name.value + " " + suggestion._highlightResult.last_name.value + '<small> ' + old + ' years</small>' + '</p>'
                +       '<small> ' + suggestion.nationality + ' '+ suggestion.position + '</small>'
                +     '</div>'
                +   '</div>'
                + '</a>'
                +'</span>';
        }
      }
    },
    {
      source: autocomplete.sources.hits(videos, { hitsPerPage: 5 }),
      displayKey: 'title',
      templates: {
        header: '<div class="aa-suggestions-category"><span>Videos</span></div>',
        suggestion: function(suggestion) {
          timeAgo();
          return '<span>'
                +  '<a href="/player/video/' + suggestion.uid + '/' + suggestion.player_name.toLowerCase() + '-' + suggestion.player_surname.toLowerCase() + '">'
                +    '<div class="media">'
                +      '<img class="d-flex mr-3" src="https://s3.eu-central-1.amazonaws.com/videos.football-talents.com/' + suggestion.video_id + '_1.jpg">'
                +      '<div class="media-body">'
                +        '<p>' + suggestion._highlightResult.title.value + ' <small class="timeago" title="' + suggestion.created_at + '">' + suggestion.created_at + '</small>' + '</p>'
                +        '<small> ' + suggestion._highlightResult.player_name.value + " " + suggestion._highlightResult.player_surname.value + '</small>'
                +      '</div>'
                +    '</div>'
                +  '</a>'
                +'</span>';
        }
      }
    }
]).on('autocomplete:updated', function(event, suggestion, dataset) {
  var timeagoTimeout;
  clearTimeout(timeagoTimeout);
  timeAgo();
  timeagoTimeout = setTimeout(timeAgo, 60000);
});

如何在algolia autocomplete上检测焦点事件,我曾尝试在他们的api文档中查找这种情况下的一些事件,但找不到任何专门针对这种情况的事件。不确定如何实现这一点?

使用vanilla JavaScript,您只需获取DOM节点并将事件侦听器“focusin”附加到元素。你已经做了这件事,看起来效果很好

我最初使用的是您自己的代码,没有运行良好的Algolia库。为了回应您的评论,我更新了使用Algolia的答案,这是基于Algolia文档提供的官方示例。这也完全符合预期。你应该将一个工作示例作为一个片段发布到你的问题上,以便于人们进行分析

我可以肯定地说,你的问题不是焦点问题

我敢打赌,您的inputFocused函数中的下一行计算结果不是真的。也许可以尝试在inputHandler函数中设置一个断点,并在DOM命中时检查它,看看body元素是否具有“pml open”类

作为旁注,您确定它是“pml open”而不是“pnl open

if($('body').hasClass('pml-open'))
或者,将上述行的结果指定给变量,并将该值记录在inputFocused函数中

例如

下面的代码片段使用的代码来自位于

我可以确认输入在接收到焦点时正在触发focusin事件,您可以通过运行代码段自己看到这一点

你的问题几乎肯定不是焦点问题。下面的代码片段正在使用Chrome、Firefox、Edge和Internet Explorer 11。我无法访问Safari进行测试

var client=algoliasearch(“Q71HM8430Y”、“7f42b7cbd41474bf777414c24302d4a4”),
index=client.initIndex(“玩家”);
自动完成(“aa-demo-1-input”{
提示:!1,
调试:!0
}, {
来源:autocomplete.sources.hits(索引{
命中率:5
}),
显示键:“名称”,
模板:{
建议:职能(e){
返回“+e.\U highlightResult.name.value+”+e.\U highlightResult.team.value+”
}
}
});
var input=document.querySelector(“#aa-demo-1-input”);
input.addEventListener('focusin',inputFocused);
函数inputFocused(){
log(“输入接收焦点”);
}
@import”https://fonts.googleapis.com/css?family=Montserrat:400,700";
.aa-demo-1{
高度:310px;
文本对齐:居中
}
.aa输入容器p{
页边距底部:0!重要
}
.aa-demo-1.aa输入容器{
显示:内联块;
职位:相对
}
.aa-demo-1.aa输入容器输入[类型=搜索]{
-webkit盒阴影:4px4p0RGBA(241,241,241,0.35)!重要;
盒影:4px4p0RGBA(241,241,241,0.35)!重要
}
.aa-demo-1.algolia自动完成{
顶部:0!重要
}
.aa-demo-1.aa输入搜索{
宽度:300px;
填充:12px28px12px12px;
边框:2px实心#e4;
边界半径:4px;
-webkit转换:.2s;
过渡:.2s;
字体系列:“蒙特塞拉特”,无衬线;
-网络工具包盒阴影:4px4p0RGBA(241,241,241,0.35);
盒影:4px4p0RGBA(241,241,241,0.35);
字体大小:11px;
-webkit框大小:边框框;
框大小:边框框;
颜色:#333;
-webkit外观:无;
-moz外观:无;
外观:无
}
.aa-demo-1.aa输入搜索:--webkit搜索装饰,
.aa-demo-1.aa输入搜索:--webkit搜索取消按钮,
.aa-demo-1.aa输入搜索::-webkit搜索结果按钮,
.aa-demo-1.aa输入搜索:--webkit搜索结果{
显示:无
}
.aa-demo-1.aa输入搜索:焦点{
大纲:0;
边框颜色:#3a96cf
}
.aa-demo-1.aa输入容器输入[类型=搜索]:焦点{
-网络工具包盒阴影:4px4p0RGBA(581502070.1)!重要;
盒子阴影:4px4p0RGBA(581502070.1)!重要
}
.aa-demo-1.aa输入图标{
高度:16px;
宽度:16px;
位置:绝对位置;
最高:50%;
右:16px;
-webkit转换:translateY(-50%);
转化:translateY(-50%);
填充:#e4;
指针事件:无;
z指数:10
}
.aa-demo-1.aa提示{
颜色:#e4
}
.aa-demo-1.aa下拉菜单{
背景色:#fff;
边框:2倍实心rgba(2282282280.6);
边框顶部宽度:1px;
字体系列:“蒙特塞拉特”,无衬线;
宽度:300px;
边缘顶部:10px;
-网络工具包盒阴影:4px4p0RGBA(241,241,241,0.35);
盒影:4px4p0RGBA(241,241,241,0.35);
字体大小:11px;
边界半径:4px;
-webkit框大小:边框框;
框大小:边框框
}
.aa-demo-1.aa建议{
填充:12px!重要;
边框底部:0!重要;
字体大小:1.1rem!重要;
边框顶部:1px实心rgba(2282282280.6)!重要;
光标:指针;
-webkit转换:.2s;
过渡:.2s;
显示:-网络工具包盒;
显示:-ms flexbox;
显示器:flex;
-webkit盒包:证明;
-ms-flex-pack:justify;
证明内容:之间的空间;
-webkit框对齐:居中;
-ms-flex-align:居中;
对齐项目:居中
}
.aa-demo-1.aa建议:悬停,
.aa-demo-1.aa-suggestion.aa-cursor{
背景色:rgba(241,241,241,0.35)!重要
}
.aa-demo-1.aa建议>跨度:第一个孩子{
颜色:#333
}
.aa-demo-1.aa建议>跨度:最后一个孩子{
文本转换:大写;
颜色:#A9A9
}
.aa-demo-1.aa建议>跨度:第一个孩子em,
.aa-demo-1.aa建议>跨度:最后一个孩子em{
字号:700;
字体风格:普通;
背景色:rgba(581502070.1);
填充:2px 0 2px 2px
}

看到它在行动吗

var input=document.getElementsByClassName('search-input搜索输入小js表单-
var input = document.getElementsByClassName('search-input-small-js')[0];

  function inputFocused() {
      if ($('body').hasClass('pml-open')) {
          $('body').removeClass('pml-open');
          $('html, body').css('overflowY', 'auto');
      }
  }

  input.addEventListener('focusin', inputFocused);
if($('body').hasClass('pml-open'))
var pmlOpen = $('body').hasClass('pml-open');
console.log('pmlOpen is: ' + pmlOpen);
if(pmlOpen) {//...
.on('autocomplete:opened', function (e) {
    alert('opened on focus')
    e.preventDefault()
});