如何检测Pull刷新

时间:2017-09-13 06:35:40

标签: javascript jquery web-applications pull-to-refresh

有许多"拉动刷新"插件。我已经测试了其中的5个。但它们都没有快速运行(特别是在旧智能手机上)。

检查拉动刷新的最佳(黄油用户体验性能和响应性)方法是什么?

PS:我不需要任何动画。我只是想知道用户是否需要刷新"

5 个答案:

答案 0 :(得分:9)

性能需要最少的代码

为了解决许多相关问题,必须编写插件和库以尽可能灵活和通用。这意味着它们总是比您需要的更笨重,从而影响性能。这也意味着您永远不必维护该代码。这是权衡。

如果您的目标是性能,请自行构建。

由于您需要的只是一个下拉检测,因此请构建一个简单的滑动检测器。 当然,您必须根据自己的需求以及您要定位的操作系统和浏览器的事件属性,事件触发器进行调整。

从我原来的js-minimal-swipe-detect

中简化
var pStart = {x: 0, y:0};
var pStop = {x:0, y:0};

function swipeStart(e) {
    if (typeof e['targetTouches'] !== "undefined"){
        var touch = e.targetTouches[0];
        pStart.x = touch.screenX;
        pStart.y = touch.screenY;
    } else {
        pStart.x = e.screenX;
        pStart.y = e.screenY;
    }
}

function swipeEnd(e){
    if (typeof e['changedTouches'] !== "undefined"){
        var touch = e.changedTouches[0];
        pStop.x = touch.screenX;
        pStop.y = touch.screenY;
    } else {
        pStop.x = e.screenX;
        pStop.y = e.screenY;
    }

    swipeCheck();
}

function swipeCheck(){
    var changeY = pStart.y - pStop.y;
    var changeX = pStart.x - pStop.x;
    if (isPullDown(changeY, changeX) ) {
        alert('Swipe Down!');
    }
}

function isPullDown(dY, dX) {
    // methods of checking slope, length, direction of line created by swipe action 
    return dY < 0 && (
        (Math.abs(dX) <= 100 && Math.abs(dY) >= 300)
        || (Math.abs(dX)/Math.abs(dY) <= 0.3 && dY >= 60)
    );
}

document.addEventListener('touchstart', function(e){ swipeStart(e); }, false);
document.addEventListener('touchend', function(e){ swipeEnd(e); }, false);

答案 1 :(得分:1)

你厌倦了这些解决方案吗? 您需要查看此fiddle

var mouseY = 0;
var startMouseY = 0;
$('body').on('mousedown', function (ev) {
    mouseY = ev.pageY;
    startMouseY = mouseY;
    $(document).mousemove(function (e) {
        if (e.pageY > mouseY) {
            var d = e.pageY - startMouseY;
            console.log("d: " + d);
            if (d >= 200)
                location.reload();
            $('body').css('margin-top', d/4 + 'px');
        }
        else
            $(document).unbind("mousemove");


    });
});
$('body').on('mouseup', function () {
    $('body').css('margin-top', '0px');
    $(document).unbind("mousemove");
});
$('body').on('mouseleave', function () {
    $('body').css('margin-top', '0px');
    $(document).unbind("mousemove");
});

如果你正在寻找一些插件this plugin可能会帮助你

答案 2 :(得分:0)

这怎么办?

<Mutation mutation={addReservationMutation}>
      {(addReservation, { data }) => (
        <Button
          title="Reserve your!"
          onPress={() => {
            addReservation({
              variables: {
                data: {
                  name: "Joe",
                  hotelName: "LemonTree",
                  arrivalDate: "06/05/2019",
                  departureDate: "06/12/2019"
               }
              }
            });
          }}
        />
      )}
</Mutation>

如果浏览器没有向下滚动,则可以将第4行替换为以下内容: var lastScrollPosition = 0; window.onscroll = function(event) { if((document.body.scrollTop >= 0) && (lastScrollPosition < 0)) { alert("refresh"); } lastScrollPosition = document.body.scrollTop; }

或者,对于android设备,您可以将if((document.body.scrollTop == 0) && (lastScrollPosition > 0))换成“ ontouchmove”或其他手势事件。

答案 3 :(得分:0)

我知道这个答案已经被很多人所困扰,但它可能对某人有所帮助。 其基于Mr. Pryamid's答案。但他的答案在触摸屏上不起作用。仅适用于鼠标。

此答案在触摸屏和台式机上效果很好。我已经在台式机中的chrome和android中的chrome中进行了测试

<!DOCTYPE html>
<html>
<head>
<style>
*{
    margin: 0;
    padding: 0;
}

html, body {
    width: 100%;
    height: 100%;
}

.pull-to-refresh-container {
    width: 100%;
    height: 100%;
    background-color: yellow;
    position: relative;
}

.pull-to-refresh-content-container {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: white;
    margin: 0px;
    text-align: center;
}
</style>
</head>
<body>

<div class="pull-to-refresh-container">
    <div class="pull-to-refresh-loader-container">
        loading ...
    </div>
    <div class="pull-to-refresh-content-container">
        here lies the content
    </div>
</div>

<script>
var mouseY = 0;
var startMouseY = 0;

