javascript - 无法按属性滚动到元素

标签 javascript jquery

我有一个搜索表单,用于搜索 UL LI 元素内的单词。当有结果时 - 我希望它按结果的属性位置(数据目标)滚动。

我无法通过它的属性获取 LI 的位置,因此无法导航到它。

当我尝试获取 element_id 变量的位置时,出现“无法读取未定义的属性‘top’”:

$(".faq_cont_right .scroll ul li").each(function() {
    if ($(this).text().search(new RegExp(filter, "i")) < 0) {
        var element_id = $(".faq_cont_right .scroll ul li").filter('[data-target="#item1"]');
        $('.scroll').animate({
            scrollTop: $(element_id).position().top - 500,
        }, 200);
    } else {
        $(this).show();
        $(this).trigger('click');
        var element_id = $(this).attr('data-target');
        var scroller = $('.scroll').offset().top;
        console.log($(element_id).offset().top); // error

        $('.scroll').animate({
            scrollTop: $(element_id).offset().top - scroller,
        }, 200);
    }
});

/**
 * Created by Roy Barak on 22-Oct-17.
 */
$(document).ready(function() {

  $('.questions_header').text($(".active_search").text());

  $('.question_div').on('shown.bs.tab', function() {


    $('.questions_header').text($(this).text());


  });

  $('#faq_chat_btn').on('click', function() {

    $(this).toggleClass('faq_chat_off faq_chat_on');
    if ($(this).hasClass("faq_chat_off")) {
      $('.faq_chat_header_left p').text('fermé');
      $('.faq_chat_middle').hide();
    }
    if ($(this).hasClass("faq_chat_on")) {

      $('.faq_chat_header_left p').text('ouvert');
      $('.faq_chat_middle').show();
    }


  });


  $('#faq_search').bind('keydown', 'keyup', function(event) {
    if (event.keyCode == 13) {
      event.preventDefault();

    }


    var filter = $(this).val();

    if (filter.length && filter !== null && filter !== '') {

      $(".faq_cont_right .scroll ul li").each(function() {


        if ($(this).text().search(new RegExp(filter, "i")) < 0) {

          var element_id = $(".faq_cont_right .scroll ul li").filter('[data-target="#item1"]');

          $('.scroll').animate({
            scrollTop: $(element_id).position().top - 500,
          }, 200);

        } else {

          $(this).show();

          $(this).trigger('click');
          var element_id = $(this).attr('data-target');
          var scroller = $('.scroll').offset().top;

          console.log($(element_id).offset().top);

          $('.scroll').animate({
            scrollTop: $(element_id).offset().top - scroller,
          }, 200);



        }
      });
      $(".tab-content>.active").each(function() {

        if ($(this).text().search(new RegExp(filter, "i")) < 0) {

          $(this).show();

        } else {

          $(this).show();

        }
      });

    }

  });

  $(".faq_cont_right .scroll ul li").on('click', function(e) {

    $(".faq_cont_right .scroll ul li").removeClass('active_search');
    $(this).toggleClass('active_search');

    e.preventDefault();

  });
});
/* Styles go here */

#faq_page .page_container {
  height: 100vh;
}

.faq_cont_right {
  float: left;
  width: 33.33333333%;
}

.scroll {
  width: 100%;
  height: 88vh;
  overflow-y: scroll;
  overflow-x: hidden;
}

.faq_cont_left .tab-content {
  padding: 15px!important;
}

.faq_tab_content {
  height: 88%;
}

.faq_question_header {
  padding: 15px;
  height: 12%;
  display: flex;
  align-items: center;
}

.faq_question_header p {
  margin: 0!important;
}

.questions_header {
  font-family: 'Roboto', sans-serif;
  color: #5d3c95;
  font-size: 1rem;
  text-transform: uppercase;
}

.answer_content {
  font-family: 'Roboto', sans-serif;
  color: #48484a;
  font-size: 1rem;
}

.search_bar {
  background-color: #fff;
  border-right: 2px solid #e9e9e9;
  border-left: 2px solid #e9e9e9;
  height: 12vh;
  display: flex;
  align-items: center;
  padding: 0 10px 0 20px;
}

.faq_search_form input {
  margin-left: 10px;
  outline: none;
  border: none;
  font-size: 11px;
}

form.faq_search_form {
  display: flex;
  align-items: center;
}

input.input_search::-webkit-input-placeholder {
  font-family: 'Roboto', sans-serif;
  font-size: 12px;
  color: #767678;
}

