JQuery 事件侦听器与 Rails 7 一起使用时出错

JQuery event listener error when using it with Rails 7

提问人:John Sall 提问时间:11/17/2023 最后编辑:John Sall 更新时间:11/18/2023 访问量:47

问:

我只使用 CDN 添加了 JQuery,我将代码放在 _head.html.erb 中的头部,这是这个:

<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>

然后我使用了这段代码,并将其放置在 show.html.erb 中的某个位置

<script>
var carouselWidth = $('.carousel-inner')[0].scrollWidth;
var cardWidth = $('.carousel-item').width();

var scrollPosition = 0;

$('.carousel-control-next').on('click', function(){
    console.log('next');
    scrollPosition = scrollPosition + cardWidth;
    $('.carousel-inner').animate({scrollLeft: scrollPosition}, 600);
});
</script>

我不确定还有什么地方可以放置jquery代码,但是当我在浏览器中打开控制台时,出现以下错误:

menu-f19d6842a068966109ba6a8b3de0283869f632ec673afe222888bbeba8442401.js:7 Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')
    at addToggleListener (menu-f19d6842a068966109ba6a8b3de0283869f632ec673afe222888bbeba8442401.js:7:26)
    at HTMLDocument.<anonymous> (menu-f19d6842a068966109ba6a8b3de0283869f632ec673afe222888bbeba8442401.js:15:9)
    at S (turbo.es2017-esm.js:344:34)
    at Object.notifyApplicationAfterPageLoad (turbo.es2017-esm.js:3158:16)
    at Object.pageBecameInteractive (turbo.es2017-esm.js:3080:14)
    at he.pageIsInteractive (turbo.es2017-esm.js:2486:27)
    at he.pageIsComplete (turbo.es2017-esm.js:2490:14)
    at HTMLDocument.interpretReadyState (turbo.es2017-esm.js:2458:22)
addToggleListener @ menu-f19d6842a068966109ba6a8b3de0283869f632ec673afe222888bbeba8442401.js:7
(anonymous) @ menu-f19d6842a068966109ba6a8b3de0283869f632ec673afe222888bbeba8442401.js:15
S @ turbo.es2017-esm.js:344
notifyApplicationAfterPageLoad @ turbo.es2017-esm.js:3158
pageBecameInteractive @ turbo.es2017-esm.js:3080
pageIsInteractive @ turbo.es2017-esm.js:2486
pageIsComplete @ turbo.es2017-esm.js:2490
interpretReadyState @ turbo.es2017-esm.js:2458

编辑

菜单.js文件:

function addToggleListener(selected_id, menu_id, toggle_class) {
        let selected_element = document.querySelector(`#${selected_id}`);
        selected_element.addEventListener('click', function(event){
                event.preventDefault();
                let menu = document.querySelector(`#${menu_id}`)
                menu.classList.toggle(toggle_class);
        });
}

document.addEventListener('turbo:load', function(){
        addToggleListener('hamburger', 'navbar-menu', 'collapse');
        addToggleListener('account', 'dropdown-menu', 'active');
});
javascript jquery ruby-on-rails ruby-on-rails-7

评论

0赞 Barmar 11/18/2023
我不认为错误来自此代码。它来自一个叫做turbo.es2017-esm.js
0赞 Alex 11/18/2023
您的错误在menu.js
0赞 John Sall 11/18/2023
@Alex我添加了菜单.js内容,知道如何解决它吗?

答:

1赞 Alex 11/18/2023 #1

您正在尝试向元素添加侦听器,但页面上没有“汉堡包”或“帐户”元素。使用 Turbo 使用事件委托是一种更好的方法:selected_element.addEventListener

// menu.js

function toggleMenu(event, selectedId, menuId, toggleClass) {
  const selected = event.target.closest(selectedId)
  if (selected) {
    event.preventDefault();
    const menu = document.querySelector(menuId)
    menu.classList.toggle(toggleClass);
  }
}

document.addEventListener("click", function(event){
  toggleMenu(event, "#hamburger", "#navbar-menu", "collapse");
  toggleMenu(event, "#account", "#dropdown-menu", "active");
});

您可能需要考虑使用属性来控制模板中的行为。这样,您就不必添加更多调用:datatoggleMenu

// menu.js

document.addEventListener("click", function(event){
  const toggler = event.target.closest("[data-toggle]")
  if (toggler) {
    event.preventDefault();
    const menu = document.querySelector(toggler.dataset.toggle)
    menu.classList.toggle(toggler.dataset.toggleClass);
  }
});
<div data-toggle="#navbar-menu" data-toggle-class="collapse">hamburger</div>

<div id="navbar-menu" class="collapse">navbar menu</div>
<div data-toggle="#dropdown-menu" data-toggle-class="active">hamburger</div>

<div id="dropdown-menu" class="active">account menu</div>

https://turbo.hotwired.dev/handbook/building#installing-javascript-behavior https://learn.jquery.com/events/event-delegation/