我正在构建带有引导弹出窗口的通知弹出窗口。弹出窗口为每个通知提供了一个div,每个div具有相同的类(除了文本内容外,它们都是相同的)。
<% notifs.each do |notif| %>
<div class="media n-media notif-popup-container notif-display" data-id=<%= notif.id %> >
Content
</div>
<% end %>
这将导致以下结果:
但是,当我单击任何通知div(在图片中)时,我的点击监听器的$(this)将始终引用第一个div。我知道这是因为,当我打印ID时,即使单击了第三个通知div,它也会打印第一个通知div的ID。
在其他地方找不到类似的问题。这是相关的jquery代码。我使用的是$(body).on(“ click”)而不是$(“。className”)。click,因为后者不会附加到所需的div,因为div的显示为:none,直到它弹出为止。>
$('body').on("click", ".popover-body .notif-popup-container", function() {
console.log("notif popup container clicked");
// prints <div class="media n-media notif-popup-container notif-display"></div>
console.log($(this)[0]);
// prints {}
console.log($(this).data());
// prints first element's id
console.log($('.notif-popup-container').data("id"));
// prints undefined
console.log($(this).data("id"));
})
这是弹出代码。我注意到,chrome-dev属性中并没有仅针对我的style =“ display:none” divs显示data-id属性。这些div会插入到弹出式标题和内容的选项中,因此必须将其隐藏。
$(document).ready(function(){
$("#notificationsBell").popover({
'title' : $('.notifications-title-header').html(), // display:none for html div
'html' : true,
'placement' : 'left',
'content' : $(".notifications-list").html() // display:none for this as well
});
});
JS可能会给出一些提示。使用Rails进行构建,但这似乎无关紧要。任何见识都表示赞赏。
编辑:没有得到第一个div,它得到了正确的div。只是没有保留data-id属性。现在,我将其存储在“ id”属性中,该属性将显示在chrome开发工具上。我仍然想知道为什么data-id不显示,而id属性显示。
编辑2:这是相关的html代码:
<%= link_to "javascript:void(0);", class: "dropdown-toggle", id: "notificationsBell" do %>
<i class="fa fa-bell dropdown-toggle" aria-hidden="true"></i>
<span id="notifUnreadCount">
<%= Notification.unread_count(current_user) %>
</span>
<% end %>
<div style="display:none" class="notifications-title-header" data-id="sup">
<p class="notifications-title">
Notifications
<span class="see-all-notifs"><u><%= link_to "See all", notifications_path %></u></span>
</p>
</div>
<div style="display:none" class="notifications-list">
<% unread_notifications = Notification.unread_count(current_user) %>
<% if unread_notifications === 0 %>
No notifications to display! You are up to date.
<% else %>
<% notifs = current_user.notifications.where(read_at: nil).order("created_at DESC") %>
<% notifs.each do |notif| %>
<div class="media n-media notif-popup-container notif-display" id=<%= notif.id %> >
<%= image_tag "bell.svg", class: "notification-icon-small mr-3" %>
<div class="media-body noti-info">
<b><p><%= notif.notify_type %></p></b>
<span class="n-date trans-timestamp dateTime" data-momentiz="(<%= notif.momentize %>)"></span>
<p><%= notif.message %></p>
</div>
<div class="actions">
<% if notif.status == 'pending' && notif.target.present? %>
<%= link_to update_request_wager_path(notif.target.try(:wager), member_id: notif.target_id, type: "accept", notif_id: notif.id), method: :put, class: "btn table-link acceptBtn red-btn-small", data: { confirm: 'Are you sure you want to accept?' } do %>
<i class="fa fa-check" aria-hidden="true"></i>
<% end %>
<%= link_to update_request_wager_path(notif.target.wager, member_id: notif.target_id, type: "reject", notif_id: notif.id), method: :put,class: "btn table-link rejectBtn red-btn-small", data: { confirm: 'Are you sure you want to reject?' } do %>
<i class="fa fa-times" aria-hidden="true"></i>
<% end %>
<% end %>
<%= link_to get_notification_url(notif) + "#" + notif.notify_type.downcase + "Notif", class: "btn red-btn-small" do %>
<i class="fa fa-eye" aria-hidden="true"></i>
<% end %>
</div>
</div>
<% end %>
<% end %>
</div>
答案 0 :(得分:0)
您的意思是,生成的HTML将类似于以下内容...所有div都包含与“ media n-media notif-popup-container notif-display”相同的多个类。单击事件时,必须将任何一个类用作“ .notif-popup-container”或“ .notif-display”,并且此代码才能正常工作。
<div class="media n-media notif-popup-container notif-display" data-id="1">
Content 1
</div>
<div class="media n-media notif-popup-container notif-display" data-id="2">
Content 2
</div>
<div class="media n-media notif-popup-container notif-display" data-id="3">
Content 3
</div>
示例代码片段为
<script>
$(function () {
$('body').on("click", ".notif-popup-container", function () {
console.log($(this).data("id"));
});
});
</script>
或者可以是这样...
<script>
$(function () {
$('body').on("click", ".notif-display", function () {
console.log($(this).data("id"));
});
});
</script>
我希望这会很好...加油
答案 1 :(得分:0)
事件委托是一种编程模式,允许我们通过绑定(又称为注册)事件来监听多个(数量不限)目标标签(例如buttons
,inputs
等)的事件( s)转换为所有目标标签都具有共同祖先的单个标签。我将其称为“共同祖先”-window
,document
和body
始终有效,但在大多数情况下不是最佳选择。
除了在调用堆栈中只有一个事件处理程序外,在页面加载后动态添加到页面的任何目标标签都将对已注册的触发事件做出反应-无法将事件绑定到页面加载后创建的标签。
jQuery .on()
方法在提供实际选择器时委托事件:
$('.btn-group').on('click',...
.btn-group
是绑定到事件的标签(公共祖先),当在其任何后代标签(目标标签)上触发时,将侦听这些事件。在处理程序中有许多引用.btn-group
的方法:
$('.btn-group')
this // Used with plain JavaScript properties and methods
$(this)[0] // As above
$(this).get() // As above
event.currentTarget // As above*
$(this) // Used with jQuery properties and methods
$(event.currentTarget) // As above*
* event.currentTarget
将始终引用绑定到事件的标签,但对于this
并非始终如此。如果将名为event.data
的第二个参数定义为选择器,则this
将引用event.data
。
$('.btn-group').on('click', '.btn-modal', openModal);
$(.btn-modal)
现在也是$(this)
,而不是$('.btn-group')
。 $('.btn-group')
的任何后代标记都将触发click事件,从而调用处理程序函数openModal()
。处理程序将确定哪个标签启动行为或将其忽略。可以通过以下方式引用单击时触发的标签:
事件起源-用户单击,更改,悬停等的标签。
event.target // Used with plain JavaScript properties and methods
this // As above if `event.data` is defined
$(this)[0] // As above
$(this).get() // As above
$(event.target) // Used with jQuery properties and methods
$(this) // As above if `event.data` is defined
event.target
将始终引用用户与之交互(例如单击)的标签。
注意:演示中详细评论了
/*
If there are multiple tags to target
ex. 3 button.btn-modal
Determine the closest parent tag that the target tags have in common.
ex. fieldset.btn-group
Delegate the event to the "common ancestor". Add the handler function
(ie `openModal()`) without the parenthesis.
ex. $('.btn-group').on('click', openModal);
*/
$('.btn-group').on('click', openModal);
/*
Pass thru the event object
Use the event object property .target to determine which tag the user clicked.
Make it into a jQuery object by wrapping it into $(...)
ex. let clicked = $(event.target);
If the clicked tag has a .btn-modal class...
ex. if (clicked.hasClass('btn-modal')) {...
...get the clicked tag data-open value...
ex. let ID = clicked.data('open');
...Finally, use previous value, ID, as a reference to a modal using the Bootstrap
method .modal() to open said modal.*
ex. $('#'+ID).modal();
*/
function openModal(event) {
let clicked = $(event.target);
if (clicked.hasClass('btn-modal')) {
let ID = clicked.data('open');
$('#' + ID).modal();
}
return false;
}
/*
*Note: Patterns involving .btn-modal classes and data-open attributes
are of my own design
*/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
rel="stylesheet">
</head>
<body>
<main class="container">
<section class='row'>
<fieldset class='btn-group btn-group-lg mx-auto mt-5'>
<button class="btn btn-primary btn-modal" data-open="noticeA" type="button">
Notice A
</button>
<button class="btn btn-warning btn-modal" data-open="noticeB" type="button">
Notice B
</button>
<button class="btn btn-danger btn-modal" data-open="noticeC" type="button">
Notice C
</button>
</fieldset>
<dialog id="noticeA" class="modal fade">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<header class="modal-header bg-primary">
<h4 class="modal-title text-white">Notice A</h4>
<button class="close" type="button" data-dismiss="modal">
×
</button>
</header>
<article class="modal-body">
<p class='display-1 text-center'>HEY!</p>
</article>
<footer class="modal-footer">
<button class="close btn btn-primary p-3" type="button" data-dismiss="modal">
Close
</button>
</footer>
</div>
</div>
</dialog>
<dialog id="noticeB" class="modal fade">
<div class="modal-dialog modal-dialog-centered modal-sm">
<div class="modal-content">
<header class="modal-header bg-warning">
<h4 class="modal-title">Notice B</h4>
<button class="close" type="button" data-dismiss="modal">
×
</button>
</header>
<article class="modal-body">
<p class='display-1 text-center'>HEY!</p>
</article>
<footer class="modal-footer">
<button class="close btn btn-warning p-3" type="button" data-dismiss="modal">
Close
</button>
</footer>
</div>
</div>
</dialog>
<dialog id="noticeC" class="modal fade">
<div class="modal-dialog modal-dialog-centered modal-lx">
<div class="modal-content">
<header class="modal-header bg-danger">
<h4 class="modal-title text-white">Notice C</h4>
<button class="close" type="button" data-dismiss="modal">
×
</button>
</header>
<article class="modal-body">
<p class='display-1 text-center'>HEY!</p>
</article>
<footer class="modal-footer">
<button class="close btn btn-danger p-3" type="button" data-dismiss="modal">
Close
</button>
</footer>
</div>
</div>
</dialog>
</section>
</main>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0
/umd/popper.min.js">
</script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js">
</script>
</body>
</html>