Setting a file upload field value - Javascript/jQuery [duplicate] - javascript

This question already has answers here:
How to set file input value when dropping file on page? [duplicate]
(1 answer)
How to set File objects and length property at FileList object where the files are also reflected at FormData object?
(1 answer)
Closed 5 years ago.
I have a form page that has a file upload field and I am trying to set the value of that field programmatically and although I know that it isn't possible due to security reasons, I would like to know if we still can? If there is a plugin or something that I could use to perform the upload. I have the Base64 value of the file field that is required to set that field, all I need to know is if there is a way to set it.
Any suggestions or help would be great in this regard.
Thanks.
Update:
Added a JsFiddle to demonstrate what I'm trying out.
Please visit this website to create a text file using the example in the js fiddle and convert it using this link.
var str = `text`;
http://www.motobit.com/util/base64-decoder-encoder.asp
JsFiddle
Note:
The answer(s) below reflect the state of legacy browsers in 2009. Now you can actually set the value of the file input element dynamically/programatically using JavaScript in 2017.
See the answer in this question for details as well as a demo:How to set file input value programatically (i.e.: when drag-dropping files)?

You can convert the base64 string to a blob and then add it to the formData before submitting it with an ajax request:
$("#form").submit(function(e) {
e.preventDefault();
formData = new FormData($(this)[0]);
var blob = dataURLtoBlob("base64 string");
formData.append("yourfile", blob);
$.ajax({
url: "whatever.php",
type: "POST",
data: formData,
contentType: false,
cache: false,
processData: false,
success: function(data) {
alert("Form has been submitted with file");
}
});
dataURLtoBlob is a function that converts the base64 string to the binary file (blob) source: Blob from DataURL?

Update: Added a JsFiddle to demonstrate what I'm trying out.
#seahorsepip Answer, minimally adjusted to substitute success for done which is not a defined $.ajax() setting, and removing trailing ; following done:function(){}, which logs a syntax error, should return expected result. Where convertedvalue at linked jsfiddle at updated Question is also adjusted to a valid data URI. That is, after converting string to base64, use the "data" URL scheme to convert base64 string to valid data URI; e.g.,
"data:text/plain;base64," + convertedvalue
Note, File object created at FormData is requested with GET and returned at success at stacksnippets and jsfiddle to demonstrate file within FormData POSTed by $.ajax()
var convertedvalue = btoa(str); // where `str` is string
$("#form").submit(function(e) {
e.preventDefault();
formData = new FormData($(this)[0]);
// pass valid `data URI` to `dataURItoBlob`
// note `base64` extension
var blob = dataURItoBlob("data:text/plain;base64," + convertedvalue);
formData.append("yourfile", blob);
$.ajax({
url: "/path/to/server",
type: "POST",
data: formData,
contentType: false,
cache: true,
processData: false,
// substitute `success` for `done`
success: function(data) {
//alert("Form has been submitted with file");
} // remove trailing `;`
});
})
var str = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras suscipit pharetra ante, quis tristique elit tempor at. Mauris nec nisi porttitor, sodales nunc facilisis, tempor ligula. Aenean luctus purus id orci commodo, eu ornare erat molestie. Proin viverra semper est, sit amet hendrerit mi. Phasellus sodales auctor ipsum eu fermentum. Quisque ut convallis turpis. Suspendisse et varius lorem. Quisque ipsum metus, venenatis quis aliquam et, lobortis nec purus. Aenean consectetur, tellus in gravida tempor, dui lacus placerat dui, quis dictum libero sapien at diam. Donec eleifend, turpis ac vulputate vulputate, nulla enim vestibulum magna, nec finibus ex urna sed quam. Curabitur vitae felis mi. Suspendisse potenti.
Quisque scelerisque mattis venenatis. Phasellus in varius lectus. Ut ut lorem eu augue convallis vulputate. Ut at tortor leo. Etiam tristique, quam et ultrices commodo, risus mauris mollis nisi, quis condimentum sapien tortor et dolor. Pellentesque sollicitudin velit ut sapien tristique, in mattis est facilisis. Pellentesque et leo massa. Sed pretium faucibus purus ac sodales. Sed varius eros felis, vel posuere metus lobortis id. Maecenas eget cursus ligula. In nec luctus orci. Nunc sed massa elit. Pellentesque iaculis tortor sit amet tellus ultrices, nec tristique lorem semper.
Donec aliquet ipsum ipsum, in consequat nisl euismod nec. Aenean aliquam nisl nec elit convallis pulvinar. Suspendisse ac malesuada ex. Fusce laoreet metus at nulla suscipit, non facilisis dui scelerisque. Maecenas blandit augue et lorem venenatis consequat. In porttitor eros ac elit placerat sodales. Suspendisse facilisis lorem vestibulum ante commodo dignissim. Mauris dignissim egestas massa, sit amet hendrerit orci molestie id. Suspendisse vel enim sit amet massa eleifend accumsan. Curabitur eleifend velit non nisi egestas ornare. Ut congue, eros a condimentum faucibus, risus sapien cursus elit, tempor condimentum nisi nisi vitae leo. Sed quis blandit tellus, in aliquet purus. Pellentesque eget leo lobortis, consectetur nisi non, facilisis lectus. Morbi tortor augue, posuere vel ultrices in, vestibulum vel nibh. Morbi accumsan tellus congue commodo tincidunt.
Curabitur vitae fermentum eros. Sed ex dolor, suscipit in ornare in, sollicitudin ac mi. Phasellus ornare ipsum vel elit mollis convallis. Nunc nec porttitor tellus. Nullam volutpat leo sed dapibus vestibulum. Ut aliquet accumsan nulla, commodo pharetra urna auctor in. In ligula lectus, molestie a libero a, sollicitudin rutrum tellus.
Integer vitae turpis id ligula eleifend laoreet. Morbi molestie libero non interdum pulvinar. Nulla facilisi. Nulla a facilisis velit. Etiam metus felis, fermentum eget massa eu, posuere vestibulum mauris. Donec placerat faucibus sapien, vitae dapibus est dapibus ac. Nam quis elementum eros, a eleifend erat. Sed interdum nisi at rhoncus rutrum. Phasellus vitae arcu a tellus tincidunt mattis.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras suscipit pharetra ante, quis tristique elit tempor at. Mauris nec nisi porttitor, sodales nunc facilisis, tempor ligula. Aenean luctus purus id orci commodo, eu ornare erat molestie. Proin viverra semper est, sit amet hendrerit mi. Phasellus sodales auctor ipsum eu fermentum. Quisque ut convallis turpis. Suspendisse et varius lorem. Quisque ipsum metus, venenatis quis aliquam et, lobortis nec purus. Aenean consectetur, tellus in gravida tempor, dui lacus placerat dui, quis dictum libero sapien at diam. Donec eleifend, turpis ac vulputate vulputate, nulla enim vestibulum magna, nec finibus ex urna sed quam. Curabitur vitae felis mi. Suspendisse potenti.
Quisque scelerisque mattis venenatis. Phasellus in varius lectus. Ut ut lorem eu augue convallis vulputate. Ut at tortor leo. Etiam tristique, quam et ultrices commodo, risus mauris mollis nisi, quis condimentum sapien tortor et dolor. Pellentesque sollicitudin velit ut sapien tristique, in mattis est facilisis. Pellentesque et leo massa. Sed pretium faucibus purus ac sodales. Sed varius eros felis, vel posuere metus lobortis id. Maecenas eget cursus ligula. In nec luctus orci. Nunc sed massa elit. Pellentesque iaculis tortor sit amet tellus ultrices, nec tristique lorem semper.
Donec aliquet ipsum ipsum, in consequat nisl euismod nec. Aenean aliquam nisl nec elit convallis pulvinar. Suspendisse ac malesuada ex. Fusce laoreet metus at nulla suscipit, non facilisis dui scelerisque. Maecenas blandit augue et lorem venenatis consequat. In porttitor eros ac elit placerat sodales. Suspendisse facilisis lorem vestibulum ante commodo dignissim. Mauris dignissim egestas massa, sit amet hendrerit orci molestie id. Suspendisse vel enim sit amet massa eleifend accumsan. Curabitur eleifend velit non nisi egestas ornare. Ut congue, eros a condimentum faucibus, risus sapien cursus elit, tempor condimentum nisi nisi vitae leo. Sed quis blandit tellus, in aliquet purus. Pellentesque eget leo lobortis, consectetur nisi non, facilisis lectus. Morbi tortor augue, posuere vel ultrices in, vestibulum vel nibh. Morbi accumsan tellus congue commodo tincidunt.
Curabitur vitae fermentum eros. Sed ex dolor, suscipit in ornare in, sollicitudin ac mi. Phasellus ornare ipsum vel elit mollis convallis. Nunc nec porttitor tellus. Nullam volutpat leo sed dapibus vestibulum. Ut aliquet accumsan nulla, commodo pharetra urna auctor in. In ligula lectus, molestie a libero a, sollicitudin rutrum tellus.
Integer vitae turpis id ligula eleifend laoreet. Morbi molestie libero non interdum pulvinar. Nulla facilisi. Nulla a facilisis velit. Etiam metus felis, fermentum eget massa eu, posuere vestibulum mauris. Donec placerat faucibus sapien, vitae dapibus est dapibus ac. Nam quis elementum eros, a eleifend erat. Sed interdum nisi at rhoncus rutrum. Phasellus vitae arcu a tellus tincidunt mattis.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras suscipit pharetra ante, quis tristique elit tempor at. Mauris nec nisi porttitor, sodales nunc facilisis, tempor ligula. Aenean luctus purus id orci commodo, eu ornare erat molestie. Proin viverra semper est, sit amet hendrerit mi. Phasellus sodales auctor ipsum eu fermentum. Quisque ut convallis turpis. Suspendisse et varius lorem. Quisque ipsum metus, venenatis quis aliquam et, lobortis nec purus. Aenean consectetur, tellus in gravida tempor, dui lacus placerat dui, quis dictum libero sapien at diam. Donec eleifend, turpis ac vulputate vulputate, nulla enim vestibulum magna, nec finibus ex urna sed quam. Curabitur vitae felis mi. Suspendisse potenti.
Quisque scelerisque mattis venenatis. Phasellus in varius lectus. Ut ut lorem eu augue convallis vulputate. Ut at tortor leo. Etiam tristique, quam et ultrices commodo, risus mauris mollis nisi, quis condimentum sapien tortor et dolor. Pellentesque sollicitudin velit ut sapien tristique, in mattis est facilisis. Pellentesque et leo massa. Sed pretium faucibus purus ac sodales. Sed varius eros felis, vel posuere metus lobortis id. Maecenas eget cursus ligula. In nec luctus orci. Nunc sed massa elit. Pellentesque iaculis tortor sit amet tellus ultrices, nec tristique lorem semper.
Donec aliquet ipsum ipsum, in consequat nisl euismod nec. Aenean aliquam nisl nec elit convallis pulvinar. Suspendisse ac malesuada ex. Fusce laoreet metus at nulla suscipit, non facilisis dui scelerisque. Maecenas blandit augue et lorem venenatis consequat. In porttitor eros ac elit placerat sodales. Suspendisse facilisis lorem vestibulum ante commodo dignissim. Mauris dignissim egestas massa, sit amet hendrerit orci molestie id. Suspendisse vel enim sit amet massa eleifend accumsan. Curabitur eleifend velit non nisi egestas ornare. Ut congue, eros a condimentum faucibus, risus sapien cursus elit, tempor condimentum nisi nisi vitae leo. Sed quis blandit tellus, in aliquet purus. Pellentesque eget leo lobortis, consectetur nisi non, facilisis lectus. Morbi tortor augue, posuere vel ultrices in, vestibulum vel nibh. Morbi accumsan tellus congue commodo tincidunt.
Curabitur vitae fermentum eros. Sed ex dolor, suscipit in ornare in, sollicitudin ac mi. Phasellus ornare ipsum vel elit mollis convallis. Nunc nec porttitor tellus. Nullam volutpat leo sed dapibus vestibulum. Ut aliquet accumsan nulla, commodo pharetra urna auctor in. In ligula lectus, molestie a libero a, sollicitudin rutrum tellus.
Integer vitae turpis id ligula eleifend laoreet. Morbi molestie libero non interdum pulvinar. Nulla facilisi. Nulla a facilisis velit. Etiam metus felis, fermentum eget massa eu, posuere vestibulum mauris. Donec placerat faucibus sapien, vitae dapibus est dapibus ac. Nam quis elementum eros, a eleifend erat. Sed interdum nisi at rhoncus rutrum. Phasellus vitae arcu a tellus tincidunt mattis.
Images:
1) Copy and replace the following files in the /images folder
i. 1icon.png
ii. 2icon.png
iii. 3icon.png
iv. mobil-app.png
v. mobil-app-this.png
vi. properties-icon.svgz
vii. setupLogo.svgz
viii. web-app.png
ix. web-app-this.png`;
var convertedvalue = btoa(str);
console.log(convertedvalue);
$("#b64text").html(convertedvalue);
$("input[type=submit]").prop("disabled", false);
function dataURItoBlob(dataURI) {
// convert base64 to raw binary data held in a string
// doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
var byteString = atob(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
// write the bytes of the string to an ArrayBuffer
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
// write the ArrayBuffer to a blob, and you're done
var blob = new Blob([ab], {
type: mimeString
});
return blob;
// Old code
// var bb = new BlobBuilder();
// bb.append(ab);
// return bb.getBlob(mimeString);
}
$("#form").submit(function(e) {
e.preventDefault();
formData = new FormData($(this)[0]);
// pass valid `data URI` to `dataURItoBlob`
var blob = dataURItoBlob("data:text/plain;base64," + convertedvalue);
formData.append("yourfile", blob);
$.ajax({
url: URL.createObjectURL(formData.get("yourfile")),
type: "GET",
// data: formData,
contentType: false,
cache: true,
processData: false,
success: function(data) {
console.log(data);
$("#b64text").html(data);
//alert("Form has been submitted with file");
}
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<form id="form">
<input type="submit" disabled/>
</form>
<div id="b64text" style=" word-wrap: break-word;">
</div>
jsfiddle https://jsfiddle.net/rccfymrz/17/

The easiest way is to do an AJAX POST request to the form's action field on the <form> tag. This is what the normal HTML does on its own anyways, but in our case you can specify the data programmatically, in this case a multipart file.
For an example, see this question.

It is that simple: file type input accepts the path to file, that would be sent on form submit, not the file itself.
UPD: Well, currently it's a little bit more complex (File API), however this is just meant to give you access to the data the user wants to give you.
You don't actually need to mess with file input to send the file.
If you are the one that owns server, you always can accept base64 string from regular text input field as a valid file (as an alternative to regular file field).
Otherwise you can always use ajax (with text or blob) to send your form.

Simple fileupload without submit form.
HTML
<input id="inputfileUpload" onchange="fileChanged(this);" type="file" accept="*/*" />
JAVACRIPT
function fileChanged(element) {
if (element.files[0]) {
var file = element.files[0];
var reader = new FileReader();
reader.onload = function (e) {
//file.name
//file.size
//Filedata: e.target.result
//You can convert to base64
//Angular sample:
//$base64.encode(e.target.result);
};
reader.readAsBinaryString(file);
}
}

I have the Base64 value of the file field [...] I need to know is if there is a way to set it.
Wouldn't be possible to have an hidden input ?
You set the base64 to that field, as the maximum size of an input type="hidden" is the same as type="file"
This way, you avoid the security reasons preventing you to load the local file, and still let you send the base64 representation.
The only problem is, we don't know how you have this base64 string. Is it loaded from a request ? Already populated from php ? ...

Use jquery:
$('#file_id_here').attr({'value':'file_path_here'})

If you just want to set what file is going to be the value of your file input field, you cannot. But you can set the field to blank for form validation reasons try using JavaScript:
document.getElementById("your-file-form-field-id").value = "";

Related

Save window binding in svelte store

Hi nice people of the Internet,
I created a listener for the scroll position of the user:
<svelte:window bind:scrollY={y} />
I would like to save this variable in a store, to make it accessible throughout the website. But for that I would need a setter. Is there a good performant way to do this?
I tried this, but it does not work:
$: () => scrollPos.set(y);
$: console.log("LOG: scrollPos", $scrollPos);```
You should be able to just bind directly to a store value:
<script>
import { writable } from 'svelte/store';
const y = writable(0);
</script>
<svelte:window bind:scrollY={$y}/>
Unfortunately it turns out you've found a bug — that doesn't currently work, for whatever reason. I've opened an issue here: https://github.com/sveltejs/svelte/issues/3832
Here's the code:
<script>
import { y } from './store.js';
import LogScrollPosition from './LogScrollPosition.svelte';
let scrollY;
$: y.set(scrollY);
</script>
<button on:click={() => scrollY = 200}>
Go down
</button>
<h1>Hello!</h1>
<LogScrollPosition />
<p>
Vestibulum arcu turpis, condimentum non lorem quis, volutpat laoreet turpis. Praesent euismod, libero eu pulvinar imperdiet, dolor ex molestie lacus, sed egestas arcu felis non libero. Aenean laoreet arcu porttitor dolor pulvinar eleifend. Pellentesque lacinia neque sit amet nulla blandit, at ullamcorper orci ultricies. Cras pulvinar nec est sit amet sollicitudin. Sed luctus massa nibh, eu luctus magna tincidunt vel. Morbi tempor velit elit, nec cursus risus pellentesque quis. Aliquam erat volutpat. Vivamus tristique lacus vel lorem lacinia, a accumsan turpis gravida. Maecenas dapibus gravida mauris, iaculis placerat urna rhoncus at. Vivamus vel malesuada nisi. Suspendisse pulvinar pellentesque lectus, non imperdiet nisi tempus sed. Maecenas vel magna eu diam faucibus semper ut nec neque.
Aliquam malesuada gravida libero, sit amet pellentesque felis viverra vel. Maecenas est tortor, eleifend ut est nec, maximus vehicula eros. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque tincidunt fringilla urna id fermentum. Proin rhoncus iaculis ipsum. In a sapien sapien. Sed eget justo ac turpis sodales imperdiet. In condimentum mauris ut ex sagittis, id malesuada ligula dictum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
Vivamus volutpat id velit et vehicula. Vivamus lectus orci, aliquam a maximus et, rhoncus in nibh. Etiam interdum sagittis justo et scelerisque. Quisque dapibus pulvinar pulvinar. Curabitur pulvinar, odio id eleifend consequat, sapien nulla congue metus, ut porttitor massa ipsum eget mauris. Duis a facilisis velit, non semper massa. Vestibulum semper velit nisi, sit amet blandit eros consectetur sit amet. Morbi accumsan magna a ex tempus imperdiet. Duis vitae convallis ipsum, imperdiet efficitur magna. Praesent ultrices turpis nec enim molestie, non aliquet tellus luctus. Sed porttitor nibh sit amet metus malesuada imperdiet et vitae ligula. Donec sit amet ullamcorper nisl. Nulla rhoncus ligula non tellus finibus efficitur. Nullam accumsan mattis risus at cursus. Duis ligula ligula, ullamcorper ac risus nec, hendrerit vulputate massa.
Phasellus pellentesque mauris ligula, id dapibus nisi lobortis a. In eget quam tincidunt, mattis ante eu, dignissim nisl. Proin sollicitudin dolor porttitor, tincidunt ipsum at, consequat leo. Morbi consequat imperdiet mauris, sed maximus tellus venenatis ut. Vestibulum tempus nisi ac semper volutpat. Vivamus rhoncus augue eu erat aliquet sodales. Ut consequat sapien enim, in pulvinar mauris dapibus varius. In mi mi, aliquam vel ante eu, lobortis aliquet lorem. Donec vulputate ac lorem ac laoreet.
</p>
<svelte:window bind:scrollY={scrollY} />
Essentially you were close, but don't make the function reactive with $: () => .... Just do $: scrollPos.set(y).
Here's an example REPL.
Reactive statements will be re-evaluated when the values they depend on change, so you could just make scrollPos.set(y) reactive and it will work as expected.
Example (REPL)
<svelte:window bind:scrollY={y} />
<script>
import { writable } from 'svelte/store';
let y;
const scrollPos = writable(0);
$: scrollPos.set(y);
</script>
<div style="height:1000px;">
<h1 style="margin-top:200px;">{$scrollPos}</h1>
</div>

scrollIntoView() using smooth function on multiple elements in Chrome

element.scrollIntoView with behavior set to smooth is not working as I expect in Chrome. When it is used only on one element in a callstack, it works fine. But if it is used on multiple elements, only the last element will actually scroll.
This works fine in Firefox. Is there a workaround for this in Chrome?
const $ = (s) => document.querySelector(s)
const $$ = (s) => document.querySelectorAll(s)
const container = $(".container")
for (let i = 0; i < 2; i++) {
document.body.appendChild(container.cloneNode(true))
}
function scrollIntoView(behavior) {
for (const element of $$(".reveal")) {
element.scrollIntoView({
behavior,
block: "end"
})
}
}
$(".instant").addEventListener("click", () => scrollIntoView("instant"))
$(".smooth").addEventListener("click", () => scrollIntoView("smooth"))
$(".reset").addEventListener("click", () => {
for (const element of $$(".container")) {
element.scrollTo(0, 0)
}
})
.container {
max-height: calc(33vh - 12px);
overflow-y: auto;
}
.reveal {
color: red;
}
<button class="instant">
Instant
</button>
<button class="smooth">
Smooth
</button>
<button class="reset">
Reset
</button>
<div class="container">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed rhoncus elementum quam. Donec quis est volutpat, dapibus nisl at, consequat turpis. Quisque convallis nunc faucibus eros egestas, in faucibus neque fringilla. Duis aliquam, metus tempor dignissim
vestibulum, nulla elit lacinia lacus, vitae pulvinar augue diam et turpis. Aenean a velit sed elit dictum fringilla ut eu augue. Vestibulum hendrerit dolor mauris. Proin quis lacus a turpis posuere maximus. Sed lacus mauris, feugiat a iaculis porta,
lacinia vel eros. Integer tempor id tortor vitae fermentum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Etiam lobortis efficitur massa, eu elementum nulla eleifend ut. Quisque non erat iaculis, ornare erat non, interdum sapien. Suspendisse
sit amet interdum nisl, eu maximus libero. Fusce nisi nulla, iaculis eu est a, mattis tincidunt sem. Pellentesque non orci dapibus, dignissim ipsum a, finibus metus. Quisque placerat porta neque, eget finibus lectus tempus sed. Cras non gravida urna.
Morbi pretium mauris nec erat consectetur, vitae convallis lacus consectetur. Nam venenatis diam magna, sed venenatis nisl placerat viverra. Integer et mi pellentesque risus consectetur ultrices. Phasellus iaculis risus elementum, vulputate est sed,
consectetur diam. Phasellus lobortis felis purus, sit amet mattis elit pharetra ac. Nulla at viverra leo. Maecenas a condimentum magna. Maecenas porta tellus sit amet elit fermentum tincidunt. Donec ultricies blandit enim id mollis. Sed rutrum risus
sit amet posuere varius. Suspendisse suscipit maximus ligula eget egestas. Nullam lorem neque, viverra in sollicitudin ac, cursus nec purus. Aliquam placerat, arcu sit amet tincidunt consequat, ex est lacinia tellus, ac mattis nisl sapien at enim. Cras
lacinia libero eu eleifend sodales. Praesent a erat convallis, venenatis dui ut, semper sem. Vivamus tincidunt tempor neque, at congue lacus tincidunt et. Praesent consectetur, massa tristique laoreet sollicitudin, erat diam mattis nibh, nec consequat
mauris odio ut est. Integer pharetra arcu at finibus congue. Proin pellentesque fringilla blandit. Suspendisse egestas interdum nisl. Nulla facilisi. Quisque dapibus odio risus. Donec non orci dapibus risus pellentesque cursus vestibulum vel arcu. Proin
volutpat tellus sed elit auctor, sit amet tincidunt ante cursus. Donec faucibus sit amet libero sit amet lobortis. Pellentesque posuere nisl vitae pharetra vestibulum. Mauris et lobortis libero, vel facilisis metus. Duis eu venenatis dui. Fusce gravida
nibh odio, quis ullamcorper nibh rutrum sed. In dapibus, nulla non auctor egestas, nisi augue venenatis quam, et finibus lorem dui non turpis. Nullam arcu diam, mattis at erat ac, viverra lobortis felis. In in nisi magna. Ut ut ultrices velit, quis
vehicula libero. Proin dictum metus vel ante lobortis, in placerat magna ornare. Etiam vulputate metus felis, sed fringilla magna convallis vitae. Curabitur non pulvinar ante, eget molestie nibh. Quisque facilisis, diam sed dapibus blandit, ex urna
vulputate est, non auctor risus dui nec augue. Donec pretium laoreet est, tempor faucibus tortor laoreet ac.
<span class="reveal">Revealed!</span>
</div>
As per this draft at drafts.csswg.org, it is not possible to use the smooth function for scrolling multiple elements simultaneously;
When a user agent is to perform a scroll of a scrolling box box, to a given position position, an associated element element and optionally a scroll behavior behavior (which is "auto" if omitted), the following steps must be run:
Abort any ongoing smooth scroll for box.
If the user agent honors the scroll-behavior property and one of the following are true:
behavior is "auto" and element is not null and its computed value of the scroll-behavior property is smooth
behavior is smooth
...then perform a smooth scroll of box to position. Otherwise, perform an instant scroll of box to position.
Your options are:
Scroll the elements one by one using the native smooth function.
Use different API or library to animate the elements.
Functionally design the thing differently, so they don't need to scroll simultaneously.

Get text selection after time elapsed from webpage

I want to get the text selected and also the DOM element along with where the ending of the text selection offset was in the webpage some seconds after the selection completed.
So like you highlight some text and if in 3 seconds that text is still highlighted, then I want to run some code that has as parameters the highlighted text and the DOM element that was nearest ancestor of the text.
I found there is this selectstart event,
https://developer.mozilla.org/en-US/docs/Web/API/Document/selectstart_event
and also the selectionchange event but I don't see a selectend event.
Some ideas were along these lines:
document.addEventListener('selectionchange', () => {
// if (Math.abs(Date.now().getTime() - process_request_start.getTime()) / 1000 <= 5
// if (is_processing_request === true) {
// return;
// }
setTimeout(() => {
if (is_processing_request === true) {
return;
} else {
is_processing_request = true;
console.log(document.getSelection());
is_processing_request = false;
}
}, 5000);
});
So I am looking for elegant code examples that provide/emulate a selectend, I had some working ideas using setTimeout but looking for any other solutions, prefer working code and not assuming any Jquery/libs, just native DOM environment.
For this particular problem, clearTimeout is your friend! You just cancel the timeouts until the time has elapsed (I shortened it to 2 seconds for this example):
let waiting = null;
document.addEventListener('selectionchange', () => {
if (waiting) clearTimeout(waiting);
waiting = setTimeout(() => {
console.log(document.getSelection().toString());
waiting = null;
}, 2000);
});
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus viverra diam quis aliquet pulvinar. Donec fringilla feugiat elit, vitae pretium turpis suscipit et. Integer tempus massa pellentesque arcu sagittis iaculis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Duis faucibus vestibulum tempus. Morbi at dolor rutrum, malesuada ex sed, tempor nisl. Aenean viverra accumsan accumsan. Suspendisse dignissim augue tellus, quis sollicitudin enim dignissim nec. Nunc mollis vehicula nibh, sed suscipit diam tristique vitae. Nam efficitur massa quis ultrices lacinia. Nunc consequat interdum nunc, vel luctus risus faucibus vel. In arcu diam, bibendum ac enim vel, dignissim vehicula quam. Donec non justo scelerisque, hendrerit est rhoncus, consectetur mi. Pellentesque a lorem eget ex placerat sodales eget sit amet metus. Phasellus aliquam vitae neque vel suscipit.
In in nisl tristique, dictum justo ut, consectetur risus. Suspendisse congue dignissim orci, scelerisque accumsan massa ornare vel. Sed finibus ultrices felis, eu ultrices magna consectetur nec. Proin eu fringilla risus. Cras id posuere ex, sed porta dui. Integer id dolor massa. Cras dui ante, congue a odio non, pulvinar faucibus nisi. Nunc in ex non quam rutrum tempus sit amet ac neque. Vestibulum blandit vulputate massa, ut tincidunt magna dictum id. Vivamus laoreet auctor sollicitudin. Duis eu quam ac lacus faucibus imperdiet sodales eu nisl. Integer auctor commodo turpis, a ultricies sem lacinia iaculis.
Quisque id mattis neque, ut dignissim lectus. Curabitur ex libero, rutrum sed massa a, ultricies fringilla justo. Pellentesque in interdum felis, et aliquet ante. Praesent mauris leo, pretium quis lectus non, ultricies elementum neque. Nam suscipit ullamcorper neque sed iaculis. Maecenas placerat nisl et convallis hendrerit. Suspendisse molestie erat non leo cursus, in maximus sem facilisis. Ut non magna quis purus pellentesque auctor sed sed lorem. Aenean sed iaculis metus, at bibendum libero. Pellentesque in est nec ipsum maximus rutrum in vel dui. Duis porta laoreet dolor, aliquet eleifend mi dapibus consequat.
Mauris posuere tempus libero ut ullamcorper. Aenean ac accumsan enim. Quisque ex felis, pretium euismod dui et, euismod malesuada sapien. Etiam et tempus nulla. Quisque aliquet aliquet risus dapibus vestibulum. Etiam blandit leo odio, ac fringilla ante molestie nec. Sed commodo ex a finibus commodo.
Fusce sed fringilla tellus. Fusce id sagittis ipsum. Vivamus lacus neque, interdum et enim et, ultricies consectetur quam. Aenean lacus augue, placerat id odio vitae, imperdiet sodales mauris. In ornare est sit amet vestibulum interdum. Fusce ultrices, mi non mollis condimentum, est ligula dictum arcu, sed hendrerit magna dolor et ex. Morbi faucibus interdum mattis. Duis vel luctus sem, vitae porta elit. In gravida, leo at laoreet iaculis, mi odio ultrices nulla, sed dictum metus enim ac mauris. Sed odio est, consequat vel turpis et, accumsan accumsan libero. Maecenas nec luctus quam. Aenean et lobortis libero, quis pulvinar felis. Vestibulum sed dolor ornare, ultrices justo non, aliquam felis. Mauris sagittis rutrum mi, sit amet imperdiet lorem luctus non. Praesent ac tortor maximus, facilisis diam sit amet, rutrum nunc. Fusce sit amet lectus pretium, vehicula arcu laoreet, elementum justo.</div>

Compare old document height to new document height using javascript

Please i want to compare my div with id = message old document height to new document height.
If there is a difference, then it should scroll to bottom automatically, else nothing should happen. I wish to do this in pure javascript.
This is what i have so far but confused on how to get things done.I know there is surely a way but not succeeding.
function Scroll(){
var elem = document.getElementById('message');
elem.scrollTop = elem.scrollHeight;
}
Thanks for quick response.
If you just want a one-step 'jump' scroll, you can use
window.scrollTo(0, document.body.scrollHeight):
function Scroll() {
var elem = document.getElementById('message');
if (elem.scrollHeight > window.innerHeight) {
window.scrollTo(0, document.body.scrollHeight);
}
}
Scroll();
<div id="message">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam non lorem efficitur eros fringilla vestibulum vel in nisl. Nullam porttitor auctor euismod. Duis efficitur eu ipsum sit amet porta. Etiam sagittis velit id urna ultricies, id semper nisi
ornare. Donec ullamcorper orci dui, et eleifend metus dictum quis. Donec libero nisl, sodales at odio sit amet, dignissim egestas enim. Pellentesque consectetur erat eget tellus vehicula efficitur. Interdum et malesuada fames ac ante ipsum primis in
faucibus. Vivamus suscipit, lacus id maximus fermentum, erat velit venenatis diam, ac viverra mi erat in nunc. Aenean eu urna dignissim, elementum dui quis, elementum eros. Duis eleifend metus sed risus sodales efficitur. Fusce sit amet ipsum et magna
luctus tristique. Mauris vitae libero et odio aliquet rhoncus. Donec sed dui ac massa volutpat elementum. Nullam et nibh sit amet nisl accumsan placerat. Morbi at tortor non metus tempor euismod. Nam eget mi at diam sodales tristique non et lacus. Aenean
non nunc imperdiet, consectetur nibh egestas, semper orci. Sed tristique sem odio. Phasellus ultrices lorem venenatis purus pellentesque, in vestibulum augue congue. Vestibulum eu maximus mauris. Nulla facilisi. Etiam in semper velit, nec accumsan nunc.
Curabitur vel fermentum velit, quis blandit velit. Cras eu scelerisque est. Nunc vel dictum ipsum. Maecenas eleifend efficitur metus nec auctor. Donec ut enim hendrerit, gravida urna eu, hendrerit mauris. Proin orci nulla, tristique vitae pharetra ut,
blandit eget erat. Sed lectus mauris, fringilla ut felis nec, feugiat faucibus sapien. Morbi est felis, suscipit at tellus pharetra, interdum gravida lectus. Praesent molestie euismod sagittis. Sed blandit dictum magna, ac ornare elit dignissim eget.
Morbi varius libero sit amet est fermentum, id convallis quam interdum. Praesent posuere eros id dignissim euismod. Sed urna quam, facilisis quis lacinia sit amet, pellentesque et lacus. Vivamus faucibus sagittis dictum. Duis posuere, ipsum elementum
molestie pulvinar, elit odio lobortis ipsum, non finibus velit urna vel neque. Aliquam vehicula augue non sapien fringilla varius. Suspendisse at pellentesque nibh. Vestibulum sollicitudin lacus quis lectus hendrerit venenatis at ut lacus. Donec condimentum
fringilla tellus id bibendum. Donec facilisis elit erat, at varius velit dictum vel. Vivamus bibendum tincidunt justo, lobortis euismod tortor semper vel. Morbi non felis tortor. Aliquam vitae elementum ligula. Praesent sem risus, gravida vitae neque
iaculis, interdum maximus nibh. Etiam eu ullamcorper dui. Etiam mauris lectus, bibendum quis semper eget, egestas a nunc. Maecenas maximus pharetra mi id egestas.</div>
Hope this helps!

Throttling with Lodash doesn't work

I want to use Lodash's throttle to have fewer function invokes on scroll. My code is as follows:
window.addEventListener('scroll', _.throttle(() => { console.log('bam'); }), 1000);
Unfortunately, this doesn't work - I am getting bam-ed all the time, and not every one secound.
What can I do?
CodePen: http://codepen.io/tomekbuszewski/pen/oxeOXy?editors=1111
The _.throttle function should only be generated once and not every time the event fires
var callback = _.throttle(() => { console.log('bam')}, 10000);
window.addEventListener('scroll', callback);
div {
height : 100px
}
div > div {
height : 1000px
}
<script src="https://cdn.jsdelivr.net/lodash/4.6.1/lodash.min.js"></script>
<div>
<div></div>
</div>
the console.log("bam") called once every 10 sec
There is a mistake in your code
window.addEventListener('scroll', _.throttle(() => { console.log('bam'); }, 1000));
var f = function() {
console.log("bam");
}
window.addEventListener('scroll', _.throttle(f, 1000));
Simple, Efficient, And Low-Overhead Soution
You do not need lodash for a decent throttle function. The purpose of a throttle function is to reduce browser resources, not to apply so much overhead that you are using even more. Also, my different uses for throttle functions require many different circumstances for them. Here is my list of things that a 'good' throttle function needs that this one has.
Minimal overhead.
Immediate function call if it has been more than interval MS since the last call.
Avoiding executing function for another interval MS.
Delaying excessive event firing instead of dropping the event altogether.
Updates the delayed event when need be so that it doesn't become 'stale'.
Prevents the default action of the event when the throttled function is delayed.
Be able to remove the throttle event listener listener.
And, I believe that the following throttle function satisfies all of those.
function throttle(func, alternateFunc, minimumInterval) {
var executeImmediately = true, freshEvt = null;
return function(Evt) {
if (executeImmediately) { // Execute immediatly
executeImmediately = false;
setTimeout(function(f){ // handle further calls
executeImmediately = true;
if (freshEvt !== null) func( freshEvt );
freshEvt = null;
}, minimumInterval);
return func( Evt );
} else { // Delayed execute
freshEvt = Evt;
if (typeof alternateFunc === "function") alternateFunc( Evt );
}
};
}
N.B.: removeEventListener can only remove the exact function passed to addEventListener. If you sent a wrapped function to addEventListener, then removeEventListener requires this same wrapped function, not the original function. Thus, the following does not work.
function clickFunctor(){ /*...*/ }
// This code throttles clickFunctor to 500ms
var throttledFunctor = throttle(clickFunctor, null, 500); // WORKS
addEventListener("click", throttledFunctor, false); // WORKS
// ONLY this removeEventListener works
removeEventListener("click", throttledFunctor, false); // WORKS
// For example, this removeEventListener does not work
removeEventListener("click", throttle(clickFunctor, null, 500), false); // FAILS
// This removeEventListener also does not work
removeEventListener("click", clickFunctor, false); // FAILS
If you need wrappers around addEventListener and removeEventListener so that they work properly, then you can use the functions below.
var tfCache = []; // throttled functions cache
function listen(source, eventName, func, _opts){
var i = 0, Len = tfCache.length, cF = null, options = _opts || {};
a: {
for (; i < Len; i += 4)
if (tfCache[i] === func &&
tfCache[i+1] === (options.ALTERNATE||null) &&
tfCache[i+2] === (options.INTERVAL||200)
) break a;
cF = throttle(func, options.ALTERNATE||null, options.INTERVAL||200);
tfCache.push(func, options.ALTERNATE||null, options.INTERVAL||200, cF);
}
source.addEventListener(eventName, cF || tfCache[i+3], _opts);
return cF === null; // return whether it used the cache or not
};
function mute(source, eventName, func, _opts){
var options = _opts || {};
for (var i = 0, Len = tfCache.length; i < Len; i += 4)
if (tfCache[i] === func &&
tfCache[i+1] === (options.ALTERNATE||null) &&
tfCache[i+2] === (options.INTERVAL||200)
) {
source.removeEventListener(eventName, tfCache[i+3], options);
return true;
}
return false;
}
listen and mute will work for any event on any instance that inherits from EventTarget, such as an Element's blur/focus, 'click' on the window, XMLHttpRequest's onprogress, FileReader's onprogress, [etc.].
Example usage:
var docElement = document.firstElementChild;
docElement.style.transition = "background .667s linear";
function whenTheDocumentScrolls() {
var scrollTop = docElement.scrollTop || -docElement.getBoundingClientRect().top;
var bgColor = "#fff";
if (scrollTop < 1600) bgColor = "#9f9";
else if (scrollTop < 3000) bgColor = "#ff9";
else if (scrollTop < 3600) bgColor = "#f9e";
else if (scrollTop < 5600) bgColor = "#c8f751";
else if (scrollTop < 7200) bgColor = "#68f";
else if (scrollTop < 9200) bgColor = "#3fb";
docElement.style.backgroundColor = bgColor;
}
whenTheDocumentScrolls(); // Compute the background color right now
var scrollListenerOptions = {
passive: true,
capture: false,
// ALTERNATE: function(){ /*...*/ },
INTERVAL: 500 // check at most twice a second
};
function throttle(func, alternateFunc, minimumInterval) {
var executeImmediately = true, freshEvt = null;
return function(Evt) {
if (executeImmediately) { // Execute immediatly
executeImmediately = false;
setTimeout(function(f){ // handle further calls
executeImmediately = true;
if (freshEvt !== null) func( freshEvt );
freshEvt = null;
}, minimumInterval);
return func( Evt );
} else { // Delayed execute
freshEvt = Evt;
if (typeof alternateFunc === "function") alternateFunc( Evt );
}
};
}
var tfCache = []; // throttled functions cache
function listen(source, eventName, func, _opts){
var i = 0, Len = tfCache.length, cF = null, options = _opts || {};
a: {
for (; i < Len; i += 4)
if (tfCache[i] === func &&
tfCache[i+1] === (options.ALTERNATE||null) &&
tfCache[i+2] === (options.INTERVAL||200)
) break a;
cF = throttle(func, options.ALTERNATE||null, options.INTERVAL||200);
tfCache.push(func, options.ALTERNATE||null, options.INTERVAL||200, cF);
}
source.addEventListener(eventName, cF || tfCache[i+3], _opts);
return cF === null; // return whether it used the cache or not
};
function mute(source, eventName, func, _opts){
var options = _opts || {};
for (var i = 0, Len = tfCache.length; i < Len; i += 4)
if (tfCache[i] === func &&
tfCache[i+1] === (options.ALTERNATE||null) &&
tfCache[i+2] === (options.INTERVAL||200)
) {
source.removeEventListener(eventName, tfCache[i+3], _opts);
return true;
}
return false;
}
listen(window, "scroll", whenTheDocumentScrolls, scrollListenerOptions);
listen(document.getElementById("stop-scrolling"), "click", function(){
mute(window, "scroll", whenTheDocumentScrolls, scrollListenerOptions);
}, {passive: true});
<button id="stop-scrolling" style="position:fixed;bottom:0;right:0">Remove the scroll listener</button>
<div style="font-size:1.4em;line-height:1.8;white-space:pre-wrap">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi semper facilisis leo quis imperdiet. Maecenas vitae malesuada nibh. Donec volutpat nunc in eros pretium vulputate. Curabitur lorem ipsum, tincidunt at hendrerit sed, venenatis vitae nibh. Duis varius felis vitae sem consequat varius. Interdum et malesuada fames ac ante ipsum primis in faucibus. Integer semper eget dolor et egestas. Proin nec ipsum rhoncus, pellentesque quam non, vestibulum augue. Curabitur et diam non est tempor dignissim. Fusce tempor nisl a ligula sagittis, eget condimentum magna iaculis. Vestibulum vulputate mauris eget mi semper, eget mattis orci tincidunt. Phasellus sit amet egestas turpis. Aliquam aliquet facilisis dolor, ultrices mollis risus mollis vulputate. Praesent id ligula at mi faucibus ornare. Fusce at tristique dui. Nullam pellentesque, augue eget tristique egestas, est metus euismod odio, a convallis lacus lectus non massa.
Nullam a fringilla turpis. Mauris in ultricies est. Nam faucibus, nunc eu suscipit volutpat, est augue congue velit, fermentum ornare nibh erat ac ex. Sed ut neque auctor, facilisis arcu in, molestie leo. Praesent vestibulum lacinia sapien, ac porta ligula porttitor et. Vestibulum nec ante libero. Sed vel velit elit. Praesent tristique bibendum consectetur. Vestibulum pretium tellus sapien, eu vulputate mi condimentum ut. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
Vestibulum semper elit risus, id fringilla enim gravida non. In in tellus quis nulla commodo volutpat. Sed tristique, magna eu sagittis porttitor, quam neque varius ante, ac mattis elit ex vitae nisl. Fusce sed justo vitae elit tempus porta. Donec nisl justo, bibendum nec dolor vitae, venenatis elementum justo. Nulla egestas quis tellus non vehicula. Proin vel lobortis felis. Quisque tempus eu elit non porta. Cras eleifend nisl nec vehicula tristique. Integer et pellentesque urna. In eu magna turpis. Vivamus vitae diam nec nulla vulputate pharetra eget vel leo. Praesent et tortor sed purus commodo finibus sit amet id ipsum. Pellentesque diam elit, condimentum et varius eu, elementum vitae quam.
Cras felis tellus, auctor non consectetur non, pharetra sed purus. In ut condimentum risus, eu ornare augue. Aliquam eu ex augue. Nunc tincidunt, libero a pellentesque dignissim, metus dui posuere mauris, eu iaculis purus dolor non quam. Donec venenatis tellus ut nisi tristique, sed egestas ipsum auctor. Integer gravida mollis nulla porta pretium. Proin vel dolor nisi. Suspendisse ut lacinia turpis. Donec lacinia lorem mollis ante pretium convallis. Aliquam erat volutpat. Donec vel porta libero. Donec eget arcu id risus fringilla finibus. Duis pulvinar hendrerit metus id porta. Maecenas et nulla in enim scelerisque tempus vel ut massa. Ut luctus placerat ipsum, sit amet pharetra nunc faucibus id.
Phasellus varius tortor a mi fermentum porttitor. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Maecenas mollis varius ante, non blandit ex cursus scelerisque. Vivamus sodales, diam at aliquam blandit, diam metus gravida lectus, non auctor augue felis ut justo. Proin in volutpat neque, id tempus arcu. Aenean vestibulum consequat leo, in tincidunt orci semper eu. Integer blandit vehicula consequat.
Donec accumsan purus quis sem dapibus aliquet. Etiam hendrerit sem eget tellus facilisis venenatis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Suspendisse vel consequat est. Sed quis convallis tellus. Vivamus quis semper odio. Mauris quis interdum ligula. Praesent cursus ante at libero sollicitudin, at varius nunc dapibus. Vivamus augue nisi, cursus in enim ut, eleifend hendrerit neque. Quisque rhoncus nibh a velit volutpat volutpat. Praesent a purus enim. Donec id fringilla nibh.
Pellentesque lectus turpis, auctor vel sem a, consequat rutrum odio. Mauris congue erat commodo, consectetur ante at, rutrum quam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In ut neque vel est rutrum pellentesque. Maecenas sem est, dapibus vitae nisi non, tempor tincidunt libero. Aenean ornare auctor tellus et molestie. Phasellus vel efficitur leo. Phasellus quis venenatis lectus. Nam ac neque quis dolor tristique gravida. Fusce sem dolor, suscipit non aliquam sed, cursus faucibus turpis. Integer feugiat, nulla ut vestibulum fringilla, velit dui rhoncus quam, a ullamcorper sapien libero ut quam. Phasellus ornare posuere libero, eu venenatis nunc iaculis nec. Etiam sed malesuada ante.
Morbi consequat risus sit amet tellus lobortis convallis ut mollis arcu. Donec suscipit mollis lectus, vitae ullamcorper sem aliquam ac. Aliquam sed erat id eros malesuada aliquam. Nunc semper felis sed ligula ullamcorper congue. Ut nec cursus libero, a posuere ligula. Proin luctus laoreet mi, ac semper lectus convallis nec. Maecenas eu egestas mi. Etiam varius ex eget tincidunt auctor.
Curabitur bibendum quam id ligula lacinia, quis molestie lacus vestibulum. Etiam dapibus lacus nulla, quis luctus justo tempus sed. Praesent mi enim, efficitur quis congue vestibulum, molestie non odio. Donec nibh ex, elementum vitae sodales quis, pulvinar vitae tortor. Morbi et egestas velit, eget congue nibh. Vestibulum fringilla mi leo. Curabitur cursus viverra mauris, sed auctor odio tristique eget. Suspendisse a ipsum tellus. Etiam eleifend vel sapien non consectetur. Mauris ac felis mauris. Donec fermentum eros sit amet ex placerat, id faucibus nisl lacinia. Vivamus eget dui vitae nisl commodo feugiat vitae ac ante. Nunc ullamcorper eros id massa sagittis, ac gravida felis semper. In hac habitasse platea dictumst.
In hac habitasse platea dictumst. Suspendisse potenti. Interdum et malesuada fames ac ante ipsum primis in faucibus. Donec vitae placerat ligula. Fusce malesuada mi et arcu pellentesque ornare. Fusce cursus, ipsum non gravida scelerisque, libero tortor sagittis elit, ac accumsan justo est sed ligula. Nam condimentum leo est. Vivamus hendrerit finibus metus quis cursus. Quisque consequat ipsum vitae justo volutpat ultricies. Nullam eget nisi quis sapien tempor scelerisque sit amet vel tellus. Vivamus euismod ultrices nisi a iaculis. Nam augue dui, aliquam et leo et, convallis imperdiet velit. Sed vestibulum eget quam eu fringilla. Suspendisse ac nunc ac ligula interdum congue et eget libero. In mollis dui sed mi finibus finibus.
Phasellus scelerisque, lectus in vulputate egestas, sem leo bibendum mauris, a tincidunt risus quam eu ante. Nulla placerat nibh et velit volutpat tincidunt. Ut luctus elementum massa, eget finibus tortor tincidunt at. Curabitur quis sagittis velit. Etiam finibus, quam vitae blandit vehicula, massa enim faucibus nisl, a aliquet purus justo tristique tortor. Sed fringilla tincidunt consequat. Mauris a tellus ultricies, tempus tortor nec, auctor est. Nulla feugiat nisl urna, a pulvinar erat consectetur condimentum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque in ultrices mi. Donec non sapien varius, tempor quam in, semper dui. Pellentesque aliquam sapien eu quam pellentesque pretium. Cras hendrerit dolor et libero semper, eget vestibulum quam tristique. Aliquam lobortis lacus vel purus mollis maximus. Nam vel imperdiet nunc, sit amet faucibus eros. Donec viverra varius volutpat.
Sed quis mollis dolor, et posuere eros. In eu quam orci. In vitae ante sed nisl vulputate ornare. Nullam quis ipsum molestie, laoreet elit quis, commodo tellus. Donec volutpat, velit at ornare fermentum, ipsum lectus convallis nisi, sed pharetra tortor tortor eget nisl. Vestibulum porta condimentum aliquet. Cras malesuada tellus erat, id auctor lorem pulvinar sed. Etiam non arcu suscipit, interdum sem eu, dapibus est.
Pellentesque tincidunt sem varius arcu semper lacinia. Suspendisse nunc felis, aliquet vel ullamcorper vitae, malesuada at dui. Vestibulum hendrerit neque sed sodales placerat. Praesent pulvinar massa eu risus facilisis placerat. Quisque tincidunt est sed mauris placerat, id viverra risus vulputate. Aenean in iaculis justo, et suscipit ligula. Aliquam efficitur in arcu vel vehicula. Suspendisse vitae dui magna. In dictum, nibh eget eleifend fermentum, sapien ex pharetra lorem, id dignissim lectus ipsum non nibh. Praesent at dignissim orci.
Sed ante nisi, commodo et metus ac, feugiat commodo nisi. Cras ut ligula sed augue dignissim gravida ut non mauris. Nullam laoreet diam at ligula luctus finibus. Nunc porta diam sit amet pharetra lacinia. Donec luctus sodales mauris, eu bibendum nisl tempus at. Donec sed pharetra nisi. Quisque sodales ligula nec eros placerat ultricies. In sit amet scelerisque tellus, quis sollicitudin ligula. Curabitur blandit ligula non odio facilisis, vel euismod ligula tempor. Nunc ligula arcu, mollis et metus eu, ullamcorper volutpat risus. Ut sem dolor, dignissim vitae fermentum malesuada, tincidunt aliquam ex. Sed placerat diam ligula, ac vehicula nunc eleifend vel. Nulla facilisi. Mauris in lectus non tortor lacinia vestibulum ut ut turpis.
Fusce gravida massa eget tincidunt malesuada. Integer sagittis quam non augue sodales viverra. Vestibulum luctus lectus sed eros molestie, ac congue leo fermentum. Mauris id urna sagittis, accumsan urna ac, posuere neque. Etiam molestie odio lobortis purus imperdiet venenatis. Ut pretium elementum velit, quis luctus massa sodales eu. Suspendisse varius at velit suscipit maximus. Pellentesque gravida ante a vehicula faucibus. Proin tincidunt scelerisque vestibulum.
Pellentesque varius semper metus, dignissim maximus elit hendrerit vel. Donec lobortis, tellus nec dictum pellentesque, nisl nisl ullamcorper erat, sit amet interdum nunc est sit amet lacus. In varius varius turpis vel facilisis. Vivamus ac viverra sem, vel scelerisque felis. Etiam eget nunc in nibh tempor dictum. Pellentesque dapibus auctor ante nec sollicitudin. Integer auctor mi tristique lectus convallis pretium. Cras aliquam, massa tempus molestie viverra, massa orci interdum ex, et dapibus justo massa eu arcu. Sed elementum pulvinar turpis, sed congue lorem tincidunt et.
Nam egestas felis orci, facilisis auctor urna sollicitudin ac. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis non euismod arcu. Aenean rhoncus ipsum ut neque finibus, ut pharetra dolor maximus. Pellentesque quam est, vestibulum non mattis id, luctus ut enim. Nam tempor lacus ut suscipit sagittis. Sed egestas id nisi quis tempus. Aenean non cursus quam, nec dignissim augue. Curabitur in placerat quam, in aliquet dui. Curabitur egestas, arcu nec auctor tempor, nibh lectus sollicitudin ligula, a malesuada mauris eros in orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Donec varius consequat dolor in pretium. Sed molestie tempor lectus. Curabitur consequat tristique risus, ac tempor ligula tristique ac. Cras porta blandit pretium. Donec vel enim nunc. Pellentesque quis bibendum dui, ac gravida orci. Donec sollicitudin massa in leo iaculis consequat.
Nulla at libero ullamcorper turpis venenatis interdum. Pellentesque gravida ante at nisl dignissim, vel consequat leo bibendum. Curabitur id turpis libero. Phasellus nec sapien magna. Quisque rhoncus sem in vulputate tempus. Nullam gravida eget purus ut imperdiet. Curabitur bibendum dapibus magna id ultricies. Sed vestibulum volutpat ante, sed porttitor ante porta in. Sed vitae eros dui. Sed sit amet nunc odio.
In cursus, est vitae fermentum facilisis, sapien felis accumsan erat, eu pretium ligula neque at orci. Cras at lorem sit amet enim finibus hendrerit ac lobortis est. Aenean nec dictum nulla. Vivamus scelerisque porttitor nisi, quis bibendum massa commodo et. Fusce nec dapibus purus, vitae sagittis nisl. Vivamus consectetur orci rutrum orci aliquam viverra. Morbi sodales elit at gravida imperdiet. Pellentesque sit amet felis sit amet orci venenatis gravida. Phasellus iaculis augue vitae laoreet lobortis.
Maecenas bibendum ultrices gravida. In eu tincidunt libero, quis tempus velit. Suspendisse placerat nisl magna, eu fringilla nunc luctus malesuada. Vestibulum sit amet orci hendrerit tortor pharetra lobortis ut at lacus. Cras erat metus, pretium sed metus ut, interdum posuere nisi. Nullam dolor sem, facilisis sed ex at, feugiat gravida lacus. Sed pellentesque mauris arcu, sit amet finibus nisi pulvinar non. Praesent metus felis, viverra quis libero in, sagittis vehicula ex. Phasellus a consectetur eros. Sed consectetur interdum sollicitudin. Donec sollicitudin venenatis arcu ultrices vehicula. Maecenas dolor urna, placerat id justo at, laoreet maximus enim. Integer porta odio ut purus interdum, at malesuada nisi tempus. Nullam vel cursus nulla. Mauris vehicula gravida sem. Nulla facilisi.
Etiam quis nisi at nibh varius tempor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus venenatis massa laoreet varius blandit. Etiam gravida elit in pulvinar tincidunt. Donec rutrum neque in consectetur dignissim. Vestibulum nec lorem sed augue pretium fermentum. Morbi mattis libero purus, eget accumsan massa accumsan vel.
Nunc ullamcorper massa augue, nec bibendum metus fringilla suscipit. Donec iaculis non nulla eu sodales. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam dapibus justo odio, at mollis nulla mollis dignissim. Suspendisse mollis, purus sed accumsan tristique, ex quam accumsan mauris, vitae tincidunt turpis magna in quam. Duis vel iaculis nibh. Praesent imperdiet diam at felis cursus commodo. Vestibulum sodales dapibus lacinia. Cras vitae eros ultricies, posuere purus eget, varius arcu. Nulla sodales mauris imperdiet dui bibendum, eu egestas lacus porttitor. Vivamus urna dolor, fermentum sit amet odio id, pharetra venenatis risus. Nunc id tortor metus. Quisque ultrices laoreet ante, a commodo libero dignissim gravida.
Sed bibendum ultricies rutrum. Aliquam ornare lacinia commodo. In dapibus nulla id fringilla convallis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam mattis laoreet interdum. Proin id nibh purus. Aenean nisi dui, imperdiet id lobortis vel, faucibus aliquam dui. Nulla maximus, nisi vitae egestas ornare, sem leo feugiat augue, ut tristique magna odio ut mauris. Ut finibus massa ut ex luctus, at commodo turpis efficitur. Maecenas vestibulum est ac lobortis vehicula. Curabitur sit amet pellentesque turpis. Integer rhoncus eget urna vel mollis. Morbi quis orci accumsan, fermentum augue in, condimentum lacus.
Pellentesque quis augue urna. In facilisis, est sollicitudin feugiat suscipit, dui ipsum ullamcorper mauris, sed ultrices ligula mauris ut urna. Maecenas posuere varius consectetur. Nunc sed egestas metus, eu imperdiet neque. Suspendisse sit amet urna et dui rhoncus vestibulum sit amet facilisis eros. Cras molestie euismod nisl, sit amet vehicula tortor efficitur egestas. Nullam ac facilisis urna. Nunc tempor felis sed ipsum feugiat hendrerit. Vestibulum sed lobortis nisi. Proin laoreet tempus tempor. Ut sed hendrerit ante, sed interdum urna. Aliquam tempus eros vitae dictum vehicula. Vestibulum purus quam, elementum sit amet rutrum in, dapibus nec metus. Quisque in mollis dui. Sed malesuada posuere sem ac gravida.</div>
Unfortunately, Stackoverflow disables code snippets on poorly misjudged and underappreciated answers, so here is a jsfiddle link to run the code instead.
Try scrolling down through the page in the demo and observing how the background color changes as you scroll. Try using your cursor to move the scrollbar up and down rapidly to see if you can get it to break and fail to update the colors. It will not break because this is a sturdy solid throttling function. Once you find a color that you like, click the "Remove the scroll listener" button in order to stop changing colors.
Although changing the background color with scrolling is a bit impractical (on a real website, it would simply distract the user from the content), I hope that this demonstration serves to show how powerful a good throttle function can be in terms of performance and fluid user experience.
Comparison To Lodash
Observe the following Lodash implementation of a throttled function.
/**
* lodash (Custom Build) <https://lodash.com/>
* Build: `lodash modularize exports="npm" -o ./`
* Copyright jQuery Foundation and other contributors <https://jquery.org/>
* Released under MIT license <https://lodash.com/license>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
*/
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';
/** Used as references for various `Number` constants. */
var NAN = 0 / 0;
/** `Object#toString` result references. */
var symbolTag = '[object Symbol]';
/** Used to match leading and trailing whitespace. */
var reTrim = /^\s+|\s+$/g;
/** Used to detect bad signed hexadecimal string values. */
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
/** Used to detect binary string values. */
var reIsBinary = /^0b[01]+$/i;
/** Used to detect octal string values. */
var reIsOctal = /^0o[0-7]+$/i;
/** Built-in method references without a dependency on `root`. */
var freeParseInt = parseInt;
/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function('return this')();
/** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the
//// Continued at https://cdn.jsdelivr.net/npm/lodash.throttle#4.1.1/index.js /////
Granted, the reason for why it is so big is because of all of the comments. Thus, let us compare the minified sizes:
// Lodash implementation: 1805 bytes (+GZip => 872 bytes);
// 19 suspended variables per throttle
throttle=function(){function A(a,b,c){function d(b){var p=g,c=k;g=k=void 0;l=b;return m=a.apply(c,p)}function h(a){var p=a-f;a-=l;return void 0===f||p>=b||0>p||q&&a>=u}function r(){var a=v.Date.now();if(h(a))return n(a);var c=setTimeout;var d=a-l;a=b-(a-f);d=q?B(a,u-d):a;e=c(r,d)}function n(a){e=void 0;if(w&&g)return d(a);g=k=void 0;return m}function x(){var a=v.Date.now(),c=h(a);g=arguments;k=this;f=a;if(c){if(void 0===e)return l=a=f,e=setTimeout(r,b),y?d(a):m;if(q)return e=setTimeout(r,b),d(f)}void 0===
e&&(e=setTimeout(r,b));return m}var g,k,m,e,f,l=0,y=!1,q=!1,w=!0;if("function"!=typeof a)throw new TypeError("Expected a function");b=z(b)||0;if(t(c)){y=!!c.leading;var u=(q="maxWait"in c)?C(z(c.maxWait)||0,b):u;w="trailing"in c?!!c.trailing:w}x.cancel=function(){void 0!==e&&clearTimeout(e);l=0;g=f=k=e=void 0};x.flush=function(){return void 0===e?m:n(v.Date.now())};return x}function t(a){var b=typeof a;return!!a&&("object"==b||"function"==b)}function z(a){if("number"==typeof a)return a;var b=a;if("symbol"==
typeof b||b&&"object"==typeof b&&"[object Symbol]"==D.call(b))return n;t(a)&&(a="function"==typeof a.valueOf?a.valueOf():a,a=t(a)?a+"":a);if("string"!=typeof a)return 0===a?a:+a;a=a.replace(E,"");return(b=F.test(a))||G.test(a)?H(a.slice(2),b?2:8):I.test(a)?n:+a}var n=0/0,E=/^\s+|\s+$/g,I=/^[-+]0x[0-9a-f]+$/i,F=/^0b[01]+$/i,G=/^0o[0-7]+$/i,H=parseInt,J="object"==typeof self&&self&&self.Object===Object&&self,v="object"==typeof global&&global&&global.Object===Object&&global||J||Function("return this")(),
D=Object.prototype.toString,C=Math.max,B=Math.min;return function(a,b,c){var d=!0,h=!0;if("function"!=typeof a)throw new TypeError("Expected a function");t(c)&&(d="leading"in c?!!c.leading:d,h="trailing"in c?!!c.trailing:h);return A(a,b,{leading:d,maxWait:b,trailing:h})}}()
But, what if we took all of that functionality in Lodash, stripped out the .cancel method (replacing it with mute/listen), made the leading options no longer an option, instead always true, and removed all of the fuss over typecasting under the assumption that you are conscious of which types you are using? The result is a radically debloated, much more performance, and just as useable throttling function that is my solution. Further, if you have special needs for a throttling function, then my solution is easily extendable with an optional 2nd parameter that defines a function to be called when an invocation to the main throttled function is dropped due to throttling.
// My implementation: 170 bytes (+GZip => 143 bytes);
// 5 suspended variables per throttle
function throttle(d,e,f){var c=!0,a=null;return function(b){if(c)return c=!1,setTimeout(function(b){c=!0;null!==a&&d(a);a=null},f),d(b);a=b;"function"===typeof e&&e(b)}};
The listen/mute are extra convenience methods that keep track of the throttle reference for you so that you do not have to. The minified Lodash code does not include these extra convenience, so why should my code have to be compared with conveniences to Lodash which is without conveniences? Thus, my above code snippet only represents my throttler without the listen/mute convenience methods.
Thus, I rest my case that my implementation is comparable to Lodash in functionality and far superior to Lodash in size and performa

Categories

Resources