I am setting up my website to be responsive, and I want to know how to hide my livechat JavaScript when the screen size is smaller than 700px.
My current livechat JavaScript is ,
<script type="text/javascript">
function wsa_include_js(){
var wsa_host = (("https:" == document.location.protocol) ? "https://" : "http://");
var js = document.createElement("script");
js.setAttribute("language", "javascript");
js.setAttribute("type", "text/javascript");
js.setAttribute("src",wsa_host + "tracking-v3.websitealive.com/3.0/?objectref=wsa3&groupid=12581&websiteid=0");
document.getElementsByTagName("head").item(0).appendChild(js);
}
if (window.attachEvent)
window.attachEvent("onload", wsa_include_js);
else if (window.addEventListener)
window.addEventListener("load", wsa_include_js, false);
else
document.addEventListener("load", wsa_include_js, false);
</script>
Can someone please show me how. Thanks
This can actually be solved pretty easily with CSS media queries, however I need to know how the LiveChat is added to the HTML in order to give you a good answer.
What you want to do is take the class or ID of the div that holds the chat window and add the following to your CSS file:
#media screen and (max-width: 700px) {
#LiveChatContainerID { display: none; }
}
or
#media screen and (max-width: 700px) {
.LiveChatContainerClass { display: none; }
}
If LiveChat requires you to add an iframe to your site, just wrap the iframe in div tags with a unique ID or class and use the above in your CSS.
EDIT:
After seeing your site, I think I have a solution that will work fine:
#media screen and (max-width: 700px) {
.wsa_window, .wsa_window_close { display: none !important; }
}
The '!important' is needed to overwrite the style the javascript puts on the elements directly, but doing this in the inspector seemed to work fine without removing anything else on the page.
Hope this helps!
check this out it will help you. Its easy with JFiddle
This particular code changes color on size change so you can simply restructure it for your purpose. Test what you want to achieve right there in the code editor and see your result.
function red() {
$('div').css('background','#B60C0C')
.text('Screen Size RED');
}
function orange() {
$('div').css('background','#EBAE10')
.text('Screen Size ORANGE');
}
function green() {
$('div').css('background','#83ba2b')
.text('Screen Size GREEN');
}
var bounds = [
{min:0,max:500,func:red},
{min:501,max:850,func:orange},
{min:851,func:green}
];
var resizeFn = function(){
var lastBoundry; // cache the last boundry used
return function(){
var width = window.innerWidth;
var boundry, min, max;
for(var i=0; i<bounds.length; i++){
boundry = bounds[i];
min = boundry.min || Number.MIN_VALUE;
max = boundry.max || Number.MAX_VALUE;
if(width > min && width < max
&& lastBoundry !== boundry){
lastBoundry = boundry;
return boundry.func.call(boundry);
}
}
}
};
$(window).resize(resizeFn());
$(document).ready(function(){
$(window).trigger('resize');
});
I'm also not sure how you have added your chat into you page but if you have it in a div-tag you could hide that div on smaller screens.
You could do it with a script like in this jsFiddle but I think it's better to use CSS media queries as Oceanity answered.
In the fiddle you can easily test it by changing the size of the output section with the handle at the center.
(The size is set to 400px in the demo for easier testing in jsFiddle.)
For checking the size I have used a script from this SO question. I'm doing the size checking in onload- and onresize event.
function getViewPortSize()
{ // source code form here https://stackoverflow.com/questions/10653019/how-to-find-the-screen-width-and-apply-it-to-a-particular-css
var viewportwidth;
var viewportheight;
// Standard browsers
if (typeof window.innerWidth != 'undefined')
{
viewportwidth = window.innerWidth,
viewportheight = window.innerHeight
}
// IE6
else if (typeof document.documentElement != 'undefined' && typeof document.documentElement.clientWidth != 'undefined' && document.documentElement.clientWidth != 0)
{
viewportwidth = document.documentElement.clientWidth,
viewportheight = document.documentElement.clientHeight
}
//Older IE
else
{
viewportwidth = document.getElementsByTagName('body')[0].clientWidth,
viewportheight = document.getElementsByTagName('body')[0].clientHeight
}
return { width: viewportwidth, height: viewportheight};
}
var hideChat = function(evt) {
console.log(getViewPortSize().width);
if ( getViewPortSize().width < 400) {
//console.log('hide div now');
document.getElementById('chatArea').style = 'display: none';
}
else {
document.getElementById('chatArea').style = 'display: block';
}
};
window.onresize = function(evt) {
console.log(evt);
hideChat(evt);
};
window.onload = function(evt) {
console.log(evt);
hideChat(evt);
};
<div id="chatArea">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc,
</div>
Related
I want to implement a vanilla JS version of the jQuery slideUp()and slideDown() function.
My idea was to use CSS transition for the height property together with incrementing/decrementing the height using requestAnimationFrame().
I tried it with the following code, and slideDown is working as expected, but slideUp is not smoothly collapsing, instead, it is just suddenly gone.
Here is how it looks:
Here is a jsfiddle.
function toggleSlide(element) {
// Check if the element is currently visible
if (element.style.display== '' || element.style.display== 'none') {
// If the element is not visible, slide it down
slideDown(element);
} else {
// If the element is visible, slide it up
slideUp(element);
}
}
function slideDown(element) {
// If the element is not visible, set the display and height properties
if (element.style.display !== 'block') {
element.style.display = 'block';
element.style.height = 0;
}
// Get the height of the element's content
const contentHeight = element.scrollHeight;
// Set a variable to keep track of the element's height
let currentHeight = 0;
// Start an animation loop
function animate() {
// Increase the element's height by 10px
currentHeight += 10;
// Update the element's height
element.style.height = `${currentHeight}px`;
// If the element's height is less than the content height, request another animation frame
if (currentHeight < contentHeight) {
requestAnimationFrame(animate);
}
}
// Start the animation
animate();
}
function slideUp(element) {
// Get the height of the element's content
const contentHeight = element.scrollHeight;
// Set a variable to keep track of the element's height
let currentHeight = contentHeight;
// Start an animation loop
function animate() {
// Decrease the element's height by 10px
currentHeight -= 10;
// Update the element's height
element.style.height = `${currentHeight}px`;
// If the element's height is greater than 0, request another animation frame
if (currentHeight > 0) {
requestAnimationFrame(animate);
} else {
// If the animation is complete, hide the element
element.style.display = 'none';
}
}
// Start the animation
animate();
}
.my-element {
background-color: #ddd;
transition: height 0.5s;
overflow: hidden;
display:none;
}
<button onclick="toggleSlide(document.querySelector('.my-element'))">Slide Down</button>
<!-- Create the element that we will slide down -->
<div class="my-element">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In et tellus in quam convallis dictum. Maecenas eget odio eget arcu accumsan porttitor. Ut elementum volutpat orci, sed tincidunt ipsum dictum at. Maecenas auctor tempus diam quis gravida. Aliquam at ultricies leo. Etiam euismod, nisi ac blandit placerat, diam turpis vestibulum diam, at ultricies turpis orci at elit. Mauris auctor dictum dolor, quis pretium nisi ultricies in. Aenean sollicitudin, quam non euismod porta, enim nisl laoreet velit, vel venenatis dui dui vel lacus. Aliquam erat volutpat. Donec et elit ut ipsum elementum volutpat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent a nisi at est eleifend ullamcorper. Aenean porta, erat ac sagittis fermentum, leo magna tincidunt lectus, ac semper risus est et diam. Suspendisse auctor ipsum quam, id porta dui dictum sed. Vivamus ac diam non elit placerat iaculis vel at velit. Aliquam vel tincidunt velit. Duis imperdiet, dolor eu placerat luctus, ipsum quam laoreet dui, non suscipit nulla tellus et arcu. Donec dictum, massa non bibendum varius, leo urna condimentum diam, nec suscipit elit turpis vel turpis. Aenean ac nunc quis nisl tempus tincidunt a eu metus.</p>
</div>
Why is slideUp not collapsing smoothly?
The CSS Transition is the one taking effect before the toggle animation ends. Removing it solves the issue since your functions are taking care of the animating durations
function toggleSlide(element) {
// Check if the element is currently visible
if (element.style.display== '' || element.style.display== 'none') {
// If the element is not visible, slide it down
slideDown(element);
} else {
// If the element is visible, slide it up
slideUp(element);
}
}
function slideDown(element) {
// If the element is not visible, set the display and height properties
if (element.style.display !== 'block') {
element.style.display = 'block';
element.style.height = 0;
}
// Get the height of the element's content
const contentHeight = element.scrollHeight;
// Set a variable to keep track of the element's height
let currentHeight = 0;
// Start an animation loop
function animate() {
// Increase the element's height by 10px
currentHeight += 10;
// Update the element's height
element.style.height = `${currentHeight}px`;
// If the element's height is less than the content height, request another animation frame
if (currentHeight < contentHeight) {
requestAnimationFrame(animate);
}
}
// Start the animation
animate();
}
function slideUp(element) {
// Get the height of the element's content
const contentHeight = element.scrollHeight;
// Set a variable to keep track of the element's height
let currentHeight = contentHeight;
// Start an animation loop
function animate() {
// Decrease the element's height by 10px
currentHeight -= 10;
// Update the element's height
element.style.height = `${currentHeight}px`;
// If the element's height is greater than 0, request another animation frame
if (currentHeight > 0) {
requestAnimationFrame(animate);
} else {
// If the animation is complete, hide the element
element.style.display = 'none';
}
}
// Start the animation
animate();
}
.my-element {
background-color: #ddd;
/* Remove the transition */
overflow: hidden;
display:none;
}
<button onclick="toggleSlide(document.querySelector('.my-element'))">Slide Down</button>
<!-- Create the element that we will slide down -->
<div class="my-element">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In et tellus in quam convallis dictum. Maecenas eget odio eget arcu accumsan porttitor. Ut elementum volutpat orci, sed tincidunt ipsum dictum at. Maecenas auctor tempus diam quis gravida. Aliquam at ultricies leo. Etiam euismod, nisi ac blandit placerat, diam turpis vestibulum diam, at ultricies turpis orci at elit. Mauris auctor dictum dolor, quis pretium nisi ultricies in. Aenean sollicitudin, quam non euismod porta, enim nisl laoreet velit, vel venenatis dui dui vel lacus. Aliquam erat volutpat. Donec et elit ut ipsum elementum volutpat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent a nisi at est eleifend ullamcorper. Aenean porta, erat ac sagittis fermentum, leo magna tincidunt lectus, ac semper risus est et diam. Suspendisse auctor ipsum quam, id porta dui dictum sed. Vivamus ac diam non elit placerat iaculis vel at velit. Aliquam vel tincidunt velit. Duis imperdiet, dolor eu placerat luctus, ipsum quam laoreet dui, non suscipit nulla tellus et arcu. Donec dictum, massa non bibendum varius, leo urna condimentum diam, nec suscipit elit turpis vel turpis. Aenean ac nunc quis nisl tempus tincidunt a eu metus.</p>
</div>
As Barmar stated, one should either use requestAnimationFrame() or CSS transitions. Cypherjac represents the solution of just using requestAnimationFrame() here comes the alternative CSS transitions solution:
See jsfiddle or
const button = document.querySelector('button')
button.addEventListener('click', (e) => {
const container = document.querySelector('div');
const active = container.style.height !== '' && container.style.height !== '0px';
if(active){
container.style.height = "0px"
container.addEventListener('transitionend', () => {
container.style.display = 'none';
}, {once: true})
return;
}
container.style.display = 'block';
container.style.height = "auto"
const height = container.clientHeight + "px"
container.style.height = "0px"
setTimeout(() => {
container.style.height = height
}, 0)
})
.box {
transition: height .5s ease;
overflow : hidden;
height:0;
}
<div class="box">
I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element. I'm an unknown content height element.
</div>
<button>Slide Toggle</button>
The part with setting display to none/block could be omitted. Only added, as I assume for most scenarios, its useful to have it completly removed from flow when toggled.
The addEventListener:transitioned is necessary, so the display is set after the height has been changed to 0 and CSS transition has taken place.
The setTimeout is necessary, because otherwise, the height would be directly set to height and CSS would not get the change to animate.
I want to show a progress bar for a pdf-reading module. I want to show the progress as the reader scrolls down the container having PDF files. Now I have applied jquery ofcourse for this but there is some issues emerging and not obtaining the desired result. Issue here is the progress bar does show progress but it works on the whole window scroll only. What I want is to have show the progress on bar when the pdf container is scrolled down in that window. I have made codes for that but somehow its unresponsive for pdf-container. Any suggestions and help will be highly appreciated.
Here is my <div> that is showing the PDF,
<div id="viewer" class="pdf-viewer" oncontextmenu="return false" data-url="../sadmin/studyMaterial/<?php echo $db->idToField("tbl_studymaterials", "file_ppt", $chapterId) ; ?>"></div>
<span><progress id="progressbar" value="0" max="100"></progress></span>
And the jquery that I am using is,
$(".pdf-viewer").scroll(function () {
var s = $(window).scrollTop(),
d = $(document).height(),
c = $(window).height();
scrollPercent = (s / (d-c)) * 100;
var position = scrollPercent;
$("#progressbar").attr('value', position);
});
You are referencing the incorrect DOM node for the scrollTop() values in your script. Since you want to track the scroll position of the PDF container, you should simply reference it's own scrollTop() value, i.e. $(this).scrollTop().
Also, instead of checking the document height, you should check the scrollHeight of the element to get its full content height. The property is native to a DOM node, so you can simply use this.scrollHeight.
Here's the updated code:
$(".pdf-viewer").scroll(function () {
var s = $(this).scrollTop(),
d = this.scrollHeight,
c = $(this).height(),
position = (s / (d-c)) * 100;
$("#progressbar").attr('value', position);
});
And actually, you don't even really need to use jQuery methods to retrieve the dimensions:
Use Element.scrollTop instead of .scrollTop() to retrieve the scroll position
Use Element.clientHeight instead of .height() to retrieve the element's defined height (sans bottom scrollbar, if any)
And you get this:
$(".pdf-viewer").scroll(function() {
var s = this.scrollTop,
d = this.scrollHeight,
c = this.clientHeight,
position = (s / (d - c)) * 100;
$("#progressbar").attr('value', position);
});
jQuery-based solution
A proof-of-concept example with a dummy DOM:
$(function() {
$(".pdf-viewer").scroll(function() {
var s = this.scrollTop,
d = this.scrollHeight,
c = this.clientHeight,
position = (s / (d - c)) * 100;
$("#progressbar").attr('value', position);
});
});
#viewer {
width: 500px;
height: 100px;
overflow-y: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="viewer" class="pdf-viewer">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium
quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium.</p>
<p>Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra
nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus.</p>
<p>Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero
venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna.</p>
</div>
<span><progress id="progressbar" value="0" max="100"></progress></span>
Native JS solution
If you do not want to use jQuery, that is also entirely possible:
var viewer = document.getElementById('viewer');
viewer.addEventListener('scroll', function() {
var s = this.scrollTop,
d = this.scrollHeight,
c = this.clientHeight,
position = (s / (d - c)) * 100;
document.getElementById('progressbar').value = position;
});
#viewer {
width: 500px;
height: 100px;
overflow-y: auto;
}
<div id="viewer" class="pdf-viewer">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium
quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium.</p>
<p>Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra
nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus.</p>
<p>Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero
venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna.</p>
</div>
<span><progress id="progressbar" value="0" max="100"></progress></span>
I am updating the scrollTop of an element right before I start listening for a scroll event. However, the scroll event fires, even though it was added after the scrollTop was updated.
I noticed that if I wrapped the .onscroll assignment in a setTimeout(..., 1); it worked just fine.
Also note in the output, the scrollTop value in memory does not change, yet it triggers the event.
starting out 0
haven't added listener yet 100
listener added 100
scrolled 100
Can anyone explain why this works like this? Using setTimeout or setting a flag seems hacky as a way to get around this; is there a better way?
var div = document.getElementsByTagName('div')[0];
console.log("starting out", div.scrollTop);
div.scrollTop = 100;
console.log("haven't added listener yet", div.scrollTop);
div.onscroll = function() {
console.log('scrolled', div.scrollTop);
};
console.log("listener added", div.scrollTop);
div {
width: 80%;
height: 200px;
margin: 20px auto;
overflow: auto;
padding: 20px;
box-sizing: border-box;
border: 1px solid black;
}
<div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi id mi sit amet tortor suscipit sagittis at id risus. Nullam ultricies nisi ac tortor ultrices porta. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam purus sapien, efficitur in risus non, cursus egestas lectus. Curabitur pharetra erat sapien, et malesuada neque mollis nec. Donec dolor lacus, pretium eu ipsum sit amet, placerat vehicula orci. Sed viverra metus id magna sodales, et condimentum urna sagittis. Donec a viverra urna. Pellentesque lacinia commodo ligula sed porttitor. Aliquam iaculis diam nec nibh congue congue. Nunc eget dapibus orci, ac tristique nunc. Mauris nisl tellus, posuere sed lectus sit amet, vulputate sollicitudin magna. Nullam porttitor leo bibendum, varius libero vitae, ultrices diam. Donec mauris nulla, egestas non nisi sit amet, ultricies laoreet sapien.</p>
<p>Vivamus mollis placerat felis ut porta. Pellentesque pellentesque blandit leo, fermentum sollicitudin risus porta quis. Phasellus gravida justo nec mi accumsan, in euismod tortor venenatis. Donec porttitor consequat dui ac iaculis. Quisque scelerisque dictum risus, eu gravida nibh sodales in. Vivamus sit amet consectetur urna. Aliquam quis pretium turpis, non rhoncus lectus. Ut vel mi urna. Mauris interdum congue felis ut faucibus. Praesent nec lobortis enim. Vestibulum velit nisl, dapibus vulputate interdum vitae, sagittis a nisl.</p>
<p>Donec consectetur justo a purus sodales, quis ultrices enim sodales. Sed fermentum congue enim vehicula volutpat. Proin pellentesque elit et dolor congue, in blandit tellus aliquet. Cras tincidunt metus lorem, et tincidunt arcu condimentum eget. Curabitur sed ipsum nec erat mollis volutpat eget eget purus. Nam nec eleifend est. Sed ut elit eget odio mollis dignissim vitae nec urna. In vel libero eget libero rutrum consectetur non eget dui. Proin dignissim convallis elit, id mollis metus sodales eget. Aliquam non iaculis justo. Aenean vel diam nibh. Nam euismod viverra ante, ac molestie sem. Donec cursus justo a sagittis iaculis. Sed at maximus lacus, sit amet gravida mauris. Curabitur non odio at ipsum consequat fermentum. Morbi vestibulum nec dui id tincidunt.</p>
<p>Integer nec nunc ultricies, mattis leo sed, gravida enim. In hac habitasse platea dictumst. Nunc sed turpis sed nisi consequat faucibus. Fusce sagittis maximus luctus. Maecenas at tortor blandit, imperdiet ligula vel, vestibulum diam. Proin consequat sodales nisl, quis varius erat semper vitae. Etiam ac pretium lacus. Phasellus in vestibulum tellus, nec tempus dolor. Etiam fringilla convallis rhoncus. Sed id enim erat. Integer congue orci sapien, ac porttitor arcu pellentesque eget. Mauris eu rutrum urna. Donec ante eros, scelerisque id ipsum et, pulvinar dapibus erat.</p>
<p>Fusce eget bibendum eros. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec finibus justo a neque hendrerit, imperdiet fringilla nibh tincidunt. Etiam consequat a erat fringilla volutpat. Proin porttitor nec sem non semper. Suspendisse sollicitudin erat eu urna gravida volutpat quis sit amet leo. Mauris luctus purus eget purus mattis semper. Curabitur ut ante fringilla, porta neque non, hendrerit diam. Morbi dignissim congue orci ac vestibulum. Vestibulum ipsum urna, faucibus nec venenatis eu, efficitur vitae massa. Suspendisse lectus lorem, molestie vel consequat eget, malesuada sed turpis. Curabitur sit amet ipsum et justo sollicitudin pretium. Praesent dignissim, mauris ut hendrerit egestas, massa orci cursus justo, non porta metus erat et velit. Curabitur vitae orci eu erat ultrices aliquet.</p>
</div>
I'd say it's because the browser doesn't do the actual scroll until the next frame. So the event listener is set before the scroll is even updated.
What you could do to avoid it is ignore the first scroll event.
var scrolled = false;
window.scrollTo(0, 100);
window.addEventListener('scroll', function() {
if(!scrolled) {
scrolled = true;
return;
}
// Do stuff...
});
Edit to reflect OP's comment:
I can't imagine why this would not work for you:
window.scrollTo(0, 100);
window.addEventListener('scroll', function() {
if(typeof window.scrollEventHasFired === "undefined") {
window.scrollEventHasFired = true;
return;
}
// Do stuff...
});
Further edit, reflecting new information:
Would this work for you? This enables multiple events to be set and also allows for the listener to be called outside of an event:
var scrolled = [false],
id = 0;
var listener = function(skipFirstExec, listenerId, args...) {
if(skipFirstExec && !scrolled[listenerId]) {
scrolled[listenerId] = true;
return;
}
// Do stuff
};
window.addEventListener('scroll', listener.bind(thisArg, true, ++id));
scrolled[id] = false;
window.addEventListener('scroll', listener.bind(thisArg, false, ++id)); // This one won't skip the scroll
scrolled[id] = false;
window.addEventListener('scroll', listener.bind(thisArg, true, ++id));
scrolled[id] = false;
listener(false, 0, args...); // call listener outside of event
Final edit:
This worked for me, don't know why I didn't think of this earlier:
/**
* requestAnimationFrame polyfill by Erik Möller & Paul Irish et. al.
* https://gist.github.com/1866474
*
* http://paulirish.com/2011/requestanimationframe-for-smart-animating/
* http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
**/
/*jshint asi: false, browser: true, curly: true, eqeqeq: true, forin: false, newcap: true, noempty: true, strict: true, undef: true */
(function( window ) {
'use strict';
var lastTime = 0;
var prefixes = 'webkit moz ms o'.split(' ');
// get unprefixed rAF and cAF, if present
var requestAnimationFrame = window.requestAnimationFrame;
var cancelAnimationFrame = window.cancelAnimationFrame;
// loop through vendor prefixes and get prefixed rAF and cAF
var prefix;
for( var i = 0; i < prefixes.length; i++ ) {
if ( requestAnimationFrame && cancelAnimationFrame ) {
break;
}
prefix = prefixes[i];
requestAnimationFrame = requestAnimationFrame || window[ prefix + 'RequestAnimationFrame' ];
cancelAnimationFrame = cancelAnimationFrame || window[ prefix + 'CancelAnimationFrame' ] ||
window[ prefix + 'CancelRequestAnimationFrame' ];
}
// fallback to setTimeout and clearTimeout if either request/cancel is not supported
if ( !requestAnimationFrame || !cancelAnimationFrame ) {
requestAnimationFrame = function( callback, element ) {
var currTime = new Date().getTime();
var timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) );
var id = window.setTimeout( function() {
callback( currTime + timeToCall );
}, timeToCall );
lastTime = currTime + timeToCall;
return id;
};
cancelAnimationFrame = function( id ) {
window.clearTimeout( id );
};
}
// put in global namespace
window.requestAnimationFrame = requestAnimationFrame;
window.cancelAnimationFrame = cancelAnimationFrame;
})( window );
(function() {
var div = document.getElementsByTagName('div')[0];
console.log("starting out", div.scrollTop);
div.scrollTop = 100;
console.log("haven't added listener yet", div.scrollTop);
window.requestAnimationFrame(function() {
div.onscroll = function() {
console.log('scrolled', div.scrollTop);
};
console.log("listener added", div.scrollTop);
});
})();
My code is supposed to place a banner after x amount of words. The code is working, but not as it should, as it is using slice to make the counting or slicing.
I need to use (count >= 20) instead of slice(0, 20)
This way the words in the text will be counted, instead counting the lines.
This is the code that does what I need: https://jsfiddle.net/714Lmgfu/3/
However, there is a loop in this code, which replicates the image (As show in the Fiddle) and I was not able to make return false working.
So I got some help and this was the final result https://jsfiddle.net/scadp0ar/, this code is working the way it should, except that, as stated before, it doesn't count the words. What should I change to make it count the words instead?
For example, change:
var img = '<img src="http://blog.leadlovers.com.br/wp-content/uploads/sites/23/2014/03/marca21-160x160.png" />'
$(".newsitem_text").html(function (i, h) {
return h.replace(h.split(/\s+/).slice(0, 20).join(' '), function (m) {
return m + img; });
});
for:
function check() {
if (count >= 20) {
newHtml += '<img src="http://blog.leadlovers.com.br/wp-content/uploads/sites/23/2014/03/marca21-160x160.png" />'
count = 0;
}
}
var img = '<img src="http://blog.leadlovers.com.br/wp-content/uploads/sites/23/2014/03/marca21-160x160.png" />'
$(".newsitem_text").html(function (i, h) {
// Match a word followed by one or more spaces 20 times
// Insert <img>-tag
// Repeat
return h.replace(/([^\s]+\s+){20}/g, function (m) {
return m + img;
});
});
Breakdown:
/ # Start regex
( # Start capturing group
[^\s]+ # Match everything - but space - 1 or more times
# could also be written as .+? that means:
# match everything 1 or more times, but not gready (meaning that if a space is encountered it will stop matching)
\s+ # Match space 1 or more times
) # End group
{20} # repeat 20 times
/ # End regex
g # global flag - will run the regex multiply times until no more matches are posible
Try using String.prototype.match() with RegExp /\w+./g to match alphanumeric character followed by any single character , Array.prototype.splice()
var img = '<img src="http://blog.leadlovers.com.br/wp-content/uploads/sites/23/2014/03/marca21-160x160.png" />'
var text = document.querySelector(".newsitem_text");
var html = text.innerHTML,
matches = html.match(/\w+./g);
matches.splice(20, 0, img);
text.innerHTML = matches.join(" ");
<div style="width:450px; margin-left:auto; margin-right:auto" class="newsitem_text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec pellentesque urna eu pulvinar maximus. Sed elit nunc, vestibulum ut eros vitae, pellentesque rhoncus ipsum. In et metus non diam porttitor maximus iaculis nec lectus. Quisque sodales scelerisque
auctor. Nam rutrum venenatis eros, eu condimentum erat placerat ut. Pellentesque sed tempus sem, eu viverra ipsum. Vestibulum nec turpis convallis, dapibus massa vitae, posuere mauris. Suspendisse mattis tincidunt lorem. Aliquam erat volutpat. Nullam
at tincidunt erat, maximus laoreet ipsum. Quisque nunc neque, semper tincidunt placerat eget, blandit a ante. Suspendisse pulvinar, velit eu ultrices pulvinar, lacus sapien tincidunt ipsum, eget sollicitudin mauris eros molestie ex. Etiam quis orci
dui. Phasellus vestibulum mollis molestie. Nam condimentum ornare nisl, sed finibus risus tempus vel. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Interdum et malesuada fames ac ante ipsum primis in faucibus. Vestibulum eget ullamcorper
lorem. Aliquam mollis elit in sem dapibus dapibus. Proin vel massa a arcu dictum tincidunt in ut ante. Sed feugiat tempus dictum. Praesent in leo ullamcorper, sodales turpis et, vehicula tellus. Duis pellentesque dui ac turpis tristique imperdiet. Sed
sed orci lectus. Suspendisse non egestas sem, sed tincidunt sem. Etiam laoreet dui sem. Mauris hendrerit massa tempus, euismod arcu sit amet, eleifend quam. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus
id fringilla mauris. Cras dapibus non lacus at finibus. Nullam vitae sagittis neque. Mauris libero velit, interdum non vehicula non, lacinia non augue. Maecenas elementum lacinia interdum. Morbi eget mollis nisl. Integer accumsan condimentum tellus,
lacinia pellentesque urna volutpat a. Nullam semper sem et erat commodo sollicitudin. Proin rhoncus felis eu aliquam venenatis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla pretium velit eu molestie
condimentum. Vestibulum vitae velit mi. Integer nec leo quam. Nam pulvinar ligula congue consectetur tristique. Donec placerat faucibus diam sit amet fermentum. Ut id pellentesque risus. Nunc lacus orci, rhoncus ut risus sed, mattis posuere tellus.
Nulla pellentesque eros sed neque consectetur dictum.</div>
jsfiddle https://jsfiddle.net/scadp0ar/3/
You should try something like this:
var img = '<img src="http://blog.leadlovers.com.br/wp-content/uploads/sites/23/2014/03/marca21-160x160.png" />';
jQuery( document ).ready(function( $ ) {
$(".newsitem_text").html(getTextWithImageBetweenWords($(".newsitem_text").html(),20));
});
function getTextWithImageBetweenWords(text, count){
var split_text = text.split(' ');
var _out = [];
var words = split_text.length;
for(var i=0;i < words; i++){
if(i !== 0 && i === count){
_out[i] = split_text[i] + img;
}
else{
_out[i] = split_text[i];
}
}
return _out.join(' ');
}
This is a more readable and easy way to accomplish this, here is the JSFiddle!
Note: if you want to repeat the image every n (20 in your case) words, just change i === count for i % count === 0.
From your comment, you may want to edit the question (just for clarity not trying to be a jerk). Also, by splitting at space, the count is of words. '\s' is space '\n' is new line '\t' is carriage return, '\r\n' is a special type of carriage return. You could potentially make a more complicated regex to cover everything that is not a new line or a space '\t|\s|\r\n'. To place the image within lines, you can use a styling trick as explained later.
If you want to have the image not repeat change:
function check() {
if (count >= 20) {
newHtml += '<img src="http://blog.leadlovers.com.br/wp-content/uploads/sites/23/2014/03/marca21-160x160.png" />'
count = 0;
}
}
For an even nicer fit, try align="right" which will wrap the text around the image.
//jQuery(function ($) {
jQuery( document ).ready(function( $ ) {
var img = '<img align="right" src="http://blog.leadlovers.com.br/wp-content/uploads/sites/23/2014/03/marca21-160x160.png" />'
$(".newsitem_text").html(function (i, h) {
return h.replace(h.split(/\s+/).slice(20,21).join(' '), function (m) {
return m + img; });
});
});
to
function check() {
if (count == 20) {
newHtml += '<img src="http://blog.leadlovers.com.br/wp-content/uploads/sites/23/2014/03/marca21-160x160.png" />';
}
}
To avoid using a nasty loop, you could slice at a different location or use splice:
//jQuery(function ($) {
jQuery( document ).ready(function( $ ) {
var img = '<img src="http://blog.leadlovers.com.br/wp-content/uploads/sites/23/2014/03/marca21-160x160.png" />'
$(".newsitem_text").html(function (i, h) {
return h.replace(h.split(/\s+/).slice(20, 21).join(' '), function (m) {
return m + img; });
});
});
To wrap your image within the words use align="left" or align="right" in the image tag.
<img align="right" src="http://blog.leadlovers.com.br/wp-content/uploads/sites/23/2014/03/marca21-160x160.png" />
I want to change the visibility of an element after the user scrolls down 100px.
I have some code already,
var fixed = false;
$(document).scroll(function() {
if( $(this).scrollTop() >= 100 ) {
if( !fixed ) {
fixed = true;
$('#logo-scroll').css({position:'fixed', display:'visible !important'});
}
} else {
if( fixed ) {
fixed = false;
$('#logo-scroll').css({display:'none'});
}
}
});
JSFiddle.
The code has two problems.
It doesn't default to be invisible, I want it so it starts invisible.
It doesn't repeat, when the user scrolls back up, it doesn't go back being invisible.
More details,
I want to make something like this header, but, as you can see, there's a certain point where you see half of the small logo, and a PART of the bigger one. It doesn't affect techcrunch much as the header is small, but on my site, it does. I have made everything, I just need to start it in display:none, and become visible after 100px.
Use: display:block; and display:none;
jsFiddle DEMO
Add this to your CSS:
#logo-scroll{ display:none; position:fixed; }
jQ:
var $logo = $('#logo-scroll');
$(document).scroll(function() {
$logo.css({display: $(this).scrollTop()>100 ? "block":"none"});
});
BTW: on TC page it's just a CSS play with z-indexes. nothing more. all elements are visible at page load, it's just the scroll that makes appear a z-index lower element beneath the big logo.
In plain Javascript would be like this:
var win = window,
docEl = document.documentElement,
$logo = document.getElementById('logo-scroll');
win.onscroll = function(){
var sTop = (this.pageYOffset || docEl.scrollTop) - (docEl.clientTop || 0);
$logo.style.display = sTop > 100 ? "block":"none" ;
};
Well the question has already been answered. just adding a better example which might be useful for others and it's exactly what op wants.
code and demo
Edited: Added actual code from original source.
jQuery:
// This function will be executed when the user scrolls the page.
$(window).scroll(function(e) {
// Get the position of the location where the scroller starts.
var scroller_anchor = $(".scroller_anchor").offset().top;
// Check if the user has scrolled and the current position is after the scroller start location and if its not already fixed at the top
if ($(this).scrollTop() >= scroller_anchor && $('.scroller').css('position') != 'fixed')
{ // Change the CSS of the scroller to hilight it and fix it at the top of the screen.
$('.scroller').css({
'background': '#CCC',
'border': '1px solid #000',
'position': 'fixed',
'top': '0px'
});
// Changing the height of the scroller anchor to that of scroller so that there is no change in the overall height of the page.
$('.scroller_anchor').css('height', '50px');
}
else if ($(this).scrollTop() < scroller_anchor && $('.scroller').css('position') != 'relative')
{ // If the user has scrolled back to the location above the scroller anchor place it back into the content.
// Change the height of the scroller anchor to 0 and now we will be adding the scroller back to the content.
$('.scroller_anchor').css('height', '0px');
// Change the CSS and put it back to its original position.
$('.scroller').css({
'background': '#FFF',
'border': '1px solid #CCC',
'position': 'relative'
});
}
});
HTML
<div class="container">
<div class="test_content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus interdum metus nec neque convallis id interdum nibh aliquet. Nulla eget varius diam. Ut ut dolor dolor. Mauris vehicula sodales mi quis euismod. In sem metus, volutpat nec fringilla sed, fermentum ac turpis. Cras aliquam venenatis rutrum. Donec pharetra ante sit amet justo pellentesque nec consequat ante elementum. Ut imperdiet iaculis tortor, id pretium urna pharetra sit amet. Aenean pharetra nunc risus, ac scelerisque urna. Morbi dictum egestas augue, in euismod metus commodo ac. Duis nisl ante, consequat et tincidunt id, eleifend eu ante. Integer lectus velit, tempus eu feugiat et, adipiscing ut mauris.
</div>
<!-- This div is used to indicate the original position of the scrollable fixed div. -->
<div class="scroller_anchor"></div>
<!-- This div will be displayed as fixed bar at the top of the page, when user scrolls -->
<div class="scroller">This is the scrollable bar</div>
<div class="test_content">
Quisque sollicitudin elit vitae diam consequat accumsan. Suspendisse potenti. Donec dapibus tortor at justo eleifend at pellentesque leo lobortis. Etiam ultrices leo et nulla iaculis eu facilisis augue fermentum. Pellentesque eu leo purus. Vestibulum bibendum, metus at bibendum blandit, lacus neque porttitor diam, id facilisis lectus mauris et leo. Donec adipiscing interdum lacus sed condimentum. In auctor sollicitudin orci, ac interdum risus aliquet ullamcorper. Curabitur mollis accumsan vulputate. Etiam adipiscing diam nec dui posuere ut tincidunt felis tristique. Vestibulum neque enim, placerat sed placerat commodo, consectetur ac mauris. Sed ultrices pretium nibh, a blandit libero imperdiet pulvinar. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
</div>
...
</div>
CSS:
.container{font-size:14px; margin:0 auto; width:960px}
.test_content{margin:10px 0;}
.scroller_anchor{height:0px; margin:0; padding:0;}
.scroller{background:#FFF; border:1px solid #CCC; margin:0 0 10px; z-index:100; height:50px; font-size:18px; font-weight:bold; text-align:center; width:960px;}