HTML5 Touch event: Getting word touched - javascript

I'm building a dicionary function for my website for mobile users.
I would like this function:
The user touches on a word, a popup window shows its definition.
I've found out the touch API of HTML5.
But couldn't figure out how to get the word touched.
Any hint?

You can sort of achieve it thanks to the Range API and its handy getBoundingClientRect method.
Indeed, this method allows us to get the position of a textNode, while normally we can only get the position of an Element.
All we have to do then, is to first retrieve the original textNode that got clicked, split its content into as many textNodes as there are words, and grab the one we want.
document.onclick = function(e){ console.log(getWord(e));};
// didn't really test with touch device yet, but should be about the same...
document.ontouchstart = function(e){ console.log(getWord(e.touches[0]));};
function getWord(e) {
// FF gives us a shortcut
var target = e.explicitOriginalTarget || e.target,
// We will use this to get the positions of our textNodes
range = document.createRange(),
rect, i;
// so first let's get the textNode that was clicked
if (target.nodeType !== 3) {
var children = target.childNodes;
i = 0;
while (i < children.length) {
range.selectNode(children[i]);
rect = range.getBoundingClientRect();
if (rect.left <= e.clientX && rect.right >= e.clientX &&
rect.top <= e.clientY && rect.bottom >= e.clientY) {
target = children[i];
break;
}
i++;
}
}
if (target.nodeType !== 3) {
return '[not a textNode]';
}
// Now, let's split its content to words
var words = target.nodeValue.split(' '),
textNode, newText;
i = 0;
while (i < words.length) {
// create a new textNode with only this word
textNode = document.createTextNode((i ? ' ' : '') + words[i]);
newText = words.slice(i + 1);
// update the original node's text
target.nodeValue = newText.length ? (' ' + newText.join(' ')) : '';
// insert our new textNode
target.parentNode.insertBefore(textNode, target);
// get its position
range.selectNode(textNode);
rect = range.getBoundingClientRect();
// if it is the one
if (rect.left <= e.clientX && rect.right >= e.clientX &&
rect.top <= e.clientY && rect.bottom >= e.clientY) {
return words[i];
}
i++;
}
};
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac fermentum ipsum, in efficitur felis. Nam fringilla semper lectus, pretium luctus tortor. Pellentesque vel aliquet orci. Quisque at accumsan felis. Phasellus a ligula congue, viverra tellus
sit amet, consequat arcu. Mauris et congue diam, eget vehicula ante. Curabitur varius augue eget augue posuere, ut tincidunt purus sodales. Suspendisse luctus fermentum justo, sed scelerisque ipsum dignissim nec.
</p>
<p>
Suspendisse sed dui elit. Vivamus laoreet ipsum ut metus finibus, eu ultrices lorem bibendum. Fusce ante nibh, egestas nec neque id, semper volutpat orci. Donec a porta nunc. Sed interdum hendrerit mauris. Donec sed semper eros. Integer rhoncus diam quis
augue ornare consequat. Sed eleifend congue ante quis malesuada. Maecenas et purus venenatis arcu malesuada condimentum id quis nunc. Integer non suscipit sapien, id iaculis mi.
</p>
<p>
Mauris cursus mauris vitae nulla tempor lacinia. Quisque tristique ullamcorper magna et consequat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Phasellus faucibus sit amet enim non sollicitudin. Aliquam malesuada,
massa hendrerit condimentum pulvinar, ex est finibus massa, at efficitur velit est eu dolor. Pellentesque facilisis ligula hendrerit lacus efficitur venenatis. Ut pretium turpis quis laoreet mattis. Quisque tempor ornare maximus. Nunc augue urna, egestas
non lectus at, fringilla pharetra nisl. Pellentesque ac quam cursus, volutpat libero eget, ultricies dolor. Donec eleifend iaculis dui dignissim pulvinar. Cras semper vehicula augue, ut ultricies arcu consectetur ut. Mauris congue turpis justo, ac feugiat
dolor semper nec. Donec id augue posuere, efficitur nunc in, hendrerit est. Morbi eget pretium odio.
</p>
<p>
Morbi at volutpat nulla. Pellentesque elementum blandit imperdiet. Morbi id lacinia quam. Sed sed accumsan mauris. Donec nulla mi, rutrum id blandit id, hendrerit at turpis. Integer ante orci, venenatis a felis id, suscipit dignissim metus. Pellentesque
dictum, lectus aliquam facilisis mattis, nisi est porttitor nulla, et semper enim ante quis ex. Quisque ante magna, viverra et ante quis, fringilla tempor mauris. Phasellus posuere nulla in eleifend egestas. Proin augue arcu, semper quis metus sit amet,
placerat porta lorem. Integer tempus mi at faucibus posuere. Vestibulum ut malesuada turpis. In malesuada eros nisl, eget laoreet velit auctor vitae.
</p>
<p>
Aliquam maximus varius metus vel congue. Ut tristique risus metus, in tempor leo tempor laoreet. Donec scelerisque ipsum vitae nisi facilisis eleifend. Vivamus condimentum risus non lectus bibendum elementum. Cras vitae malesuada lorem. Curabitur et posuere
massa, ut luctus mi. Sed et enim nec nisl sollicitudin semper. Donec eget consectetur leo, a faucibus nulla. Nam accumsan hendrerit neque, ultrices aliquam ex auctor id. Nunc euismod faucibus ullamcorper. Sed ornare interdum congue. Quisque eget erat
erat. Morbi congue orci vitae porttitor semper.
</p>