input.input_search::-moz-placeholder {
  font-family: 'Roboto', sans-serif;
  font-size: 12px;
  color: #767678;
}

input.input_search:-ms-input-placeholder {
  font-family: 'Roboto', sans-serif;
  font-size: 12px;
  color: #767678;
}

input.input_search {
  padding: 0 !important;
}

form.faq_search_form i:before {
  content: "\f002";
  font-size: 2vw;
  font-family: FontAwesome;
  font-style: normal;
  font-weight: normal;
  text-decoration: inherit;
  color: #767678;
}

.faq_cont_left {
  height: 100vh;
  background-color: white;
  float: left;
  width: 66.66666667%;
}

.faq_questions {
  padding: 0;
  width: 100%;
  list-style: none;
  margin-top: 0 !important;
  margin-bottom: 0px !important;
}

.faq_questions li:hover {
  font-weight: 600;
}

.question_div {
  font-family: 'Roboto', sans-serif;
  font-size: 11px;
  background-color: #e9e9e9;
  display: flex;
  align-items: center;
  height: 80px;
  justify-content: center;
}

.questions_border {
  height: 100%;
  border-bottom: 0.5px solid white;
  display: flex;
  align-items: center;
  width: 70%;
}

.questions_cont p {
  margin: 0;
}

.questions_cont {
  /*padding-left: 22px;*/
  /*padding-right: 55px;*/
}

.question_div {
  position: relative;
  z-index: 10000;
}

.active_search {
  font-weight: 600;
  background-color: #5d3c95;
  color: white;
}

.scroll::-webkit-scrollbar-track {
  background-color: #F5F5F5;
}

.scroll::-webkit-scrollbar {
  width: 7px;
  background-color: #d8d8d8;
}

.scroll::-webkit-scrollbar-thumb {
  background-color: #bebebe;
  border: none;
}


/*-------------chat---------------*/

.faq_chat_box {
  width: 66.66666667%;
  background-color: #d3f2f1;
  position: absolute;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  right: 0;
  padding: 20px;
}

.faq_chat_box_wrap {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.faq_chat_header {
  padding: 15px 20px 15px 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background-color: #5d3c95;
  color: #fff;
}

.faq_chat_header_right img {
  width: 11%;
}

.faq_chat_header_right span {
  font-family: 'Roboto', sans-serif;
  font-size: 1.3rem;
  color: #fff;
  padding: 10px;
  margin: 0 !important;
  font-weight: 300;
}

.faq_chat_header_left p {
  font-family: 'Montserrat Semi Bold', sans-serif;
  font-size: 11px;
  color: #fff;
  padding: 10px;
  margin: 0 !important;
}

.faq_chat_middle {
  width: 100%;
  background-color: #fff;
  padding: 10px;
}

.chat_text {
  font-family: 'Roboto', sans-serif;
  font-size: 1.3rem;
  color: #48484a;
}

.chat_parme_text {
  margin-bottom: 15px;
}

.chat_parme_text_header {
  font-family: 'Roboto', sans-serif;
  font-size: 1.3rem;
  color: #5d3c95;
}

.chat_client_text_header {
  font-family: 'Roboto', sans-serif;
  font-size: 1.3rem;
  color: #41c8c2;
}

#faq_chat_btn:hover {
  cursor: pointer;
  cursor: hand;
}

.faq_chat_footer {
  padding: 18px;
  background-color: #41c8c2;
}

.faq_chat_middle .scroll {
  height: 20vh;
  width: 100%;
  overflow-y: scroll;
  overflow-x: hidden;
}

.faq_chat_icon {
  position: relative;
}

.faq_chat_header_left {
  display: flex;
  align-items: center;
}

.faq_chat_status i {
  font-size: 18px;
}

.faq_chat_on {
  color: #41c8c2;
}

.faq_chat_off {
  color: #ff4444;
}

.input-icon {
  position: absolute;
  color: #41c8c2;
  right: 17px;
  font-size: 18px;
  top: calc(50% - 0.5em);
  /* Keep icon in center of input, regardless of the input height */
}

input#faq_chat {
  border-radius: 5px;
  outline: none;
  border: none;
}

