jQuery动画“完全”回调过早发射

时间:2015-10-13 10:52:09

标签: javascript jquery animation

根据jQuery documentation @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.fragment_chatlist, menu); } @Override public void onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); inboxMenuItem = menu.findItem(R.id.menu_search); inboxMenuItem.setActionView(R.layout.menu_item_chatlist); settingsMenuItem = menu.findItem(R.id.mainMenu); settingsMenuItem.setActionView(R.layout.menu_item_settings); if (null != animationWatcher && animationWatcher.getPendingAnimation() == true) { animationWatcher.upatePendingAnimation(false); startIntroAnimation(); } SearchView searchView = (SearchView) inboxMenuItem.getActionView(); searchView.setOnSearchClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ((ChatListActivity) getActivity()).setLogoVisibility(false); } }); searchView.setOnCloseListener(new SearchView.OnCloseListener() { @Override public boolean onClose() { ((ChatListActivity) getActivity()).setLogoVisibility(true); return false; } }); settingsMenuItem.getActionView().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ChatList.this.onOptionsItemSelected(settingsMenuItem); ((ChatListActivity) (getActivity())).toolbar.showOverflowMenu(); ((ChatListActivity) (getActivity())).openOptionsMenu(); } }); } 有一个名为'Complete'的参数,只有在动画结束后才能触发。不幸的是,我发现在动画开始之前它会触发

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/menu_search"
        app:showAsAction="always"
        android:title="@string/search"
        />


    <item
        android:id="@+id/mainMenu"
        android:title="Text"
        android:orderInCategory="101"
        app:showAsAction="always">
        <menu>

            <item
                android:id="@+id/menu_tag"
                android:icon="@drawable/tag_icon"
                app:showAsAction="always|withText"
                android:title="Tags"/>
            <item
                android:id="@+id/menu_profile"
                android:icon="@drawable/profile_image_50"
                app:showAsAction="always|withText"
                android:title="Profile"/>
        </menu>
    </item>

</menu>

JSFiddle显示问题: http://jsfiddle.net/JohnnyWalkerDesign/5zu90ygz/

我错过了什么?

2 个答案:

答案 0 :(得分:7)

已经接受了答案,但我不认为它解释得很好,解决方案会增加不必要的补充,所以这里还有更多信息。

callback参数应为function pointer。它现在不是经常使用的术语,但它意味着您传递函数本身,而不是函数的结果

这是什么意思?

举个例子:

function message(q) {
    alert(q);
}

这里,message是一个功能。要将该函数作为callback传递,请使用函数的名称,例如:

setTimeout(message, 100);
$("#id").click(message);

请注意,函数名称后面没有()

在javascript术语中,函数本身是一个变量,你传递变量,但是一旦添加(),你就调用函数并传递结果,而不是函数本身。

如果你使用message(),那么该函数将被执行,而函数的结果将作为callback传递,即:

setTimeout(message("x"), 100);

相当于:

var x = message("x");
setTimeout(x, 100);

因此,您可以从此代码中看到为什么消息会立即运行(对于单击事件或更长的超时更明显)。

格式setTimeout(message, 100);经常不被用作a)它看起来像一个拼写错误(应该是message()?)和b)它不允许你通过一个参数,所以这经常写成:

setTimeout(function() { message("x") }, 100);

使用匿名内联函数作为callback变量/函数指针。

回答问题:

original fiddle中,您需要做的就是将callback更改为真callback,而无需添加单独的参数,即:

$('#scroll').on('click', function(e) {
    e.preventDefault;
    scrollToTop(function() { message("Reached Top")});
});

更新了小提琴:http://jsfiddle.net/5zu90ygz/9/

答案 1 :(得分:6)

在语句message中将其注册为回调时,您正在调用函数scrollToTop(message('Reached Top'));。这里将调用函数message,并将返回的值传递给scrollToTop函数。

Updated Fiddle

您可以将额外参数传递给函数scrollToTop,即要显示的消息,然后在动画完成后将此消息转发到message函数。

&#13;
&#13;
// Scroll to the top and fire callback
function scrollToTop(callback, message) {
  // Send the message as the second parameter

  if ($('html').scrollTop()) {
    $('html').animate({
      scrollTop: 0
    }, function() {
      // Call the callback function with the message as param after completion of animate
      callback(message)
    });
    return;
  }

  if ($('body').scrollTop()) {
    $('body').animate({
      scrollTop: 0
    }, function() {
      // Call the callback function with the message as param after completion of animate
      callback(message)
    });
    return;
  }

  callback(message);
}

// Dummy callback function to fire
function message(q) {
  alert(q);
}

// On click event
$('#scroll').on('click', function(e) {
  e.preventDefault;
  
  // Add message as second parameter
  scrollToTop(message, "Reached Top! Yay!");
});
&#13;
div {
  width: 100%;
  border: 1px solid black;
  height: 200px;
  margin: 10px 0;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<a href="#" id="scroll">Scroll to top</a>
&#13;
&#13;
&#13;