Recently I was writing a page for an H5, and one of the components used pullToRefresh in ANTD-Mobile. Boy, the car flipped over!
Realize the function
PullToRefresh component is used for pull-up loading of data on the next page to realize continuous loading of data.
Rollover phenomenon
The pullToRefresh component in Chrome on the Web side can be used to load the data on the next page normally, and the H5 embedded in the APP can be accessed by the simulator without any problems. However, when you get to the real machine or open the connection of H5 directly on the real machine, the pullToRefresh will flip over and cannot be pulled up (the function that cannot trigger its pull up operation), which is outrageous!
Trying to reason
Through a variety of local information, finally found in the ANTD-mobile issues of the big guy’s explanation.
The problem is as follows: AntD-Mobile pullToRefresh component trigger pull-up source code is isEdge function in the following code
if (direction === UP) {
return ele.scrollHeight - ele.scrollTop === ele.clientHeight;
}
Copy the code
At first glance, there is no problem, but the height of ele on the mobile terminal is dynamically calculated by REM. The algorithm is:
let remHeight = 2.48 // The height of the element in rem
let __fontUnit = 43.3333 // The pixels represented by 1rem for mobile phones with different resolutions
someElementHeight = remHeight * __fontUnit
Copy the code
Because of the resolution of different mobile phones someElementHeight is the decimal A that may appear decimals, while ele.clientHeight obtained with JS code is always the integer B, Thus, there is an error between the real PX value of someElementHeight and the real value obtained through JS code on different models.
If A
conclusion
Because rem is used, the height (px) dynamically set to the element may be decimal, resulting in ele.scrollheight-ele.scrolltop! = el.clientheight, unable to trigger sliding threshold.
The solution
This paper only gives their own solution may not be the optimal solution, please use as appropriate!
Modify the source code
Ele.scrollheight-ele.scrolltop === ele.clientheight This statement determines the exception caused by the failure to trigger the pull-up refresh operation
So change the source code to
_this2.isEdge = function (ele, direction) {
var container = _this2.props.getScrollContainer();
if (container && container === document.body) {
// In chrome61 `document.body.scrollTop` is invalid
var scrollNode = document.scrollingElement ? document.scrollingElement : document.body;
if (direction === UP) {
return scrollNode.scrollHeight - scrollNode.scrollTop <= window.innerHeight;
}
if (direction === DOWN) {
return scrollNode.scrollTop <= 0; }}if (direction === UP) {
var __height = Math.abs(ele.scrollHeight - ele.scrollTop - ele.clientHeight)// Change the code
return __height>=0 && __height<=1 // Change the code
return ele.scrollHeight - ele.scrollTop === ele.clientHeight; // Source code
}
if (direction === DOWN) {
return ele.scrollTop <= 0; }};Copy the code
Node_modules = antD-mobile = antD-mobile = antD-mobile = antD-mobile = antD-mobile = antD-mobile = antD-mobile
When I asked later, I realized that this is only source code, but the actual code path referenced in the project is in package.json in ANTD-mobile
"main": "lib/index.js"."module": "es/index.js".Copy the code
Whether it’s main or module or even browser we’ll talk about next time or we’ll look into it ourselves, but we’re using module which is es/index, so find out where the pullToRefresh component came from.
export { default as PullToRefresh } from './pull-to-refresh/index';
Copy the code
Go to the es/pull-to-refresh/index.js file
.import RPullToRefresh from 'rmc-pull-to-refresh'; .var PullToRefresh = function (_React$Component) {
_inherits(PullToRefresh, _React$Component);
function PullToRefresh() {... } _createClass(PullToRefresh, [{key: 'render'.value: function render() {...// I'm here
return React.createElement(RPullToRefresh, _extends({}, this.props, { indicator: ind })); }}]);return PullToRefresh;
}(React.Component);
export default PullToRefresh;
Copy the code
RPullToRefresh (rC-pull-to-refresh) {rc-pull-to-refresh (rC-pull-to-refresh) {rc-pull-to-refresh (rC-pull-to-refresh); Then go to the actual referenced PullToRefresh. Js file, modify isEdge, restart the project, and finally fix the problem.
To solve the follow-up
However, only my local modification dependency will appear when the project is pulled by others, the installation dependency is not modified, so we need to solve the problem that everyone can automatically modify the file when the code is pulled.
This problem can be handled in several ways:
- Encapsulate the component itself and reference it directly within the project
- The Colone project re-released the NPM package, but it was a bit of a hassle.
- .
The patch-package plug-in is introduced to patch dependencies
package.json
Add the following code to the package.json file
"scripts": {..."postinstall": "patch-package"
},
Copy the code
Perform patch
NPX patch-package package-name (package name to be changed)Copy the code
It will automatically compare your local file with the clean NPM package to determine the difference between the two pieces of code and record the patch. Patches will be created in the project directory under which the patches will be found. You only need to upload the patch to the code repository, and then everyone who pulls the project installation dependency will automatically patch the dependency package and write your changes into the dependency package.
This is the whole rollover and all the repair process!