How to take a screenshot of a web page by using Javascript
In the end, I ended up using server side generation of screenshots with phantomjs. Found it the most reliable in my scenario and it takes pretty decent screenshots.
how to capture screenshot in html using js or jquery
Web pages are not the best things to be "screenshoted", because of their nature; they can include async elements, frames or something like that, they are usually responsive etc...
For your purpose the best way is to use external api or an external service, I think is not a good idea to try doing that with JS.
You should try url2png
Generate and Download Screenshot of webpage without lossing the styles
You can achieve this using the following JavaScript libraries ...
- html2canvas ( for taking screenshot of webpage )
- FileSave.js ( for downloading the screenshot as an image )
ᴅᴇᴍᴏ
(function(exports) {
function urlsToAbsolute(nodeList) {
if (!nodeList.length) {
return [];
}
var attrName = 'href';
if (nodeList[0].__proto__ === HTMLImageElement.prototype || nodeList[0].__proto__ === HTMLScriptElement.prototype) {
attrName = 'src';
}
nodeList = [].map.call(nodeList, function(el, i) {
var attr = el.getAttribute(attrName);
if (!attr) {
return;
}
var absURL = /^(https?|data):/i.test(attr);
if (absURL) {
return el;
} else {
return el;
}
});
return nodeList;
}
function screenshotPage() {
var wrapper = document.getElementById('wrapper');
html2canvas(wrapper, {
onrendered: function(canvas) {
canvas.toBlob(function(blob) {
saveAs(blob, 'myScreenshot.png');
});
}
});
}
function addOnPageLoad_() {
window.addEventListener('DOMContentLoaded', function(e) {
var scrollX = document.documentElement.dataset.scrollX || 0;
var scrollY = document.documentElement.dataset.scrollY || 0;
window.scrollTo(scrollX, scrollY);
});
}
function generate() {
screenshotPage();
}
exports.screenshotPage = screenshotPage;
exports.generate = generate;
})(window);
@import url(https://fonts.googleapis.com/css?family=Merriweather);
$red: #e74c3c;
*,
*:before,
*:after {
@include box-sizing(border-box);
}
html,
body {
background: #f1f1f1;
font-family: 'Merriweather', sans-serif;
padding: 1em;
}
h1 {
text-align: center;
color: #a8a8a8;
@include text-shadow(1px 1px 0 rgba(white, 1));
}
form {
border: 2px solid blue;
margin: 20px auto;
max-width: 600px;
padding: 5px;
text-align: center;
}
input,
textarea {
border: 0;
outline: 0;
padding: 1em;
@include border-radius(8px);
display: block;
width: 100%;
margin-top: 1em;
font-family: 'Merriweather', sans-serif;
@include box-shadow(0 1px 1px rgba(black, 0.1));
resize: none;
&:focus {
@include box-shadow(0 0px 2px rgba($red, 1)!important);
}
}
#input-submit {
color: white;
background: $red;
cursor: pointer;
&:hover {
@include box-shadow(0 1px 1px 1px rgba(#aaa, 0.6));
}
}
textarea {
height: 126px;
}
}
.half {
float: left;
width: 48%;
margin-bottom: 1em;
}
.right {
width: 50%;
}
.left {
margin-right: 2%;
}
@media (max-width: 480px) {
.half {
width: 100%;
float: none;
margin-bottom: 0;
}
}
/* Clearfix */
.cf:before,
.cf:after {
content: " ";
/* 1 */
display: table;
/* 2 */
}
.cf:after {
clear: both;
}
.half.left.cf > input {
margin: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<div id="wrapper">
<h1>Scrrenshot</h1>
<form class="cf">
<div class="half left cf">
<input type="text" id="input-name" placeholder="Name">
<input type="email" id="input-email" placeholder="Email address">
<input type="text" id="input-subject" placeholder="Subject">
</div>
<div class="half right cf">
<textarea name="message" type="text" id="input-message" placeholder="Message"></textarea>
</div>
<input type="submit" value="Submit" id="input-submit">
</form>
</div>
<a class="btn btn-success" href="javascript:void(0);" onclick="generate();">Generate Screenshot »</a>
How to take a screenshot of a webpage using html5, without rendering it on a canvas via JS
This is simpler than it seemed. The missing part, saving a still shot of the video to png, can be achieved with code from this answer. The complete code would be as follows:
const v = document.getElementById("v");
const b = document.getElementById("b");
const i = document.getElementById("i");
navigator.mediaDevices.getDisplayMedia({
audio: false
}).then((r) => {
console.log(r);
v.srcObject = r;
}).catch((e) => {
console.log("this must be run in a secure context. Stack snippets (rightfully) refuse to run this.");
});
b.onclick = () => {
// take screenshot
// from https://stackoverflow.com/a/44325898/15472
let scale = 1;
const canvas = document.createElement("canvas");
canvas.width = v.clientWidth * scale;
canvas.height = v.clientHeight * scale;
canvas.getContext('2d').drawImage(v, 0, 0,
canvas.width, canvas.height);
i.src = canvas.toDataURL();
// you can send i.src here to a server
// stop video
let tracks = v.srcObject.getTracks();
tracks.forEach(track => track.stop());
v.srcObject = null;
}
#v,
#i {
width: 400;
height: 300;
}
#v {
border: 1px solid blue;
}
#i {
border: 1px solid green;
}
<div>
<video id="v" autoplay></video>
<button id="b">take screenshot</button>
<img id="i" src="//:0" />
</div>
Take a screenshot of a webpage with JavaScript?
I have done this for an HTA by using an ActiveX control. It was pretty easy to build the control in VB6 to take the screenshot. I had to use the keybd_event API call because SendKeys can't do PrintScreen. Here's the code for that:
Declare Sub keybd_event Lib "user32" _
(ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
Public Const CaptWindow = 2
Public Sub ScreenGrab()
keybd_event &H12, 0, 0, 0
keybd_event &H2C, CaptWindow, 0, 0
keybd_event &H2C, CaptWindow, &H2, 0
keybd_event &H12, 0, &H2, 0
End Sub
That only gets you as far as getting the window to the clipboard.
Another option, if the window you want a screenshot of is an HTA would be to just use an XMLHTTPRequest to send the DOM nodes to the server, then create the screenshots server-side.
Take screenshot of the whole webpage
It's wasn't easy but for the other people look to the browser engine.
Because thanks to the use of the blob (kindly clone the whole webpage).
urlsToAbsolute(document.images);
urlsToAbsolute(document.querySelectorAll("link[rel='stylesheet']"));
urlsToAbsolute(document.scripts);
var screenshot = document.documentElement.cloneNode(true);
var blob = new Blob([screenshot.outerHTML], {type: 'text/html'});
window.open(window.URL.createObjectURL(blob));
screenshot.dataset.scrollX = window.scrollX;
screenshot.dataset.scrollY = window.scrollY;
screenshot.style.pointerEvents = 'none';
screenshot.style.overflow = 'hidden';
screenshot.style.userSelect = 'none';
var script = document.createElement('script');
script.textContent = '(' + addOnPageLoad_.toString() + ')();';
screenshot.querySelector('body').appendChild(script);
window.addEventListener('DOMContentLoaded', function(e) {
var scrollX = document.documentElement.dataset.scrollX || 0;
var scrollY = document.documentElement.dataset.scrollY || 0;
window.scrollTo(scrollX, scrollY);
});
I found you can read more in the chromium project:
http://www.html5rocks.com/en/tutorials/streaming/screenshare/
Related Topics
No Visible Cause For "Unexpected Token Illegal"
Backslashes - Regular Expression - JavaScript
Crockford'S Prototypal Inheritance - Issues With Nested Objects
How to Post a File from a Form With Axios
Get Computed Font-Family in JavaScript
How to Make Jquery UI Tabs Scroll Horizontally If There Are Too Many Tabs
Vue.Js - Add Class to Clicked Button
iOS Wkwebview Not Showing JavaScript Alert() Dialog
.Trim() in JavaScript Not Working in Ie
Rotate the Elements in an Array in JavaScript
Take a Screenshot of a Webpage With JavaScript
Graph Visualization Library in JavaScript
JavaScript Call() & Apply() VS Bind()
Iterating Over Result of Getelementsbyclassname Using Array.Foreach
Read CSS Property of an Element Using JavaScript
CSS Selector for Targeting Only Immediate Children and Not Other Identical Descendants