.input-wrapper {
  position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="faq_cont_right">
  <div class="search_bar">
    <form class="faq_search_form"><i></i>
      <input class="form-control input_search" placeholder="Rechercher une question..." name="faq_search" id="faq_search" type="text" autocomplete="off">
    </form>
  </div>
  <div class="scroll">
    <ul class="faq_questions">




      <li class="question_div" data-target="#item1" data-toggle="tab">
        <div class="questions_border">
          <div class="questions_cont">
            Les salariés SNCF en activité sont-ils les seuls à pouvoir déposer une demande ?
          </div>
        </div>
      </li>


      <li class="question_div" data-target="#item2" data-toggle="tab">
        <div class="questions_border">
          <div class="questions_cont">
            Mon futur hébergement est pris en charge par mon entreprise. Quelles sont les démarches à effectuer ?
          </div>
        </div>
      </li>


      <li class="question_div" data-target="#item3" data-toggle="tab">
        <div class="questions_border">
          <div class="questions_cont">
            Une famille peut-elle faire une demande de logement ?
          </div>
        </div>
      </li>


      <li class="question_div" data-target="#item4" data-toggle="tab">
        <div class="questions_border">
          <div class="questions_cont">
            Qu'est-ce que le contrat d'occupation ?
          </div>
        </div>
      </li>


      <li class="question_div" data-target="#item5" data-toggle="tab">
        <div class="questions_border">
          <div class="questions_cont">
            Qu'est-ce que le garant physique ou cautionnement ?
          </div>
        </div>
      </li>


      <li class="question_div" data-target="#item6" data-toggle="tab">
        <div class="questions_border">
          <div class="questions_cont">
            Quelles conditions doit remplir mon garant physique ou cautionnaire ?
          </div>
        </div>
      </li>


      <li class="question_div" data-target="#item7" data-toggle="tab">
        <div class="questions_border">
          <div class="questions_cont">
            How to ask question
          </div>
        </div>
      </li>


      <li class="question_div" data-target="#item8" data-toggle="tab">
        <div class="questions_border">
          <div class="questions_cont">
            Terris civitates civitates quam honorem?
          </div>
        </div>
      </li>


      <li class="question_div" data-target="#item9" data-toggle="tab">
        <div class="questions_border">
          <div class="questions_cont">
            Une famille peut-elle faire une demande de logement ?
          </div>
        </div>
      </li>


      <li class="question_div" data-target="#item10" data-toggle="tab">
        <div class="questions_border">
          <div class="questions_cont">
            Qu'est-ce que le contrat d'occupation ?
          </div>
        </div>
      </li>


      <li class="question_div active_search active" data-target="#item11" data-toggle="tab">
        <div class="questions_border">
          <div class="questions_cont">
            Qu'est-ce que le foo ?
          </div>
        </div>
      </li>





    </ul>
  </div>
</div>

Fiddle

最佳答案

您的选择器存在一些问题。

首先,element_id在您的代码中设置了两个不同的场合:

var element_id = $(".faq_cont_right .scroll ul li").filter('[data-target="#item1"]')
...
var element_id = $(this).attr('data-target')

第一个返回一个 jQuery 对象,第二个返回一个字符串。这意味着没有统一的方式来对待element_id .建议将 jQuery 对象命名为 $element_id和字符串 element_id将它们分开。

其次,标记中的数据属性包含类似 #item11 的值.这意味着 jQuery 选择器 $(element_id)将等于例如$('#item11') , 尝试选择 id="item11" 的项目.但是,标记中的所有元素都没有设置 ID,因此选择器将返回 undefined .

使用您当前的标记,您可以尝试使用像 $('[data-target="'+element_id+'"]') 这样的选择器通过数据属性定位元素,尽管为什么不跳过 data-target属性并简单地获取 ID?

我还建议您在用户快速键入时阻止滚动动画构建队列,因为这会来回滚动结果。通过添加 .stop() 来做到这一点像这样:$('.scroll').stop().animate({ //... }) .

我已经 put together an example根据我上面的建议。这并不能修复您的所有代码(现在它的乐趣在哪里?:o),但希望这会让您走上正确的道路。可能需要更多调整,但至少错误应该消失。

关于javascript - 无法按属性滚动到元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47258822/

相关文章:

javascript - 为什么 'await' 不等待 axios 请求完成?

jquery - 按钮onclick刷新页面

javascript - jQuery:如何提交包含编辑后的用户输入值的表单?

javascript - 溢出属性不考虑填充

javascript - 在 Javascript 数组中将数字彼此相除

c# - 继续下一步,不要跳过前面的 LINQ c#

javascript - 使用更多属性更新模型 (backbone.js)

javascript - 使用 AJAX 删除项目后未触发 .ajaxComplete?

javascript - 使一个 div 宽度为另一个 div 的一半

javascript - .slideDown 对我不起作用