我决定在我的应用程序中集成一个动画对象(FX
),用于两个可点击元素的下拉动作,之后我写了一个可重用的函数来触发各个元素的下拉动作。
但是我似乎无法将动画对象的fadeIn
和fadeOut
方法调用到我的可重用dropdownFunction
中。
如何从dropdownFunction
?
导航栏(html.erb
)
<header>
<div class="dropdown">
<div onclick="dropdownFunction('current-user');" class="button-sign-out">
<%= gravatar_for current_user %>
</div>
<div id="current-user" class="dropdown-content">
<ul>
<li><%= link_to "#{current_user.name.truncate(13)}", user_path(current_user) %></li>
<li><%= link_to "Settings", edit_user_path(current_user) %></li>
<li><%= link_to "Sign out", logout_path, method: "delete" %></li>
</ul>
</div>
</div>
<div class="container">
<div class="row">
<h1><%= link_to "threadly", views_path %></h1>
</div>
</div>
<%= link_to new_view_path do %>
<div class="button-terrance">
terrance
</div>
<% end %>
<%= link_to users_path do %>
<div class="button-discover tool-tip-up">
<i class="fa fa-compass" aria-hidden="true"></i>
<span class="tool-tip-text">Discover</span>
</div>
<% end %>
<div class="dropdown-container" data-behavior="notifications" data-notifications='<%= render template: "notifications/index", formats: [:json] %>'> <!-- wrapper -->
<div onclick="dropdownFunction('notification');" class="button-notification" data-behavior="notifications-link" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-bell" aria-hidden="true"></i>
<div class="count" data-behavior="unread-count"></div>
</div>
<div class="notification-bell dropdown-content-notification-items" id="notification" data-behavior="notification-items">
<!-- Notifications -->
</div>
</div>
<%= form_tag(users_path, :method => "get", id: "search-form") do %>
<%= text_field_tag :search, params[:search], autocomplete: :off,
class: "user-search", spellcheck: false, placeholder: "Search" %>
<% end %>
</header>
综合动画类(.js
)
// Animations FX Class
(function() {
var FX = {
easing: {
linear: function(progress) {
return progress;
},
quadratic: function(progress) {
return Math.pow(progress, 2);
},
swing: function(progress) {
return 0.5 - Math.cos(progress * Math.PI) / 2;
},
circ: function(progress) {
return 1 - Math.sin(Math.acos(progress));
},
back: function(progress, x) {
return Math.pow(progress, 2) * ((x + 1) * progress - x);
},
bounce: function(progress) {
for (var a = 0, b = 1, result; 1; a += b, b /= 2) {
if (progress >= (7 - 4 * a) / 11) {
return -Math.pow((11 - 6 * a - 11 * progress) / 4, 2) + Math.pow(b, 2);
}
}
},
elastic: function(progress, x) {
return Math.pow(2, 10 * (progress - 1)) * Math.cos(20 * Math.PI * x / 3 * progress);
}
},
animate: function(options) {
var start = new Date();
var id = setInterval(function() {
var timePassed = new Date() - start;
var progress = timePassed / options.duration;
if (progress > 1) {
progress = 1;
}
options.progress = progress;
var delta = options.delta(progress);
options.step(delta);
if (progress === 1) {
clearInterval(id);
options.complete;
}
}, options.delay || 10);
},
fadeOut: function(element, options) {
var to = 1;
var target = document.getElementById(element);
this.animate({
duration: options.duration,
delta: function(progress) {
progress = this.progress;
return FX.easing.swing(progress);
},
complete: options.complete,
step: function(delta) {
target.style.opacity = to - delta;
}
});
},
fadeIn: function(element, options) {
var to = 0;
var target = document.getElementById(element);
this.animate({
duration: options.duration,
delta: function(progress) {
progress = this.progress;
return FX.easing.swing(progress);
},
complete: options.complete,
step: function(delta) {
target.style.opacity = to + delta;
}
});
}
};
window.FX = FX;
})();
可重复使用的下拉功能(.js
)
var dropdownElements = ["notification", "current-user"];
// OnClick event toggles between hiding and showing the dropdown content
function dropdownFunction(element) {
for (var dropdownElement in dropdownElements) {
if (dropdownElements[dropdownElement] !== element) {
document.getElementById(dropdownElements[dropdownElement]).style.display = "none";
}
}
// My attempt at calling the methods
document.getElementById(element).style.display === "block" ? FX.fadeOut(element) : FX.fadeIn(element);
// Close the dropdown if the user clicks outside of it
window.onclick = ev => {
if (!ev.target.matches(element)) {
document.getElementById(element).style.display = "none";
}
};
}