document.querySelector(".pull-to-refresh-content-container").onmousedown = (ev) => {
    mouseY = ev.pageY;
    startMouseY = mouseY;
    document.querySelector(".pull-to-refresh-content-container").onmousemove = (e) => {
      if (e.pageY > mouseY) {
        var d = e.pageY - startMouseY;
        console.log("d: " + d);
        document.querySelector(".pull-to-refresh-content-container").style.marginTop = d/4 + 'px';
        if (d >= 300){
          // alert("load more content");
        }
      } else {
        document.querySelector(".pull-to-refresh-content-container").onmousemove = null;
      }
    }
};

document.querySelector(".pull-to-refresh-content-container").onmouseup = (ev) => {
    document.querySelector(".pull-to-refresh-content-container").style.marginTop = '0px';
    document.querySelector(".pull-to-refresh-content-container").onmousemove = null;
};

document.querySelector(".pull-to-refresh-content-container").onmouseleave = (ev) => {
    document.querySelector(".pull-to-refresh-content-container").style.marginTop = '0px';
    document.querySelector(".pull-to-refresh-content-container").onmousemove = null;
};
document.querySelector(".pull-to-refresh-content-container").ontouchstart = (ev) => {
    mouseY = ev.touches[0].pageY;
    startMouseY = mouseY;
    document.querySelector(".pull-to-refresh-content-container").ontouchmove = (e) => {
      if (e.touches[0].pageY > mouseY) {
        var d = e.touches[0].pageY - startMouseY;
        console.log("d: " + d);
        document.querySelector(".pull-to-refresh-content-container").style.marginTop = d/4 + 'px';
        if (d >= 300){
          // alert("load more content");
        }
      } else {
        document.querySelector(".pull-to-refresh-content-container").onmousemove = null;
      }
    }
};

document.querySelector(".pull-to-refresh-content-container").ontouchcancel = (ev) => {
    document.querySelector(".pull-to-refresh-content-container").style.marginTop = '0px';
    document.querySelector(".pull-to-refresh-content-container").onmousemove = null;
};

document.querySelector(".pull-to-refresh-content-container").ontouchend = (ev) => {
    document.querySelector(".pull-to-refresh-content-container").style.marginTop = '0px';
    document.querySelector(".pull-to-refresh-content-container").onmousemove = null;
};

</script>

</body>
</html>

答案 4 :(得分:-1)

一个简单的方法:

&#13;
&#13;
struct Data_t
{
   int num_;
   //... some other data
}

template<typename ConnectionHandler>
class Server {
    using shared_handler_t = std::shared_ptr<ConnectionHandler>;
public:
    Server(int thread_count = 10) :
            thread_count_(thread_count), acceptor_(io_service_)
    void
    start_server(uint16_t port) {
        auto handler = std::make_shared<ConnectionHandler>(io_service_, configer_, thread_names_);
        // set up the acceptor to listen on the tcp port
        boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port);
        acceptor_.open(endpoint.protocol());
        boost::system::error_code ec;
        acceptor_.bind(endpoint);
        acceptor_.listen();
        acceptor_.async_accept(handler->socket(),
                               [=](boost::system::error_code const &ec) {
                                   handle_new_connection(handler, ec);
                               }); 
        // start pool of threads to process the asio events
        for (int i = 0; i < thread_count_; ++i) {
            thread_pool_.emplace_back([=] { io_service_.run(); });
        }
        // Wait for all threads in the pool to exit.
        for (std::size_t i = 0; i < thread_pool_.size(); ++i) {
            thread_pool_[i].join();
        }
    }
private:
    void
    handle_new_connection(shared_handler_t handler,
                          boost::system::error_code const &error) {
        if (error) {
            return;
        }
        handler->start();
        auto new_handler = std::make_shared<ConnectionHandler>(io_service_);
        acceptor_.async_accept(new_handler->socket(),
                               [=](boost::system::error_code const &ec) {
                                   handle_new_connection(new_handler, ec);
                               });
    }
    int thread_count_;
    std::vector<std::thread> thread_pool_;
    boost::asio::io_service io_service_;
    boost::asio::ip::tcp::acceptor acceptor_;
};


class ConnectionHandler : public std::enable_shared_from_this<ConnectionHandler> {
 public:
  ConnectionHandler (boost::asio::io_service &service) :
      service_ (service), socket_ (service)
  {
  }
  void
  start ()
  {
    read_packet ();
  }

 private:
  void
  read_packet ()
  {
    auto me = shared_from_this ();
    boost::asio::async_read (
        socket_, boost::asio::buffer (&received_data_, sizeof (Data_t)),
        boost::asio::transfer_exactly (sizeof (Data_t)),
        [me] (boost::system::error_code const &ec, std::size_t bytes_xfer)
        {
            me->process_data (ec, bytes_xfer);
        });

  }
  void
  process_data (boost::system::error_code const &error,
                    std::size_t bytes_transferred)
  {
    if (error)
      {
        socket_.close ();
        return;
      }
    total_sum_+=received_data_.num_;
    read_packet ();
  }
  boost::asio::io_service &service_;
  boost::asio::ip::tcp::socket socket_;
  Data_t received_data_;
  int total_sum_;
};
&#13;
&#13;
&#13;