我的模板中有一个 algolia 自动完成输入:

     <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>

这是它的css:
.algolia-autocomplete {
  display: flex!important;
  flex: auto!important;
}
.aa-dropdown-menu {
  position: relative;
  top: -6px;
  border-radius: 3px;
  margin: 6px 0 0;
  padding: 0;
  text-align: left;
  height: auto;
  position: relative;
  background: $white;
  border: 1px solid #ccc;
  width: 100%;
  left: 0 !important;
  box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.2), 0 2px 3px 0 rgba(0, 0, 0, 0.1);
}

.aa-dropdown-menu:before {
  position: absolute;
  content: '';
  width: 14px;
  height: 14px;
  background: #fff;
  z-index: 0;
  top: -7px;
  border-top: 1px solid #D9D9D9;
  border-right: 1px solid #D9D9D9;
  transform: rotate(-45deg);
  border-radius: 2px;
  z-index: 999;
  display: block;
  left: 24px;
}

.aa-dropdown-menu .aa-suggestions {
  position: relative;
  z-index: 1000;
}

.aa-dropdown-menu [class^="aa-dataset-"] {
  position: relative;
  border: 0;
  border-radius: 3px;
  overflow: auto;
  padding: 8px 8px 8px;
  color: #3c3e42;
  font-weight: 500;
}

.aa-dropdown-menu * {
  box-sizing: border-box;
}

.aa-suggestion {
  padding: 0 4px 0;
  display: block;
  width: 100%;
  height: 38px;
  clear: both;
}
.aa-suggestion span {
  white-space: nowrap !important;
  text-overflow: ellipsis;
  overflow: hidden;
  display: block;
  float: left;
  line-height: 1em;
  width: calc(100% - 30px);
}
.aa-suggestion.aa-cursor {
  background-color: transparent;
}
.aa-suggestion em {
  color: #00bcd4;
  font-weight: 700;
}
.aa-suggestion img {
  float: left;
  height: 44px;
  width: 44px;
  margin-right: 6px;
}

.aa-suggestion a {
  color: #3c3e42;
}

.aa-suggestions-category {
  font-weight: 700;
  color: #3c3e42;
  border-bottom: 1px solid rgba(102, 105, 105, 0.17);
}

.powered-by-algolia {
  padding-left: 15px;
  border-top: 1px solid rgba(102, 105, 105, 0.17);
  display: flex;
  align-items: center;
  height: 30px;
}

.aa-input-container {
  display: inline-block;
  position: relative; }
.aa-input-search {
  width: 100%;
  height: 100%;
  padding: 12px 28px 12px 12px;
  box-sizing: border-box;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none; }
.aa-input-search::-webkit-search-decoration, .aa-input-search::-webkit-search-cancel-button, .aa-input-search::-webkit-search-results-button, .aa-input-search::-webkit-search-results-decoration {
  display: none;
}
.media {
  margin: 10px 0;
}
.media-body {
  p {
    margin: 0;
  }
}

这是我的 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);
});

我试图以各种方式检测该输入字段上的焦点事件,但没有任何效果,这是尝试之一:
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);

我如何检测 algolia 自动完成上的焦点事件,我试图在他们的 api 文档中为这种情况找到一些事件,但找不到任何专门针对此的事件。不知道我该怎么做?

最佳答案

使用 vanilla JavaScript,您只需获取 DOM 节点并将“focusin”的事件监听器附加到元素。你已经这样做了,它似乎工作得很好。

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

我可以明确地说你的问题不是焦点问题。

我敢打赌 inputFocused 函数中的以下行不会评估为真。也许尝试在 inputHandler 函数中设置一个断点并在它命中时检查 DOM 以查看 body 元素是否具有“pml-open”类。

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

if($('body').hasClass('pml-open'))

或者,将上述行的结果分配给一个变量,并在 inputFocused 函数中记录该值。

