【问题标题】:Js Vanilla dynamic url + nesting anchor and preventdefaultJs Vanilla 动态 url + 嵌套锚点和 preventdefault
【发布时间】:2018-12-07 07:33:19
【问题描述】:

如何防止具有子元素的默认锚点。我使用事件委托点击,因为链接是动态设置的。

当用户点击时,我必须检查它是否在锚点中有data-applink,在这种情况下,我使用closest 遍历找到它的父元素(因为点击事件会检测到子元素,而不是锚点)。

获得父节点后,添加点击事件并防止默认。但不知何故,它不起作用。

请帮忙,有什么想法吗?

//simulate ajax
setTimeout(()=> {
  const anchor = document.querySelectorAll('.anchor')[0];
  anchor.setAttribute("href", "http://www.google.com");
  anchor.setAttribute("data-applink", "app://link.id");
},800);

const checkNesting = (selector, event, callback) => {
  let elem = event.target;
  if (elem.matches(selector)) {
     callback(elem);
  }else{
     elem = event.target.closest(selector);
    if (elem) {
      // console.log(elem);
       callback(elem);
    }
  }
 

}
document.body.addEventListener('click', (event) => {
  checkNesting('*[data-applink]', event, (el) => {
    el.addEventListener('click', (ev) => {
       ev.preventDefault();
    });
  });
});
<a href="#" class="anchor">
  <button>Click Here</button>
</a>

【问题讨论】:

    标签: javascript ajax preventdefault


    【解决方案1】:
        el.addEventListener('click', (ev) => {
           ev.preventDefault();
        });
    

    我最好的猜测是上面的事件监听器在下一个点击事件开始工作,而不是当前的。如果有人能提供解释,我将不胜感激。

    为解决您的问题,您可以将preventDefault 应用到当前的event

    //simulate ajax
    setTimeout(()=> {
      const anchor = document.querySelectorAll('.anchor')[0];
      anchor.setAttribute("href", "https://www.google.com");
      anchor.setAttribute("data-applink", "app://link.id");
    },800);
    
    const checkNesting = (selector, event, callback) => {
      let elem = event.target;
      if (elem.matches(selector)) {
         return true
      }
      elem = event.target.closest(selector);
      if (elem) {
        // console.log(elem);
         return true
      }
      return false
    }
    document.body.addEventListener('click', (event) => {
      if (checkNesting('*[data-applink]', event)) {
        event.preventDefault();
      }
    });
    <a href="#" class="anchor">
      <button onClick="alert('I am working fine and bubbling up is cancelled')">Click Here</button>
    </a>
    
    <a href="https://www.google.com">
    <button onClick="alert('I allow bubbling up')">Click me too</button>
    </a>

    【讨论】:

    • 你是对的,我不应该在文档点击委托中再次添加点击事件,你的答案有效,所以关键是使用返回布尔值,所以不需要回调?我使用回调是因为我需要对元素(或匹配的父元素)做一些事情。我想我只是创建另一个函数而不是回调函数?
    • @Ardeus 是的,应该是这样。
    【解决方案2】:
    (() => {
      const anchor = document.querySelector('#anchor');
    
      setTimeout(()=> {
        anchor.setAttribute("href", "http://www.google.com");
        anchor.setAttribute("data-applink", "app://link.id");
      }, 800);
    
      anchor.addEventListener("click", (e) => {
        e.preventDefault();
        console.log('prevented');
      });
    })();
    

    我不太确定,但在我看来“preventDefault”过于复杂,但这个应该可以正常工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多