querySelectorAll 和事件监听器

Posted

技术标签:

【中文标题】querySelectorAll 和事件监听器【英文标题】:querySelectorAll and event listener 【发布时间】:2020-05-06 11:00:45 【问题描述】:

我目前正在尝试调整this demo 以在您单击应用了相同类的链接时进行页面转换。目前,在@ourmaninamsterdam 的推荐here 之后,我有以下代码,但我似乎无法使其工作。您对我如何获得它来启动转换有什么建议吗?

<script>
// SVG Overlay Transition

// This will allow for delay for animation to play before next page load
$(".link-with-overlay").click(function(e) 
  e.preventDefault();
  setTimeout(function(url)  window.location = url , 1700, this.href);
);
</script>


<script>
// These are the 'Easing' functions we will reference
const ease = 
  exponentialIn: (t) => 
    return t == 0.0 ? t : Math.pow(2.0, 10.0 * (t - 1.0));
  ,
  exponentialOut: (t) => 
    return t == 1.0 ? t : 1.0 - Math.pow(2.0, -10.0 * t);
  ,
  exponentialInOut: (t) => 
    return t == 0.0 || t == 1.0
      ? t
      : t < 0.5
        ? +0.5 * Math.pow(2.0, (20.0 * t) - 10.0)
        : -0.5 * Math.pow(2.0, 10.0 - (t * 20.0)) + 1.0;
  ,
  sineOut: (t) => 
    const HALF_PI = 1.5707963267948966;
    return Math.sin(t * HALF_PI);
  ,
  circularInOut: (t) => 
    return t < 0.5
        ? 0.5 * (1.0 - Math.sqrt(1.0 - 4.0 * t * t))
        : 0.5 * (Math.sqrt((3.0 - 2.0 * t) * (2.0 * t - 1.0)) + 1.0);
  ,
  cubicIn: (t) => 
    return t * t * t;
  ,
  cubicOut: (t) => 
    const f = t - 1.0;
    return f * f * f + 1.0;
  ,
  cubicInOut: (t) => 
    return t < 0.5
      ? 4.0 * t * t * t
      : 0.5 * Math.pow(2.0 * t - 2.0, 3.0) + 1.0;
  ,
  quadraticOut: (t) => 
    return -t * (t - 2.0);
  ,
  quarticOut: (t) => 
    return Math.pow(t - 1.0, 3.0) * (1.0 - t) + 1.0;
  ,

</script>

<script>
//Demo 6 Code
class ShapeOverlays 
  constructor(elm) 
    this.elm = elm;
    this.path = elm.querySelectorAll('path');
    this.numPoints = 10;
    this.duration = 900;
    this.delayPointsArray = [];
    this.delayPointsMax = 300;
    this.delayPerPath = 250;
    this.timeStart = Date.now();
    this.isOpened = false;
    this.isAnimating = false;
  
  toggle() 
    this.isAnimating = true;
    for (var i = 0; i < this.numPoints; i++) 
      this.delayPointsArray[i] = Math.random() * this.delayPointsMax;
    
    if (this.isOpened === false) 
      this.open();
     else 
      this.close();
    
  
  open() 
    this.isOpened = true;
    this.elm.classList.add('is-opened');
    this.timeStart = Date.now();
    this.renderLoop();
  
  close() 
    this.isOpened = false;
    this.elm.classList.remove('is-opened');
    this.timeStart = Date.now();
    this.renderLoop();
  
  updatePath(time) 
    const points = [];
    for (var i = 0; i < this.numPoints; i++) 
      points[i] = (1 - ease.cubicInOut(Math.min(Math.max(time - this.delayPointsArray[i], 0) / this.duration, 1))) * 100
    

    let str = '';
    str += (this.isOpened) ? `M 0 0 V $points[0]` : `M 0 $points[0]`;
    for (var i = 0; i < this.numPoints - 1; i++) 
      const p = (i + 1) / (this.numPoints - 1) * 100;
      const cp = p - (1 / (this.numPoints - 1) * 100) / 2;
      str += `C $cp $points[i] $cp $points[i + 1] $p $points[i + 1] `;
    
    str += (this.isOpened) ? `V 100 H 0` : `V 0 H 0`;
    return str;
  
  render() 
    if (this.isOpened) 
      for (var i = 0; i < this.path.length; i++) 
        this.path[i].setAttribute('d', this.updatePath(Date.now() - (this.timeStart + this.delayPerPath * i)));
      
     else 
      for (var i = 0; i < this.path.length; i++) 
        this.path[i].setAttribute('d', this.updatePath(Date.now() - (this.timeStart + this.delayPerPath * (this.path.length - i - 1))));
      
    
  
  renderLoop() 
    this.render();
    if (Date.now() - this.timeStart < this.duration + this.delayPerPath * (this.path.length - 1) + this.delayPointsMax) 
      requestAnimationFrame(() => 
        this.renderLoop();
      );
    
    else 
      this.isAnimating = false;
    
  


(function() 
  const elmHamburgers = document.querySelectorAll('.link-with-overlay');
  const elmOverlay = document.querySelector('.shape-overlays');
  const overlay = new ShapeOverlays(elmOverlay);

  const onHamburgerClick = function() 
    if (overlay.isAnimating) 
      return false;
    
    overlay.toggle();
    if (overlay.isOpened === true) 
      this.classList.add('is-opened-navi');

     else 
      this.classList.remove('is-opened-navi');
    
  ;

  // Iterates over all of the elements matched with class .link-with-overlay and 
  // adds an onclick event listener

  elmHamburgers.forEach(elem => elem.addEventListener('click', onHamburgerClick));
      
    
  );
());
</script>

【问题讨论】:

【参考方案1】:

您的代码无效,因为文件末尾的右括号过多。最后关闭 &lt;/script&gt; 之前的代码结尾应如下所示:

      elmHamburgers.forEach(elem => elem.addEventListener('click', onHamburgerClick));
      
  )();

</script>

【讨论】:

以上是关于querySelectorAll 和事件监听器的主要内容,如果未能解决你的问题,请参考以下文章

通过单选按钮循环事件监听器。可能吗?

事件高级1注册事件(绑定事件)

事件高级1注册事件(绑定事件)

调用事件侦听器的 HTML 按钮不起作用 HTML 和 JS

QuerySelectorAll 不适用于 onclick 事件

addEventListener、箭头函数和`this` [重复]