Javascript 如何从函数调用对象的方法?

Javascript 如何从函数调用对象的方法?,javascript,ruby-on-rails,Javascript,Ruby On Rails,我决定在我的应用程序中集成一个动画对象(FX),用于两个可单击元素的下拉操作,后来我编写了一个可重用函数来触发相应元素的下拉操作。 但是,我似乎无法将动画对象的fadeIn和fadeOut方法调用到可重用的下拉函数中。 如何从我的下拉函数成功调用对象方法 导航栏(html.erb) 可重复使用的下拉功能(.js) 您是否尝试过window.FX.fadeOut()在FX类的底部获得window.FX=FX是的,现在刚试过。还是没用。那不是一门课。这只是一个包含分配给全局函数的函数。我真的建议不要

我决定在我的应用程序中集成一个动画对象(
FX
),用于两个可单击元素的下拉操作,后来我编写了一个可重用函数来触发相应元素的下拉操作。 但是,我似乎无法将动画对象的
fadeIn
fadeOut
方法调用到可重用的
下拉函数中。
如何从我的
下拉函数
成功调用对象方法

导航栏(
html.erb

可重复使用的下拉功能(
.js


您是否尝试过
window.FX.fadeOut()
FX
类的底部获得
window.FX=FX是的,现在刚试过。还是没用。那不是一门课。这只是一个包含分配给全局函数的函数。我真的建议不要在2017年重新发明轮子和创建基于javascript的动画库。从性能角度来看,使用基于CSS的动画更好,因为它们利用了GPU。您在控制台中看到了什么?在调用它的方法时是否定义了FX?至于为什么
window.FX
可能不可用,这取决于包含javascript的顺序。如果您使用的是Spockets和
//=require\u tree。
文件将按字母顺序包含在清单中。如果您的代码依赖于特定的顺序,则显式要求更好。请添加
layout.html.erb
部分和
application.js
或任何链接到的文件。您是否尝试过
window.FX.fadeOut()
FX
类的底部
window.FX=FX是的,现在刚试过。还是没用。那不是一门课。这只是一个包含分配给全局函数的函数。我真的建议不要在2017年重新发明轮子和创建基于javascript的动画库。从性能角度来看,使用基于CSS的动画更好,因为它们利用了GPU。您在控制台中看到了什么?在调用它的方法时是否定义了FX?至于为什么
window.FX
可能不可用,这取决于包含javascript的顺序。如果您使用的是Spockets和
//=require\u tree。
文件将按字母顺序包含在清单中。如果您的代码依赖于特定的顺序,则显式要求更好。请添加您的
layout.html.erb
部分和
application.js
或您链接到的任何文件。
 <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>
// 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;
})();
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";
        }
    };
}