Skip to content

Instantly share code, notes, and snippets.

@orhanveli
Last active September 27, 2019 10:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save orhanveli/78a162e3a3d795eaf9d6778f97befcad to your computer and use it in GitHub Desktop.
Save orhanveli/78a162e3a3d795eaf9d6778f97befcad to your computer and use it in GitHub Desktop.
react-native-webview auto height and link click handler via window.postMessage
import React, { FunctionComponent, useState } from "react";
import { WebView, WebViewProps } from "react-native-webview";
import { WebViewNavigation } from "react-native-webview/lib/WebViewTypes";
interface HtmlRendererProps extends WebViewProps {
html: string;
width: number;
height?: number;
}
const srcpt = ` (function(window) {
'use strict';
var doc = window.document;
var clickHandler = (e) => {
e.preventDefault();
window.ReactNativeWebView.postMessage(e.target.attributes["href"].value);
e.stopPropagation();
}
var i = 0;
function updateHeight(height) {
doc.title = height;
window.location.hash = ++i;
}
setTimeout(() => {
var links = doc.querySelectorAll("a");
for (var i = 0; i < links.length; i++) {
links[i].addEventListener('click', clickHandler, false);
}
var h = doc.querySelector(".html-wrapper").clientHeight;
updateHeight(h);
}, 100);
})(window);
true;`;
const formatHtml = (html: string) => {
return `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="html-wrapper">
${html}
</div>
</body>
</html>
`;
};
const HtmlRenderer: FunctionComponent<HtmlRendererProps> = (props) => {
const [finalHeight, setFinalHeight] = useState<number>(!props.height ? props.html.length / 2 : props.height);
const handleNavigationChange = (navState: WebViewNavigation) => {
if (navState.title) {
const realContentHeight = parseInt(navState.title, 10) || 0; // turn NaN to 0
setFinalHeight(realContentHeight);
}
};
if (typeof props.onNavigationStateChange === "function") {
const usersHandler = props.onNavigationStateChange;
props.onNavigationStateChange = (navState: WebViewNavigation) => {
handleNavigationChange(navState);
usersHandler(navState);
};
}
if (props.html) {
if (props.html.indexOf("<body>") < 1) {
props.html = formatHtml(props.html);
}
props.source = { html: props.html };
}
props.style = [props.style, {
width: props.width,
height: finalHeight,
}];
return (
<WebView {...props} />
);
};
export default HtmlRenderer;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment