如何检测拉动刷新
How to detect Pull to refresh
有很多 "pull to refresh" 插件。我已经测试了其中的 5 个。但是 none 其中 运行 速度很快(尤其是在旧智能手机上)。
检查拉动刷新的最佳(糟糕的用户体验性能和响应能力)方法是什么?
PS: 我不需要任何动画。我只想知道用户是否 "pull to refresh"
性能需要最少的代码
插件和库必须写得尽可能灵活和通用,以解决许多相关问题。这意味着它们总是比您需要的体积大,从而影响性能。这也意味着您永远不必维护该代码。这就是权衡。
如果性能是您的目标,请自行构建。
由于您只需要下拉检测,因此构建一个简单的滑动检测器。
当然,您必须根据自己的需要、OS 的事件属性、事件触发器和您所定位的浏览器进行调整。
简化而来
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
);
你厌倦了这些解决方案吗?
你需要检查这个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 可能会对您有所帮助
一个简单的方法:
$(document.body).pullToRefresh(function() {
setTimeout(function() {
$(document.body).pullToRefreshDone();
}, 2000);
});
这个呢?
var lastScrollPosition = 0;
window.onscroll = function(event)
{
if((document.body.scrollTop >= 0) && (lastScrollPosition < 0))
{
alert("refresh");
}
lastScrollPosition = document.body.scrollTop;
}
如果您的浏览器没有负向滚动,那么您可以将第 4 行替换为如下内容:
if((document.body.scrollTop == 0) && (lastScrollPosition > 0))
或者,对于 android 设备,您可以将 lastScrollPosition
换成 "ontouchmove" 或其他手势事件。
我知道很多人已经回答了这个答案,但它可能会对某些人有所帮助。
它基于 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
var container = document.querySelector(
".pull-to-refresh-content-container"
)
container.onmousedown = (ev) => {
mouseY = ev.pageY
startMouseY = mouseY
container.onmousemove = (e) => {
if (e.pageY > mouseY) {
var d = e.pageY - startMouseY
console.log("d: " + d)
container.style.marginTop = d / 4 + "px"
if (d >= 300) {
// alert("load more content");
}
} else {
container.onmousemove = null
}
}
}
container.onmouseup = (ev) => {
container.style.marginTop = "0px"
container.onmousemove = null
}
container.onmouseleave = (ev) => {
container.style.marginTop = "0px"
container.onmousemove = null
}
container.ontouchstart = (ev) => {
mouseY = ev.touches[0].pageY
startMouseY = mouseY
container.ontouchmove = (e) => {
if (e.touches[0].pageY > mouseY) {
var d = e.touches[0].pageY - startMouseY
console.log("d: " + d)
container.style.marginTop = d / 4 + "px"
if (d >= 300) {
// alert("load more content");
}
} else {
container.onmousemove = null
}
}
}
container.ontouchcancel = (ev) => {
container.style.marginTop = "0px"
container.onmousemove = null
}
container.ontouchend = (ev) => {
container.style.marginTop = "0px"
container.onmousemove = null
}
</script>
</body>
</html>
以下是我使用 Stimulus 和 Turbolinks 的方法:
观看视频:https://imgur.com/a/qkzbhZS
import { Controller } from "stimulus"
import Turbolinks from "turbolinks"
export default class extends Controller {
static targets = ["logo", "refresh"]
touchstart(event) {
this.startPageY = event.changedTouches[0].pageY
}
touchmove(event) {
if (this.willRefresh) {
return
}
const scrollTop = document.documentElement.scrollTop
const dy = event.changedTouches[0].pageY - this.startPageY
if (scrollTop === 0 && dy > 0) {
this.logoTarget.classList.add("hidden")
this.refreshTarget.classList.remove("hidden")
if (dy > 360) {
this.willRefresh = true
this.refreshTarget.classList.add("animate-spin")
this.refreshTarget.style.transform = ""
} else {
this.refreshTarget.classList.remove("animate-spin")
this.refreshTarget.style.transform = `rotate(${dy}deg)`
}
} else {
this.logoTarget.classList.remove("hidden")
this.refreshTarget.classList.add("hidden")
this.refreshTarget.classList.remove("animate-spin")
this.refreshTarget.style.transform = ""
}
}
touchend(event) {
if (this.willRefresh) {
Turbolinks.visit(window.location.toString(), { action: 'replace' })
} else {
this.logoTarget.classList.remove("hidden")
this.refreshTarget.classList.add("hidden")
this.refreshTarget.classList.remove("animate-spin")
this.refreshTarget.style.transform = ""
}
}
}
body(class="max-w-md mx-auto" data-controller="pull-to-refresh" data-action="touchstart@window->pull-to-refresh#touchstart touchmove@window->pull-to-refresh#touchmove touchend@window->pull-to-refresh#touchend")
= image_tag "logo.png", class: "w-8 h-8 mr-2", "data-pull-to-refresh-target": "logo"
= image_tag "refresh.png", class: "w-8 h-8 mr-2 hidden", "data-pull-to-refresh-target": "refresh"
有很多 "pull to refresh" 插件。我已经测试了其中的 5 个。但是 none 其中 运行 速度很快(尤其是在旧智能手机上)。
检查拉动刷新的最佳(糟糕的用户体验性能和响应能力)方法是什么?
PS: 我不需要任何动画。我只想知道用户是否 "pull to refresh"
性能需要最少的代码
插件和库必须写得尽可能灵活和通用,以解决许多相关问题。这意味着它们总是比您需要的体积大,从而影响性能。这也意味着您永远不必维护该代码。这就是权衡。
如果性能是您的目标,请自行构建。
由于您只需要下拉检测,因此构建一个简单的滑动检测器。 当然,您必须根据自己的需要、OS 的事件属性、事件触发器和您所定位的浏览器进行调整。
简化而来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
);
你厌倦了这些解决方案吗?
你需要检查这个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 可能会对您有所帮助
一个简单的方法:
$(document.body).pullToRefresh(function() {
setTimeout(function() {
$(document.body).pullToRefreshDone();
}, 2000);
});
这个呢?
var lastScrollPosition = 0;
window.onscroll = function(event)
{
if((document.body.scrollTop >= 0) && (lastScrollPosition < 0))
{
alert("refresh");
}
lastScrollPosition = document.body.scrollTop;
}
如果您的浏览器没有负向滚动,那么您可以将第 4 行替换为如下内容:
if((document.body.scrollTop == 0) && (lastScrollPosition > 0))
或者,对于 android 设备,您可以将 lastScrollPosition
换成 "ontouchmove" 或其他手势事件。
我知道很多人已经回答了这个答案,但它可能会对某些人有所帮助。
它基于 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
var container = document.querySelector(
".pull-to-refresh-content-container"
)
container.onmousedown = (ev) => {
mouseY = ev.pageY
startMouseY = mouseY
container.onmousemove = (e) => {
if (e.pageY > mouseY) {
var d = e.pageY - startMouseY
console.log("d: " + d)
container.style.marginTop = d / 4 + "px"
if (d >= 300) {
// alert("load more content");
}
} else {
container.onmousemove = null
}
}
}
container.onmouseup = (ev) => {
container.style.marginTop = "0px"
container.onmousemove = null
}
container.onmouseleave = (ev) => {
container.style.marginTop = "0px"
container.onmousemove = null
}
container.ontouchstart = (ev) => {
mouseY = ev.touches[0].pageY
startMouseY = mouseY
container.ontouchmove = (e) => {
if (e.touches[0].pageY > mouseY) {
var d = e.touches[0].pageY - startMouseY
console.log("d: " + d)
container.style.marginTop = d / 4 + "px"
if (d >= 300) {
// alert("load more content");
}
} else {
container.onmousemove = null
}
}
}
container.ontouchcancel = (ev) => {
container.style.marginTop = "0px"
container.onmousemove = null
}
container.ontouchend = (ev) => {
container.style.marginTop = "0px"
container.onmousemove = null
}
</script>
</body>
</html>
以下是我使用 Stimulus 和 Turbolinks 的方法:
观看视频:https://imgur.com/a/qkzbhZS
import { Controller } from "stimulus"
import Turbolinks from "turbolinks"
export default class extends Controller {
static targets = ["logo", "refresh"]
touchstart(event) {
this.startPageY = event.changedTouches[0].pageY
}
touchmove(event) {
if (this.willRefresh) {
return
}
const scrollTop = document.documentElement.scrollTop
const dy = event.changedTouches[0].pageY - this.startPageY
if (scrollTop === 0 && dy > 0) {
this.logoTarget.classList.add("hidden")
this.refreshTarget.classList.remove("hidden")
if (dy > 360) {
this.willRefresh = true
this.refreshTarget.classList.add("animate-spin")
this.refreshTarget.style.transform = ""
} else {
this.refreshTarget.classList.remove("animate-spin")
this.refreshTarget.style.transform = `rotate(${dy}deg)`
}
} else {
this.logoTarget.classList.remove("hidden")
this.refreshTarget.classList.add("hidden")
this.refreshTarget.classList.remove("animate-spin")
this.refreshTarget.style.transform = ""
}
}
touchend(event) {
if (this.willRefresh) {
Turbolinks.visit(window.location.toString(), { action: 'replace' })
} else {
this.logoTarget.classList.remove("hidden")
this.refreshTarget.classList.add("hidden")
this.refreshTarget.classList.remove("animate-spin")
this.refreshTarget.style.transform = ""
}
}
}
body(class="max-w-md mx-auto" data-controller="pull-to-refresh" data-action="touchstart@window->pull-to-refresh#touchstart touchmove@window->pull-to-refresh#touchmove touchend@window->pull-to-refresh#touchend")
= image_tag "logo.png", class: "w-8 h-8 mr-2", "data-pull-to-refresh-target": "logo"
= image_tag "refresh.png", class: "w-8 h-8 mr-2 hidden", "data-pull-to-refresh-target": "refresh"