this will be a little bit tricky. if you want to know the specific word touched inside a sentence, you should save a word in a separate span, register a touch event on all spans and get the text content on touch.
Please see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener for event listeners and
https://developer.mozilla.org/en-US/docs/Web/API/Touch_events/Using_Touch_Events for capturing touch events.

Related

Removing ‘<b/>’ with a userscript [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I frequently use a website where some pages erroneously contain a singular <b/>, resulting in all following text being bold. I’m trying to write a userscript to get around this, but the following JS code doesn’t work:
document.body.innerHTML = document.body.innerHTML.replace(/<b\/>/g, '')
Why?
A nice and safe way to do this would be:
document.querySelectorAll('b').forEach(b => {
// const parent = b.parentNode;
const fragment = document.createDocumentFragment();
fragment.append(...b.childNodes);
b.replaceWith(fragment);
// (optional) to join consecutive textNodes
// parent.normalize();
});
setTimeout(() => {
document.querySelectorAll('b').forEach(b => {
const parent = b.parentNode;
fragment = document.createDocumentFragment();
fragment.append(...b.childNodes);
b.replaceWith(fragment);
parent.normalize();
});
}, 1000);
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis pellentesque posuere neque, ac consectetur turpis porta vel. Nullam consequat mauris quis lectus porttitor, id vehicula lorem maximus. Nunc laoreet velit nisl. Nunc sit amet nulla egestas, <b>tincidunt magna sed, hendrerit ante.</b> Vestibulum elementum porttitor nisi quis commodo. Morbi gravida odio a eros pretium, at sagittis velit iaculis. Ut quis eleifend tortor. Etiam consectetur congue tempor. Pellentesque vel gravida velit. Maecenas quis urna ante. Morbi vel tellus eros.
</p>
<p>
Nulla scelerisque vitae lacus quis consequat. Donec volutpat efficitur diam non lobortis. Donec porttitor in lorem vitae iaculis. Suspendisse eu ligula a arcu ultrices scelerisque vitae at lacus. Fusce sodales, nunc ac tincidunt dignissim, velit felis pellentesque odio, ac mattis orci eros molestie est. Aliquam euismod cursus sem, nec convallis libero aliquam vel. Aliquam ut velit ornare risus sollicitudin convallis. <b>Etiam massa sem, facilisis vel hendrerit vitae, <b>dignissim fermentum nulla.</b> Nullam pellentesque ipsum eu egestas convallis.</b> Maecenas scelerisque vitae nisl at tempor. Etiam eu egestas nibh. Phasellus vitae consectetur velit, sed fringilla metus. Nunc vitae pellentesque arcu. Nullam eget felis id ligula molestie placerat. Aliquam gravida pulvinar posuere. Nullam non purus consequat, volutpat enim eu, convallis ante.
</p>
<p>
<b>Quisque egestas</b> enim sed felis scelerisque ultrices. Proin id justo vitae ante volutpat tristique a nec metus. Vivamus quis scelerisque nunc, vitae dictum nunc. Vestibulum ultrices sem sit amet facilisis ornare. Sed tellus libero, vestibulum molestie ultricies a, cursus a nisi. Suspendisse potenti. Vestibulum sed ante tortor. Suspendisse eu sem quis velit aliquam tempus. Vivamus eget vulputate est, nec fermentum sem. Suspendisse potenti. In nunc ante, tincidunt ut nunc id, tempor aliquam mi. Vestibulum dictum, mi sed tempus commodo, ex turpis aliquam felis, suscipit aliquet leo eros tempor nisi. Donec et suscipit risus. Proin vestibulum felis interdum tellus luctus, nec tempus turpis cursus. Curabitur lectus nibh, scelerisque ut magna sed, aliquet mollis risus. Sed pulvinar, felis at sodales porta, enim neque rhoncus nulla, eget ornare odio lectus facilisis dolor.
</p>
To support ES5 (not sure why you'd need to at this point), here's a more verbose alternative that also happens to be more efficient than above:
var nodes = document.getElementsByTagName('b');
for (var i = 0; i < nodes.length; i++) {
var b = nodes[i];
var parent = b.parentNode;
var fragment = document.createDocumentFragment();
for (var j = 0; j < b.childNodes.length; j++) {
fragment.appendChild(b.childNodes[j]);
}
parent.replaceChild(fragment, b);
// check for DOM level 2 support
if (typeof parent.normalize === 'function') {
// this step is not required
// just re-optimizes DOM layout
parent.normalize();
}
}
See:
document.querySelectorAll()
DocumentFragment
ChildNode.replaceWith()
ParentNode.append()
Node.childNodes
Node.normalize()
The dom can't contain a single <b/>, it must have a <b> before.
The correct regex would be :
document.body.innerHTML = document.body.innerHTML.replace(/<b\/?>/g, '')

How to create a ‘search function’ for a web page?

I’m new to jQuery/JavaScript but I have a solid idea of what I want, I’m just struggling to get it working.
I have a web page made up of different ‘div’s’ which have different ‘id’s’. I wrapped these divs in a pageContainer div. I want to be able to type a word in my ‘search bar’ and the word be looked for in the web page. It would signify a matching word by a collapsable div that would appear under the search bar which would have links to the different div id’s for where that word is. When clicked that word would be highlighted.
It’s simple but I figure it’s a good exercise to do.
Right now I know that I’m searching for the word in my pageContainer. As my understanding goes, I must search instead in each div, instead of the whole page. How can I do this?
Also as a side note, why is it that for every character I type, the search starts. Shouldn’t it only start on 3+ characters? I thought that’s what keyup does.
As of now, when I type in a word and search it, nothing happens on the web page.
/*Need to get the below search code working...*/
var thePage = $(".pageContainer");
// var content = $.makeArray(thePage.map(function(k, v){
// return $(v).text().toLowerCase();
// }));
$("#search").keyup(function(){
var input = $(this).val();
console.log(input);
//if match found, make corresponding div link appear in open collapsible div,
// else say nothing found in open collapsible div
// console.log(
thePage.filter.(function(index, value){
var foundText = $(this).val().toLowerCase();
// console.log(foundText, " BAAAAA");
console.log(index, value, " Second Here");//find 'user' input in value
// console.log(foundText.indexOf(input) >= 0);
console.log($(value).find(foundText.indexOf(input) >= 0));
// $(value).filter(foundText.indexOf(input) >= 0);
$(value).find(foundText.indexOf(input) >= 0);
var highlight = '<span class="word">' + value + '</span>';
});
// );
});
Interesting task, to sum it up the requirements are:
A web page made up of different ‘div’s’ which have different ‘id’s’.
These divs wrapped in a pageContainer div.
Type a word in my ‘search bar’ and the word be looked for in the web
page.
Signify a matching word by a collapsable div that would appear
under the search bar which would have links to the different div id’s
for where that word is.
When clicked that word would be highlighted.
Search should start on 3+ characters
I took all the above into consideration and created this codepen demo
(search for 'elementum' for example).
P.S. The highlight function is quite basic, it would be much better and safier to rely on a plugin like these.
var thePage = $(".pageContainer");
$('#results').hide(); //Hide the results div at first
$("#search").keyup(function() {
//Empty and hide the results div everytime the user types something
$('#results').empty();
$('#results').hide();
//Get the typed value
var input = $(this).val();
//Do nothing if it's smaller than three characters
if (input.length < 3) return;
//iterate through the results
var results = $(".pageContainer>div:contains('" + input + "')");
var counter = 0;
results.each(function(index, value) {
counter++;
//Get the current div that contains the given text
currentId = $(this).attr('id');
console.log('div' + index + ':' + currentId);
//Create a new element in the search div below the search input
var newP = $('<p/>', {
text: currentId
}).click(function() {
//Highlight when click
highliter(input, $(this).text());
});
$('#results').append(newP);
});
//Collapse if no results found
if (counter) $('#results').show();
else $('#results').hide();
});
function highliter(word, id) {
//Remove whatever was already highlighted
$('*').removeClass('highlight');
//Create a regular expression for the given word
var rgxp = new RegExp(word, 'g');
//Replace the plain text with a highlighted one
var repl = '<span class="highlight">' + word + '</span>';
var element = document.getElementById(id);
element.innerHTML = element.innerHTML.replace(rgxp, repl);
//Scroll to the position of the results
$('html, body').scrollTop($(".highlight").offset().top);
}
body{
background-color:grey;
}
#search{
width:200px;
}
#results{
width:200px;
border:2px solid black;
border-bottom-left-radius: 1em;
border-bottom-right-radius: 1em;
}
#results p{
background-color:#AAA;
margin: 8px;
cursor:pointer;
}
.highlight{
background-color:yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="search" type="text" />
<div id="results"></div>
<hr/>
<div class="pageContainer" id="main">
SECTION_1 (first div)
<div id="section1">
<p>Mauris eget risus ipsum. Ut dignissim justo id orci efficitur, ac ultricies sem ultricies. Nullam id velit vestibulum arcu eleifend tempor non nec purus. Sed mollis metus non aliquam accumsan. Fusce venenatis urna vel elit aliquet accumsan sit amet
et velit. Cras et molestie sem, et dignissim lorem. Etiam laoreet, dui eget cursus blandit, erat nisi pulvinar erat, sed volutpat turpis ante et massa. Nunc ornare orci ut purus maximus fermentum. Fusce nisl quam, maximus nec tortor quis, sagittis
maximus velit. Morbi in enim ac augue pharetra ultricies. Ut aliquet magna tellus, non volutpat ex vulputate ac. Curabitur in enim maximus, volutpat nibh ac, auctor urna.</p>
<p>Vivamus ac lacus rutrum, suscipit mauris et, rhoncus magna. Phasellus a ante a mi fringilla interdum sed feugiat massa. Interdum et malesuada fames ac ante ipsum primis in faucibus. Donec bibendum, tellus sed lobortis ullamcorper, nibh ex maximus
lacus, egestas scelerisque diam turpis a elit. Suspendisse iaculis, massa in ultricies sollicitudin, est dui bibendum augue, non dignissim nulla nibh ut dolor. Maecenas et mollis est. Donec condimentum laoreet erat, id maximus ante imperdiet in.
Proin id purus nulla. Vivamus tincidunt facilisis nisl, eget placerat elit mattis at. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
</div>
SECTION_2(second div)
<div id="section2">
<p>Fusce sit amet sem eget elit volutpat consequat. Nulla hendrerit sem dictum volutpat convallis. Sed interdum, arcu non facilisis condimentum, ipsum purus bibendum ex, a tincidunt leo leo vel sem. Maecenas porttitor quam non tortor accumsan interdum.
In id ultrices enim. Maecenas risus arcu, egestas nec ante et, vehicula bibendum dui. Quisque nec hendrerit ante. Integer in faucibus augue. Integer imperdiet felis id tempor facilisis. Nam lobortis sem non purus luctus varius. Quisque sit amet
justo ac dui convallis efficitur eget ut mi. Sed in efficitur nisi, ac rutrum mi. In pulvinar egestas turpis, non tincidunt orci finibus nec. Sed euismod augue eu tortor pharetra maximus eget at urna. Nulla efficitur elit lacus, sit amet faucibus
justo tristique eget.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse pellentesque augue non aliquam scelerisque. In tincidunt vel nisi id porttitor. Integer vulputate cursus augue. Sed luctus accumsan dui elementum eleifend. Proin convallis, sem non
accumsan pulvinar, justo lorem mattis enim, nec lobortis libero nibh nec nisi. Nulla faucibus tellus in magna rutrum, sed porttitor orci pharetra. Mauris sit amet quam enim. Sed laoreet, neque in pretium congue, neque sem tincidunt massa, sed sollicitudin
orci ex eget nisl. Donec ultrices ligula eget augue convallis, vitae sagittis mauris vulputate. Nulla non bibendum odio, a tincidunt massa. Mauris ultricies augue sit amet venenatis ornare. In pellentesque quam vitae orci pretium rutrum. Vivamus
non orci congue orci pellentesque euismod ac id dolor. Nam accumsan scelerisque sodales.</p>
</div>
SECTION_3 (third div)
<div id="section3">
<p>Ut vel eros sit amet eros accumsan imperdiet. Donec placerat urna sit amet tellus eleifend rhoncus. Pellentesque finibus dolor tortor, et dignissim tellus iaculis eu. Etiam sollicitudin mattis fermentum. Etiam porta est turpis, ut consectetur lorem
sodales eu. Aenean rutrum volutpat efficitur. Morbi a elementum lectus, id ornare orci. Fusce bibendum dignissim lacinia. Aliquam venenatis urna et leo pretium tempus. Proin ligula felis, posuere nec vestibulum quis, pellentesque ut quam. Vestibulum
sed elementum lectus. Quisque at ipsum id lacus efficitur lacinia non in lorem. Donec tristique lectus eu ex laoreet, non tristique libero blandit. Curabitur massa quam, fermentum sit amet dui non, bibendum convallis orci. Sed vulputate turpis nec
erat commodo, rhoncus cursus quam ornare. Donec pellentesque posuere tortor vel efficitur.
<p>
<p>Duis ligula purus, vulputate sed sodales quis, condimentum sit amet arcu. Sed fermentum ut dui ac posuere. Donec tristique volutpat lobortis. Aenean tortor elit, molestie nec tincidunt non, semper vel nisi. Phasellus quis est sit amet massa facilisis
posuere. Integer sit amet elit semper ipsum sodales tempus vitae id lacus. Donec facilisis libero sit amet aliquam fermentum. Sed luctus, tortor et ullamcorper faucibus, libero sem ornare tortor, at gravida erat lorem elementum eros.</p>
</div>
</div>

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

Making a page scroll to a specific height after a certain amount of time, after checking scroll position is at top

Title basically says it all, I want to make a page scroll to a specific height after a certain amount of time, after checking scroll position is at top.
This is what I have so far, but i only seems to load the second function once?
<script>
window.onload = setTimeout("pageHeightTest();",2000);
function pageHeightTest() {
var top = window.pageYOffset || document.documentElement.scrollTop
if (top < 50){
pageScroll();
}
}
var scrollAmount = 0;
var h = window.innerHeight;
function pageScroll() {
window.scrollBy(0,7);
scrollAmount += 7;
timer += 1;
if(scrollAmount < h) {
scrolldelay = setTimeout('pageScroll()',0.1);
}
}
Can anyone point out where I'm going wrong?
Cheeeers
Do you ever check console for js errors? timer is not defined
Add var timer = 0;
FIDDLE
window.onload = setTimeout("pageHeightTest();",2000);
function pageHeightTest() {
var top = window.pageYOffset || document.documentElement.scrollTop
if (top < 50){
pageScroll();
}
}
var scrollAmount = 0;
var h = window.innerHeight;
var timer = 0;
function pageScroll() {
window.scrollBy(0,7);
scrollAmount += 7;
timer += 1;
if(scrollAmount < h) {
scrolldelay = setTimeout('pageScroll()',0.1);
}
}
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque lacinia elit blandit sapien iaculis, et pharetra leo dignissim. Proin dignissim pretium sapien, in vulputate tortor. Sed id sodales purus, ut auctor nisi. Morbi a odio tellus. Aliquam sollicitudin leo neque, ac ultricies arcu dignissim vel. Aliquam tempor ligula porttitor, cursus massa non, posuere dui. Etiam faucibus dictum pharetra.
Proin ac magna adipiscing, iaculis ante vitae, vehicula mauris. Nunc eleifend, sapien id blandit gravida, lorem quam convallis mauris, at pellentesque metus purus eu justo. Mauris commodo lorem enim, vel semper justo volutpat vitae. Nam vel diam non justo vulputate ullamcorper nec vel turpis. Proin faucibus dolor a ipsum viverra imperdiet. Sed ultricies vehicula mi a tempus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse sed mi ut ligula gravida semper. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
Morbi rutrum tortor eget metus ultricies tempus. Maecenas augue urna, auctor commodo egestas at, porta pretium tortor. Fusce nec eros mauris. Cras purus tortor, rutrum at tellus imperdiet, accumsan aliquam felis. Quisque facilisis tortor at orci accumsan vestibulum ut ut elit. Sed dapibus egestas metus ut facilisis. Maecenas et mauris eleifend, accumsan nisl et, scelerisque ipsum. Ut at luctus purus. Mauris id lacus porta, feugiat ipsum id, tincidunt sem. Suspendisse ornare venenatis ipsum, id elementum lectus consequat accumsan. Quisque quis eleifend justo. Aliquam erat volutpat.
Ut quis lorem vestibulum, scelerisque arcu in, aliquet tellus. Morbi tincidunt consectetur tristique. Curabitur adipiscing, nisl in tincidunt pellentesque, eros odio gravida erat, quis porta nunc massa et tellus. Proin posuere sollicitudin eros, in sodales mi convallis at. Nulla porttitor urna ut bibendum egestas. Maecenas interdum convallis lectus, vitae scelerisque augue eleifend in. Nulla quis dapibus erat, in tempor nibh. Nunc aliquet in velit sit amet vehicula. Aenean tincidunt leo ac odio fermentum sollicitudin. Cras felis turpis, consectetur vel orci eu, commodo volutpat sem. Donec eget viverra leo.
Fusce ac varius nibh, nec bibendum erat. In quam massa, aliquet vitae sollicitudin sit amet, pellentesque nec turpis. Suspendisse dapibus, metus ut blandit placerat, lectus risus vestibulum urna, eget consequat nunc nisi faucibus leo. Fusce vel vestibulum justo. Mauris et pulvinar diam, eget condimentum erat. Vivamus malesuada vehicula justo in mattis. Cras at condimentum tellus, sit amet viverra tortor. Maecenas convallis orci diam, et posuere eros semper in.

always make the expand button at the end of the paragraph

Here is the online sample: http://jsfiddle.net/Nh4K2/
<div class="container">
Nulla varius diam at sem adipiscing pharetra. Integer eget nulla non purus commodo aliquam. Aenean sed nunc neque. Aliquam eleifend aliquam arcu, ac semper nulla faucibus id. Etiam luctus eleifend tempus. Vestibulum ornare, nisi vitae fermentum luctus, sem lectus rhoncus nibh, auctor iaculis magna turpis nec turpis. Aliquam orci tortor, vulputate at pretium sit amet, blandit eget libero. Sed posuere ultricies mi, sed rhoncus massa ultrices quis. Donec pulvinar vestibulum rhoncus. Donec urna lacus, mollis et convallis at, commodo nec lectus. Maecenas pretium, nunc ac volutpat tempus, dolor orci ultricies massa, eu malesuada urna massa ut orci. Duis eget elit nulla, ornare aliquet nulla. Sed eleifend scelerisque est, eu laoreet lacus ultricies id. Aenean aliquam porttitor augue, quis lacinia augue consequat vitae. Ut venenatis orci massa. Duis dignissim, justo at pellentesque adipiscing, ligula eros mollis tellus, ut accumsan lorem dui eu est.
<div class="whatever">hahahahahaha</div>
<div class="damn">hohohohohohoho</div>
<div class="laugh">lololololololololo</div>
</div>
<span>Show</span>​
function excerpt(str, nwords) {
var words = str.split(' ');
words.splice(nwords, words.length - 1);
return words.join(' ') + '…';
}
var $div = $('.container');
$div.each(function() {
var theExcerpt = excerpt($(this).text(), 30);
$(this).data('html', $(this).html()).html( theExcerpt );
});
$('span').click(function() {
var isHidden = $(this).text() == 'Show';
var $div = $(this).prev();
var theExcerpt = excerpt($div.text(), 30);
$div.html( isHidden ? $div.data('html') : theExcerpt);
$(this).remove();
});​
any possible way to make "show" toggle button always shows at the end of the paragraph? rather than showing on the second line, the format looks like
Nulla varius diam at sem adipiscing pharetra. Integer eget nulla non
purus commodo aliquam. Aenean sed nunc neque. Aliquam eleifend aliquam
arcu, ac semper nulla faucibus…Show
Many thanks for any suggestions or solutions.
Add the span to the excerpt in the function.
Make sure you select the span's parent() instead of its prev().
http://jsfiddle.net/Nh4K2/3/
<div class="container">
Nulla varius diam at sem adipiscing pharetra. Integer eget nulla non purus commodo aliquam. Aenean sed nunc neque. Aliquam eleifend aliquam arcu, ac semper nulla faucibus id. Etiam luctus eleifend tempus. Vestibulum ornare, nisi vitae fermentum luctus, sem lectus rhoncus nibh, auctor iaculis magna turpis nec turpis. Aliquam orci tortor, vulputate at pretium sit amet, blandit eget libero. Sed posuere ultricies mi, sed rhoncus massa ultrices quis. Donec pulvinar vestibulum rhoncus. Donec urna lacus, mollis et convallis at, commodo nec lectus. Maecenas pretium, nunc ac volutpat tempus, dolor orci ultricies massa, eu malesuada urna massa ut orci. Duis eget elit nulla, ornare aliquet nulla. Sed eleifend scelerisque est, eu laoreet lacus ultricies id. Aenean aliquam porttitor augue, quis lacinia augue consequat vitae. Ut venenatis orci massa. Duis dignissim, justo at pellentesque adipiscing, ligula eros mollis tellus, ut accumsan lorem dui eu est.
<div class="whatever">hahahahahaha</div>
<div class="damn">hohohohohohoho</div>
<div class="laugh">lololololololololo</div>
</div>
​
function excerpt(str, nwords) {
var words = str.split(' ');
words.splice(nwords, words.length - 1);
return words.join(' ') + '…' + '<span>Show</span>';
}
var $div = $('.container');
$div.each(function() {
var theExcerpt = excerpt($(this).text(), 30);
$(this).data('html', $(this).html()).html( theExcerpt);
});
$('span').click(function() {
var isHidden = $(this).text() == 'Show';
var $div = $(this).parent();
var theExcerpt = excerpt($div.text(), 30);
$div.html( isHidden ? $div.data('html') : theExcerpt);
$(this).remove();
});​
You can simply set the display property of .container elements to inline.
Updated fiddle at http://jsfiddle.net/Nh4K2/2/
If you want them to be block, you could add a wrapper div around both .container and the <span>.
Your HTML is poorly structured, I would lay it out like this:
<div class="container">
<div class="description_text">
<span>description_text_here</span>
<span class="show_more"> Show</span>
</div>
<div class="more_text_to_show">
<p>more_text_to_show_here</p>
</div>
</div>
At least that is what I am reading into your question and posted code.

Categories

Resources