在渲染后将元素更改为粘性(使搜索输入具有粘性)

时间:2021-06-06 10:19:44

标签: javascript html css dom bootstrap-table

我正在使用 bootstrap-table,这意味着它会呈现表格本身。 我正在尝试使搜索输入具有粘性,因此即使用户滚动,他仍然可以使用快速搜索功能而无需向上滚动。

示例代码可以在这里找到: https://live.bootstrap-table.com/example/options/table-search.html

代码本身是这样的:

<table
  id="table"
  data-toggle="table"
  data-search="true"
  data-url="json/data1.json">
  <thead>
    <tr>
      <th data-field="id">ID</th>
      <th data-field="name">Item Name</th>
      <th data-field="price">Item Price</th>
    </tr>
  </thead>
</table>

我尝试过:

document.querySelector('body > div.bootstrap-table.bootstrap4 > div.fixed-table-toolbar > div').style.position = "sticky"

document.querySelector('body > div.bootstrap-table.bootstrap4 > div.fixed-table-toolbar > div').style.top = "0"

但它似乎不起作用。

1 个答案:

答案 0 :(得分:0)

我可能用该死的核武器杀死了一只蝴蝶,但由于我找不到“轻松”做到这一点的方法,我手动克隆了输入并修复了它。然后在原始搜索超出视口时手动检查以隐藏/显示它。 并从原来的 CSS 复制过来,使它看起来像粘在一起。

我是这样做的,此代码用于引导表搜索,但您可以将其用于任何输入,我尝试留下评论,以便您可以查看需要编辑的位置。< /p>

HTML:

将其添加到 <body> 标签内的任意位置

<div id="stickySeachDiv" class="position-fixed top-0 end-0" style="z-index: 100;">
<!-- sticky search will be added by script into this div -->
</div>

CSS:

复制您的搜索在填充方面的属性以创建粘性效果。 隐藏是在启动时它会被隐藏,就像在我的情况下原始输入存在于顶部

#stickySeachDiv {
    padding-right: 2%;
    display: none;
}

Javascript:

我正在使用自动提交搜索,您可以将其注释掉。也不要忘记删除侦听器。 另外,我从 pre-bs 调用了 CreateStickySearch...你也可以修改它,window.onload 也应该可以工作。

$("#gamesTable").one("pre-body.bs.table", createStickySearch);
function createStickySearch() {
  // get hold on the input and clone it
  const OriginalSearch = document.querySelector(".fixed-table-toolbar .search input");
  const stickySearch = OriginalSearch.cloneNode(true);
  stickySearch.addEventListener("keyup", autoSearchHandler);
  stickySearch.addEventListener("search", handleStickySearch);
  document.querySelector("#stickySeachDiv").appendChild(stickySearch);
  // jQuery Listeners, change if you don't use jquery
  $(window).on("DOMContentLoaded load resize scroll", stickySearchListener);
}

let time;
function autoSearchHandler() {
  // automaticly submit the search after given time
  clearTimeout(time);
  time = setTimeout(() => submitStickySearch(this.value), 500);
}

function handleStickySearch() {
  submitStickySearch(this.value);
}

function submitStickySearch(text) {
  $("#table").bootstrapTable("refreshOptions", {
    searchText: text
  });
}

function revealStickySearch() {
  const originalSearch = document.querySelector(".fixed-table-toolbar .search input");
  const stickySearchDiv = document.querySelector("#stickySeachDiv");
  const stickySearchInput = stickySearchDiv.querySelector('input');
  stickySearchDiv.style.display = "block";
  stickySearchInput.value = originalSearch.value;
}

function hideStickySearch() {
  document.querySelector("#stickySeachDiv").style.display = "none";
}


// Code to see when it should activate, credit to https://stackoverflow.com/questions/123999/how-can-i-tell-if-a-dom-element-is-visible-in-the-current-viewport

function isElementInViewport(el) {
  // Special bonus for those using jQuery
  if (typeof jQuery === "function" && el instanceof jQuery) {
    el = el[0];
  }

  var rect = el.getBoundingClientRect();

  return (
    rect.top >= 0 &&
    rect.left >= 0 &&
    rect.bottom <=
      (window.innerHeight ||
        document.documentElement.clientHeight) /* or $(window).height() */ &&
    rect.right <=
      (window.innerWidth ||
        document.documentElement.clientWidth) /* or $(window).width() */
  );
}

let old_visible = true;
function onVisibilityChange(el, onvisible, onNotvisible) {
    var visible = isElementInViewport(el);
    if(visible !== old_visible) {
      old_visible = visible;
      visible ? onvisible() : onNotvisible();
    }
}


function stickySearchListener() {
  const originalSearch = document.querySelector(".fixed-table-toolbar .search input");
  onVisibilityChange(originalSearch, hideStickySearch, revealStickySearch);
}

这不是最漂亮的解决方案,但它有效,如果有人找到更优雅的解决方案,我会编辑我的解决方案。

祝大家好运