Javascript 是否为每个滚动事件在可变内存中重新创建?

Javascript 是否为每个滚动事件在可变内存中重新创建?,javascript,performance,scroll,addeventlistener,sticky,Javascript,Performance,Scroll,Addeventlistener,Sticky,我有一个名为“”.offer“类的元素,就在页面的页脚上方。当我在滚动运动中接近该元素时,我希望粘性标题关闭 我在scroll事件中为此编写了一个函数,但我对一些东西很好奇 当我创建一个类似下面示例的函数时,函数中的变量是否在内存中为每次滚动移动重新创建?或者,在一个简单的页面滚动事件中,性能的真实情况是什么 const stickyNearOfferClose = () => { let scrollPos; let header = document.querySelector(&

我有一个名为“”.offer“类的元素,就在页面的页脚上方。当我在滚动运动中接近该元素时,我希望粘性标题关闭

我在scroll事件中为此编写了一个函数,但我对一些东西很好奇

当我创建一个类似下面示例的函数时,函数中的变量是否在内存中为每次滚动移动重新创建?或者,在一个简单的页面滚动事件中,性能的真实情况是什么

const stickyNearOfferClose = () => {

let scrollPos; 
let header = document.querySelector("header");
const documentOffset = document.querySelector(".offer").offsetTop;

  header.classList.toggle("sticky", window.scrollY);
  scrollPos = window.scrollY;

    if (scrollPos >= documentOffset) {
      header.classList.add("hide");
    } else {
      header.classList.remove("hide");
    }
};


window.addEventListener("scroll", function () {
  stickyNearOfferClose();
});
除上述问题外,

当我想将上述功能用于一个或多个滚动动作时

在性能和可用性方面,我们应该使用它定义函数内部的变量还是对象内部的变量

我在下面分享了两个不同的例子。你认为应该是哪一个

const Obj = {
  scrollPos : null,
  elHeader: document.querySelector("header"),
  documentOffset: document.querySelector(".offer").offsetTop,
  // otherfunction (){},
  stickyNearOfferClose() {
    Obj.elHeader.classList.toggle("sticky", window.scrollY);

    if (Obj.scrollPos >= Obj.documentOffset) {
      Obj.elHeader.classList.add("hide");
    } else {
      Obj.elHeader.classList.remove("hide");
    }
  },
  // init(){}
};

window.addEventListener("scroll", function () {
  Obj.scrollPos = window.scrollY;
  requestAnimationFrame(Obj.stickyNearOfferClose);
});


// OR


const Obj = {
  // variables
  stickyNearOfferClose() {
    let scrollPos;
    const elHeader = document.querySelector("header");
    const elOffer = document.querySelector(".offer");
    const documentOffset = elOffer.offsetTop;

      let stickyClose = () => {
        elHeader.classList.toggle("sticky", window.scrollY);
          if (scrollPos >= documentOffset) {
            elHeader.classList.add("hide");
          } else {
            elHeader.classList.remove("hide");
          }
      };

    window.addEventListener("scroll", () => {
      scrollPos = window.scrollY;
      requestAnimationFrame(stickyClose);
    });
  },
  spyScrolling() {
    let scrollPos;
    const sections = document.querySelectorAll(".hero");

    let scrollActiveUrl = () => {
      for (let s in sections) {
        if (
          sections.hasOwnProperty(s) &&
          sections[s].offsetTop <= scrollPos + 150
        ) {
          const id = sections[s].id;
          document.querySelector(".active").classList.remove("active");
          document.querySelector(`a[href*=${id}]`).classList.add("active");
        }
      }
    };

    window.addEventListener("scroll", () => {
      scrollPos = document.documentElement.scrollTop || document.body.scrollTop;
      requestAnimationFrame(scrollActiveUrl);
    });
  }
  init(){
    this.stickyNearOfferClose();
    this.spyScrolling()
  }
};

const Obj={
scrollPos:null,
elHeader:document.querySelector(“标题”),
documentOffset:document.querySelector(“.offer”).offsetTop,
//otherfunction(){},
粘滞物{
Obj.elHeader.classList.toggle(“sticky”,window.scrollY);
如果(对象滚动位置>=对象文档偏移量){
Obj.elHeader.classList.add(“hide”);
}否则{
Obj.elHeader.classList.remove(“hide”);
}
},
//init(){}
};
window.addEventListener(“滚动”),函数(){
Obj.scrollPos=window.scrollY;
requestAnimationFrame(对象stickyNearOfferClose);
});
//或
常量对象={
//变数
粘滞物{
让我们来讨论一下;
const elHeader=document.querySelector(“header”);
const elOffer=document.querySelector(“.offer”);
const documentOffset=elOffer.offsetTop;
让stickyClose=()=>{
elHeader.classList.toggle(“sticky”,window.scrollY);
如果(滚动位置>=文档偏移量){
elHeader.classList.add(“hide”);
}否则{
elHeader.classList.remove(“hide”);
}
};
window.addEventListener(“滚动”,()=>{
scrollPos=window.scrollY;
requestAnimationFrame(stickyClose);
});
},
斯皮斯克罗林(){
让我们来讨论一下;
const sections=document.queryselectoral(“.hero”);
让scrollActiveUrl=()=>{
for(让我们分段){
如果(
第3节拥有自己的财产&&
第[s]节。偏移{
scrollPos=document.documentElement.scrollTop | | document.body.scrollTop;
requestAnimationFrame(scrollActiveUrl);
});
}
init(){
这个。粘滞物为圆形();
这是spyScrolling()
}
};

是的,函数中的变量将在每个滚动事件中重新创建。但是在您的情况下,您可以将一些变量放在函数之外以节省一点时间

根据MDN,您不应该直接在函数中调用昂贵的DOM操作。相反,建议使用
requestAnimationFrame()
setTimeout()
、或
CustomEvent
来限制事件。您可以在中了解更多信息

下面是代码的改进示例:

let scrollPos;
const elHeader = document.querySelector("header");
const elOffer = document.querySelector(".offer");
// Note: I'm assuming that `documentOffset` don't need to be updated on every scroll events.
//       Update it as `scrollPos` if it need to be updated on every scroll events.
const documentOffset = elOffter.offsetTop;;

const stickyNearOfferClose = () => {
  
  // Note: Please move the following line in the scroll event 
  //       if it's also needed to be called on every scroll events.
  elHeader.classList.toggle("sticky", window.scrollY);

  if (scrollPos >= documentOffset) {
    elHeader.classList.add("hide");
  } else {
    elHeader.classList.remove("hide");
  }
};


window.addEventListener("scroll", function () {
  scrollPos = window.scrollY;
  requestAnimationFrame(stickyNearOfferClose);
});

收听
滚动
事件不是一个好方法。请查看。