我有一个通过Javascript添加CSS类而触发的通知下拉菜单。但是,我确信Turbolinks导致它无法正常工作,因为它似乎只能在刷新时工作。
文档的data-turbolinks="true"
标记中有一个<body>
。如果将其更改为false
,则可以正常运行。
如果我将data-turbolinks="false"
放在特定链接的<div>
标记中,它仍然无法正常工作。
所以我想我将不得不更改JaveScript,以使其不受Turbolinks的影响。但是,我不确定该如何处理。这是针对Laravel 5.6应用的。
/*--------------------------------------------------*/
/* Notification Dropdowns
/*--------------------------------------------------*/
$(".header-notifications").each(function() {
var userMenu = $(this);
var userMenuTrigger = $(this).find('.header-notifications-trigger a');
$(userMenuTrigger).on('click', function(event) {
event.preventDefault();
if ( $(this).closest(".header-notifications").is(".active") ) {
close_user_dropdown();
} else {
close_user_dropdown();
userMenu.addClass('active');
}
});
});
// Closing function
function close_user_dropdown() {
$('.header-notifications').removeClass("active");
}
// Closes notification dropdown on click outside the conatainer
var mouse_is_inside = false;
$( ".header-notifications" ).on( "mouseenter", function() {
mouse_is_inside=true;
});
$( ".header-notifications" ).on( "mouseleave", function() {
mouse_is_inside=false;
});
$("body").mouseup(function(){
if(! mouse_is_inside) close_user_dropdown();
});
// Close with ESC
$(document).keyup(function(e) {
if (e.keyCode == 27) {
close_user_dropdown();
}
});
答案 0 :(得分:1)
我认为问题在于脚本仅在第一页加载时选择元素,而不是在每次页面加载时选择元素。例如,调用$(".header-notifications")
会尝试查找具有.header-notifications
类的所有元素,但是此操作仅运行一次,因此,在使用Turbolinks加载新页面时,body
会得到替换,并且那些选择的元素不再存在。在加载整个页面之前,不会再次执行脚本,因此该脚本仅运行一次-永远不会重新选择.header-notifications
元素。
要解决此问题,Turbolinks自述文件建议使用事件委托:
如果可能,请避免使用turbolinks:load事件将其他事件侦听器直接添加到页面正文上的元素。而是考虑使用event delegation在文档或窗口上注册一次事件监听器。
因此,您将事件侦听器添加到文档或窗口中,然后使用选择器选择应在其上运行的元素,例如:
$(document).on(
"click", ".header-notifications-trigger a", function (event) { … }
)
这意味着每当将.header-notifications-trigger a
元素添加到页面时,都会触发click事件处理程序。
考虑到这一点,您可能希望将脚本更新为以下内容:
/*--------------------------------------------------*/
/* Notification Dropdowns
/*--------------------------------------------------*/
// For convenience and to prevent unnecessary $() calls
var doc = $(document);
doc.on("click", ".header-notifications-trigger a", function (event) {
event.preventDefault();
var user_menu = $(this).closest(".header-notifications");
if (user_menu.is(".active")) {
close_user_dropdown();
} else {
close_user_dropdown();
user_menu.addClass('active');
}
});
// Closing function
function close_user_dropdown() {
$('.header-notifications').removeClass("active");
}
// Closes notification dropdown on click outside the container
var mouse_is_inside = false;
doc.on("mouseenter", ".header-notifications", function() {
mouse_is_inside = true;
});
doc.on("mouseleave", ".header-notifications", function() {
mouse_is_inside = false;
});
doc.on("mouseup", function(){
if(!mouse_is_inside) close_user_dropdown();
});
// Close with ESC
doc.on("keyup", function(e) {
if (e.keyCode == 27) {
close_user_dropdown();
}
});