Wowhead Fixed Search Header

Makes the page header (the search box) "sticky" when you scroll.

  1. // ==UserScript==
  2. // @name Wowhead Fixed Search Header
  3. // @description Makes the page header (the search box) "sticky" when you scroll.
  4. // @namespace drnick
  5. // @include *wowhead.com*
  6. // @grant none
  7. // @version 1.2.0
  8. // ==/UserScript==
  9.  
  10. (function() {
  11.  
  12. if (typeof jQuery == "undefined") throw "jQuery not found";
  13. if (window.top != window.self) return;
  14. var $ = jQuery;
  15. var $window = $(window);
  16. var $header = $(".header-search");
  17. var $headerInput = $(".header-search input");
  18. if ($header.length == 0) throw "#header not found";
  19. var styles = [
  20. ".header-search.sticky {",
  21. "position: fixed;",
  22. "top: 5px;",
  23. "right: 5px;",
  24. "z-index: 9999;",
  25. "-width: 300px;",
  26. "box-shadow: 0 6px 8px #000;",
  27. "margin-right: 10px;",
  28. "opacity: 0.7;",
  29. "}",
  30. ".header-search.sticky[data-has-focus=true] {",
  31. "opacity: 1;",
  32. "}",
  33. ".header-search.sticky form {",
  34. "position: static !important;",
  35. "}",
  36. ".header-search.sticky input {",
  37. "width: 260px !important;",
  38. "-padding: 2px !important;",
  39. "}",
  40. ".header-search.sticky .header-search-button {",
  41. "top: 2px !important;",
  42. "left: 0px !important;",
  43. "-height: 26px;",
  44. "-line-height: 26px;",
  45. "}",
  46. ".header-search.sticky .data-env-links {",
  47. "display: none;",
  48. "}",
  49. ".fixed-interior-sidebar {",
  50. "margin-top: 3em;",
  51. "}",
  52. ].join("\n");
  53. $liveSearchStyle = $("<style type='text/css'></style");
  54. $("head").append("<style type='text/css'>" + styles + "</style>");
  55. $("head").append($liveSearchStyle);
  56. var offset = $header.offset().top;
  57. var height = $header.height();
  58. var $dummy = $header.clone();
  59. $dummy.empty();
  60. $dummy.attr("id", "header-dummy");
  61. $dummy.hide();
  62. $dummy.insertAfter($header);
  63. var liveSearchStyle = $liveSearchStyle.get(0);
  64. var isFloating = false;
  65. var liveSearchLeft = 0;
  66. var liveSearchTop = 0;
  67. var liveSearchWidth = 0;
  68. var liveSearchPos = "absolute";
  69. $window.on("scroll resize", function(event) {
  70. var scrollTop = $window.scrollTop();
  71. var recalc = true;
  72. if (!isFloating && scrollTop > offset) {
  73. $header.addClass("sticky");
  74. $dummy.show();
  75. isFloating = true;
  76. liveSearchPos = "fixed";
  77. }
  78. else if (isFloating && scrollTop <= offset) {
  79. $header.removeClass("sticky");
  80. $dummy.hide();
  81. isFloating = false;
  82. liveSearchPos = "absolute";
  83. }
  84. else
  85. recalc = false;
  86. if (recalc || event.type == "resize") {
  87. console.log("recalc");
  88. liveSearchLeft = $header.offset().left | 0;
  89. liveSearchTop = ($header.offset().top + $header.height()) | 0;
  90. liveSearchWidth = $headerInput.outerWidth() | 0;
  91. if (isFloating) {
  92. liveSearchTop -= ($window.scrollTop() | 0);
  93. liveSearchStyle.innerHTML = ".live-search { "
  94. + "position:" + liveSearchPos + " !important; "
  95. + "top: " + liveSearchTop + "px !important; "
  96. + "left: " + liveSearchLeft + "px !important; "
  97. + "width: " + liveSearchWidth + "px !important; "
  98. + "}";
  99. }
  100. else
  101. liveSearchStyle.innerHTML = "";
  102. }
  103. });
  104. $window.trigger('scroll');
  105. })();