EN
JavaScript - paste any data form system clipboard (e.g. image, text, HTML, etc.)
10
points
In this short article we would like to show how to paste any data from system clipboard using JavaScript.
Presented solution lets to paste any content from clipboard, e.g. image, text, HTML, etc. We can limit content type by setting MIME types in the types
array. Clipboard content can be read as plain text (string
), Blob URL (string
), Blob Object, Data URL (string
) or Buffer Object (ArrayBuffer
).
Usage example
var types = [ // types order is verry important providing at first top type
'image/png',
'image/jpeg',
'text/plain',
'text/html',
// etc.
];
var reader = new ClipboardReader(types); // here we expect for clipboard content only according to `types` variable or permit to all when array is empty
// Somewhere in the source code ...
reader.readContent(function(blob, error) {
if (error) {
console.error(error);
return;
}
if (blob) {
console.log('Clipboard content: ' + blob);
return;
}
console.log('Content is not available - copy something to clipboard.');
});
Note: empty
types
array means: we accept all files types.
Full example
// ONLINE-RUNNER:browser;
<!doctype html>
<html>
<body>
<div>Copy to system clipboard some content and click some bellow button to paste it here.</div>
<br />
<button onclick="handleClick()">Paste content</button>
<script>
// Main logic:
function ClipboardReader(types) {
var _types = types || [];
var findType = function(types) {
if (_types.length > 0) {
for (var i = 0; i < _types.length; ++i) {
var type = _types[i];
if (types.includes(type)) {
return type;
}
}
return null;
} else {
return types[0] || null;
}
};
var findItem = function(items) {
for (var i = 0; i < items.length; ++i) {
var item = items[i];
if (item) {
var type = findType(item.types);
if (type) {
return item.getType(type);
}
}
}
return null;
};
this.readContent = function(callback) {
if (navigator.clipboard) {
var promise = navigator.clipboard.read();
promise
.then(function(items) {
var promise = findItem(items);
if (promise == null) { // null or undefined
callback(null, null);
} else {
promise
.then(function(blob) {
callback(blob);
})
.catch(function(error) {
callback(null, error || 'Clipboard reading error.');
});
}
})
.catch(function(error) {
callback(null, error || 'Clipboard reading error.');
});
} else {
callback(null, 'Clipboard API is not supported (or check for permisions).');
}
};
};
// Helper logic:
function createReader(callback) {
var reader = new FileReader();
reader.onload = function() {
callback(reader.result, null);
};
reader.onerror = function() {
callback(null, 'Incorrect file.');
};
return reader;
}
function toPlainText(blob, callback) {
var reader = createReader(callback);
reader.readAsText(blob);
}
function toDataURL(blob, callback) {
var reader = createReader(callback);
reader.readAsDataURL(blob);
}
function toArrayBuffer(blob, callback) {
var reader = createReader(callback);
reader.readAsArrayBuffer(blob);
}
// Usage example:
var types = [ // types order is verry important providing at first top type
'image/png',
'image/jpeg',
'text/plain',
'text/html',
// etc.
];
var reader = new ClipboardReader(types); // here we expect for clipboard content only according to `types` variable or permit to all when array is empty
function handleClick() {
reader.readContent(function(blob, error) {
if (error) {
console.error(error);
return;
}
if (blob) {
toPlainText(blob, function(text, error) {
console.log('Clipboard content as plain text:\n' + text);
});
return;
}
console.log('Content is not available - copy something to clipboard.');
});
}
</script>
</body>
</html>
According to the above logic it is possible to convert Blob
object to:
- Internal URL (Object URL):
const url = URL.createObjectURL(blob); try { // e.g. image.src = url; } finally { URL.revokeObjectURL(url); // releases memory }
- Plain text
toPlainText(blob, function(text, error) { console.log('[plain text]: ' + text); });
- DataURL
toDataURL(blob, function(data, error) { console.log('[DataURL]: ' + data); });
- ArrayBuffer
toArrayBuffer(blob, function(buffer, error) { console.log('[ArrayBuffer]: ' + buffer); });