例如。
var pmlOpen = $('body').hasClass('pml-open');
console.log('pmlOpen is: ' + pmlOpen);
if(pmlOpen) {//...

下面的代码片段使用了位于 https://www.algolia.com/doc/tutorials/search-ui/autocomplete/auto-complete/ 的 Autocomplete 教程(Algolia 的事实可信来源)中的代码

我可以确认输入在接收到焦点时触发了 focusin 事件,您可以通过运行代码片段为自己查看。

您的问题几乎肯定不是焦点问题。以下代码段适用于 Chrome、Firefox、Edge 和 Internet Explorer 11。我无法访问 Safari 来对其进行测试。

var client = algoliasearch("Q71HM8430Y", "7f42b7cbd41474bf777414c24302d4a4"),
  index = client.initIndex("players");
autocomplete("#aa-demo-1-input", {
  hint: !1,
  debug: !0
}, {
  source: autocomplete.sources.hits(index, {
    hitsPerPage: 5
  }),
  displayKey: "name",
  templates: {
    suggestion: function(e) {
      return "<span>" + e._highlightResult.name.value + "</span><span>" + e._highlightResult.team.value + "</span>"
    }
  }
});

var input = document.querySelector('#aa-demo-1-input');

input.addEventListener('focusin', inputFocused);

function inputFocused() {
  console.log('input received focus');
}
@import "https://fonts.googleapis.com/css?family=Montserrat:400,700";
.aa-demo-1 {
  height: 310px;
  text-align: center
}

.aa-input-container p {
  margin-bottom: 0 !important
}

.aa-demo-1 .aa-input-container {
  display: inline-block;
  position: relative
}

.aa-demo-1 .aa-input-container input[type=search] {
  -webkit-box-shadow: 4px 4px 0 rgba(241, 241, 241, 0.35) !important;
  box-shadow: 4px 4px 0 rgba(241, 241, 241, 0.35) !important
}

.aa-demo-1 .algolia-autocomplete {
  top: 0 !important
}

.aa-demo-1 .aa-input-search {
  width: 300px;
  padding: 12px 28px 12px 12px;
  border: 2px solid #e4e4e4;
  border-radius: 4px;
  -webkit-transition: .2s;
  transition: .2s;
  font-family: "Montserrat", sans-serif;
  -webkit-box-shadow: 4px 4px 0 rgba(241, 241, 241, 0.35);
  box-shadow: 4px 4px 0 rgba(241, 241, 241, 0.35);
  font-size: 11px;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  color: #333;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none
}

.aa-demo-1 .aa-input-search::-webkit-search-decoration,
.aa-demo-1 .aa-input-search::-webkit-search-cancel-button,
.aa-demo-1 .aa-input-search::-webkit-search-results-button,
.aa-demo-1 .aa-input-search::-webkit-search-results-decoration {
  display: none
}

.aa-demo-1 .aa-input-search:focus {
  outline: 0;
  border-color: #3a96cf
}

.aa-demo-1 .aa-input-container input[type=search]:focus {
  -webkit-box-shadow: 4px 4px 0 rgba(58, 150, 207, 0.1) !important;
  box-shadow: 4px 4px 0 rgba(58, 150, 207, 0.1) !important
}

.aa-demo-1 .aa-input-icon {
  height: 16px;
  width: 16px;
  position: absolute;
  top: 50%;
  right: 16px;
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
  fill: #e4e4e4;
  pointer-events: none;
  z-index: 10
}

.aa-demo-1 .aa-hint {
  color: #e4e4e4
}

.aa-demo-1 .aa-dropdown-menu {
  background-color: #fff;
  border: 2px solid rgba(228, 228, 228, 0.6);
  border-top-width: 1px;
  font-family: "Montserrat", sans-serif;
  width: 300px;
  margin-top: 10px;
  -webkit-box-shadow: 4px 4px 0 rgba(241, 241, 241, 0.35);
  box-shadow: 4px 4px 0 rgba(241, 241, 241, 0.35);
  font-size: 11px;
  border-radius: 4px;
  -webkit-box-sizing: border-box;
  box-sizing: border-box
}

.aa-demo-1 .aa-suggestion {
  padding: 12px !important;
  border-bottom: 0 !important;
  font-size: 1.1rem !important;
  border-top: 1px solid rgba(228, 228, 228, 0.6) !important;
  cursor: pointer;
  -webkit-transition: .2s;
  transition: .2s;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: justify;
  -ms-flex-pack: justify;
  justify-content: space-between;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center
}

.aa-demo-1 .aa-suggestion:hover,
.aa-demo-1 .aa-suggestion.aa-cursor {
  background-color: rgba(241, 241, 241, 0.35) !important
}

.aa-demo-1 .aa-suggestion>span:first-child {
  color: #333
}

.aa-demo-1 .aa-suggestion>span:last-child {
  text-transform: uppercase;
  color: #a9a9a9
}

.aa-demo-1 .aa-suggestion>span:first-child em,
.aa-demo-1 .aa-suggestion>span:last-child em {
  font-weight: 700;
  font-style: normal;
  background-color: rgba(58, 150, 207, 0.1);
  padding: 2px 0 2px 2px
}
<section>
  <h2 id=see-it-in-action>See it in action</h2>
  <link href="/doc/tutorials/search-ui/autocomplete/auto-complete.css" rel=stylesheet/>
  <div class=aa-demo-1>
    <div class=aa-input-container>
      <p>
        <input type=search id=aa-demo-1-input class=aa-input-search placeholder="Search for players or videos..." name=search autocomplete=off required=required/>
      </p>
      <svg id=icon-search class=aa-input-icon viewBox="654 -372 1664 1664">
                                            <path d="M1806,332c0-123.3-43.8-228.8-131.5-316.5C1586.8-72.2,1481.3-116,1358-116s-228.8,43.8-316.5,131.5 C953.8,103.2,910,208.7,910,332s43.8,228.8,131.5,316.5C1129.2,736.2,1234.7,780,1358,780s228.8-43.8,316.5-131.5 C1762.2,560.8,1806,455.3,1806,332z M2318,1164c0,34.7-12.7,64.7-38,90s-55.3,38-90,38c-36,0-66-12.7-90-38l-343-342 c-119.3,82.7-252.3,124-399,124c-95.3,0-186.5-18.5-273.5-55.5s-162-87-225-150s-113-138-150-225S654,427.3,654,332 s18.5-186.5,55.5-273.5s87-162,150-225s138-113,225-150S1262.7-372,1358-372s186.5,18.5,273.5,55.5s162,87,225,150s113,138,150,225 S2062,236.7,2062,332c0,146.7-41.3,279.7-124,399l343,343C2305.7,1098.7,2318,1128.7,2318,1164z"/>
                                        </svg>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/algoliasearch/3/algoliasearch.min.js"></script>
  <script src="https://cdn.jsdelivr.net/autocomplete.js/0/autocomplete.min.js"></script>
  <script src="/doc/tutorials/4-search-ui/autocomplete/auto-complete.js"></script>
</section>

关于javascript - 检测 algolia 自动完成字段上的焦点事件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46131465/

10-12 19:44