How to leave the scroll always down in JavaScript? - javascript

I have a div where I would like to always scroll down.
scrollDown(){
var chatt = this.conversa;
this.conversa.scrollTop = chatt.scrollHeight;
}
verificKeyPress(e){
if (e.key == "Enter") {
this.scrollDown();
...
}
}
<div id="scroll" ref={(conversa) => this.conversa = conversa} style={{display: "block",overflowY: "auto", overflowX: "hidden", position: "absolute", ...}}>
...
</div>
In this link is a giphy showing the error that is giving. Attention in the sequence entered and where it appears: https://media.giphy.com/media/LUeVZl33p6WlQrVmq9/giphy.gif.
Thank you!
Note: In the function verifyKeyPress has more thing to work sending the message, but I did not put it because it is extensive
I got it, the problem is that this function (this.scrollDown) should be in the callback of another function that I did not show here, I apologize, it would be difficult for someone to help me, I have little experience, but anyway thank you.

I'm not clear what you are attempting to do. Are you wanting the program to "page down" one screen full each time you hit enter? Or are you wanting to go to the bottom of the entire page w/enter?
In the first case, you'll have to use "view height" * "pageNum" for the scrollTop to allow for a view full to move each time return is hit. This will be tricky as it will be hard to get it to center just right on the top item.
In the second case, I believe scroll height will need to be set to "page height" - "view height". These are "general" values, don't recall the precise JS/CSS var names for these offhand but should be easy to look up
If you'd like to clarify what the desired behavior is I'm happy to look a little deeper

Related

Scroll to top of a bubble in botframework webchat

Some answers of our chatbot are very long. The webchat scrolls automatically to the bottom so users have to scroll up to get to the top of the bubble and start reading.
I've implemented a custom renderer (react) to wrap the answers into a custom component which simply wraps the answer into a div-tag. I also implemented a simple piece of code to scroll to the top of the bubble.
const MyCustomActivityContainer = ({ children }) => {
const triggerScrollTo = () => {
if (scrollRef && scrollRef.current) {
(scrollRef.current as any).scrollIntoView({
behavior: 'smooth',
block: 'start',
})
}
}
const scrollRef: React.RefObject<HTMLDivElement> = React.createRef()
return (
<div ref={ scrollRef } onClick={ triggerScrollTo }>
{ children }
</div>
)
}
export const activityMiddleware = () => next => card => {
if (/* some conditions */) {
return (
<MyCustomActivityContainer>
{ next(card) }
</MyCustomActivityContainer>
);
} else {
return (
{ next(card) }
)
}
};
But this only works if the scrollbar slider is not at its lowest position (there is at least 1 pixel left to scroll down, see here). The problem is the useScrollToBottom hook which always scrolls to bottom automatically if the scrollbar is completely scrolled down.
Is there any way to overwrite the scroll behavior or to temporarily disable the scrollToBottom feature?
As there is no reproducible example I can only guess.
And I'll have to make some guesses on the question too.
Because it's not clear what exactly in not working:
Do you mean that click on the <div> of MyCustomActivityContainer and subsequent call to triggerScrollTo doesn't result into a scroll?
That would be strange, but who knows. In this case I doubt anyone will help you without reproducible example.
Or do you mean that you can scroll the message into view, but if it is already in the view then new messages can result into a scroll while user is still reading a message.
That's so, but it contradicts with you statement that your messages are very long, because that would be the problem with short messages, not with the long ones.
But anyway, you should be able to fix that.
If it works fine with 1 pixel off the lowest position, then just scroll that 1 pixel. You'll need to find the scrollable element. And do scrollable_element.scrollTop -= 1. I tested this approach here. And it worked (there the scrollable element is the grandparent of <p>'s)
Or do you try to scroll automatically at the moment the message arrives? Аnd that is the real issue, but you forgot to mention it, and didn't posted the code that tries to auto-scroll?
In that case you can try to use setTimeout() and defer the scroll by, let's say, 200ms.
This number in based on what I gathered from the source:
BotFramework-WebChat uses react-scroll-to-bottom
In react-scroll-to-bottom there are some timeouts 100ms and 34ms
BotFramework-WebChat doesn't redefine them
There are some heuristics in react-scroll-to-bottom that probably coursing the trouble
https://github.com/compulim/react-scroll-to-bottom/blob/3eb21bc469ee5f5095a431ac584be29a0d2da950/packages/component/src/ScrollToBottom/Composer.js
Currently, there are no reliable way to check if the "scroll" event is trigger due to user gesture, programmatic scrolling, or Chrome-synthesized "scroll" event to compensate size change. Thus, we use our best-effort to guess if it is triggered by user gesture, and disable sticky if it is heading towards the start direction.
And
https://github.com/compulim/react-scroll-to-bottom/blob/f19b14d6db63dcb07ffa45b4433e72284a9d53b6/packages/component/src/ScrollToBottom/Composer.js#L91
For what we observed, #1 is fired about 20ms before #2. There is a chance that this stickyCheckTimeout is being scheduled between 1 and 2. That means, if we just look at #1 to decide if we should scroll, we will always scroll, in oppose to the user's intention.
That's why I think you should use setTimeout()
Since there isn't a reproducible code for me tweak and show you. My suggestion is tweak your code slightly. Chatbot requires constant streaming of data when a new message arrives calculate the height of the div element created for the message. If the div element is greater than the widget height scroll to the top else you can choose to leave it as it is.

JS (No Jquery) - Change CSS when scrolled to a set point

Sorry, but I am a complete noob with JS. I am using Bootstrap to try build my first website.
The website has a fixed top navbar. I want to change the navbar's border-bottom properties when it reaches the bottom of the header div (about 480/500px down the page).
Currently the border-bottom is white, but I want to change it to blue when scrolled beyond a certain point (bottom of header) and then change back to white if scrolled back up again. The effect I want is the appearance of the fixed nav 'picking up' the bottom border of the banner section when it scroll's past.
I have given the navbar div an id of id="n1", and created a class .navbar1{border-bottom: 1px solid rgba(46,152,255,1)!Important;} to add to override the existing css.
I am not using jQuery because I don't use much JS and I don't want to call it just for a few things - it is a big file. I have tried various things without any success. Probably because they relied on jQuery? I don't know. For example, the last one was:
$(window).scroll( function(){
if($(window).scrollTop() > 50) $("n1").addClass("navbar1");
else $("n1").removeClass("navbar1");
});
Anyway, I was hoping someone may be able to help me with the plain/pure JS to change the attribute properties as described. Thank you in advance for any assistance.
EDIT:
This has been kindly answered below. But given some comments, I thought it might be useful to clarify my use of JS: My website requires very little JS functionality so I have chosen to inline my JS, rather than call an external JS file or files - such as jquery.js and bootstrap.js which are relatively large files.
Although I lose the benefit of caching the JS, and my HTML is slightly larger, I am happy to do that because in my case I feel those losses are more than made up for the increased initial page load speed from:
not having to make additional http requests,
not having to load relatively large files.
It is certainly not for everyone, but I feel that it suits my case. Having said that, when all is done and my website is up and running I will probably do some testing to see whether a custom external JS file is better again. Basically, I am only using Bootstrap for its CSS functionality, not its JS functionality. I hope that makes sense.
This demo may help you!
It doesn't use jQuery.
Here is the javascript code:
window.onscroll = function() {
var nav = document.getElementById('nav');
if ( window.pageYOffset > 100 ) {
nav.classList.add("navbar1");
} else {
nav.classList.remove("navbar1");
}
}
I did a small change on #radonirina-maminiaina amazing answer.
While it works, I do prefer avoiding doing unnecessary DOM calls during the onScroll event. The onScroll event can be triggered quite often on some devices, so it's best to keep its handler as fast as possible.
In my solution, I cache the nav DOM element on a closure and I only update its classes if the offset changes.
window.onscroll = function () {
let isScrolled = false
const scrollPoint = 100
const nav = document.getElementById('navbar')
function onScroll () {
if ( window.pageYOffset > scrollPoint && !isScrolled ) {
nav.classList.add("scroll");
isScrolled = true
} else if (window.pageYOffset <= scrollPoint && isScrolled) {
nav.classList.remove("scroll");
isScrolled = false
}
}
onScroll() // Makes sure that the class is attached on the first render
return onScroll
}()

Show advertisement while game loads

I looked around internet and was always looking like from previous 6 months for a script that could load flash content/game while showing an actual loading screen But I always received a few answers:
It is not possible to show an actual loading with Javascript.
You can do it only by adding action script to the flash file maybe they are talking about FLA
Why Don't you show a fake loading screen that appears and show some
seconds and then disappears (the most annoying this of such screen
is that they first make user load 15 seconds then the flash starts
loading, if it starts loading those 15 seconds still it is worth
something it is good BUT making them wait double is really bad)
But at last I found something that I was looking forever. A Jquery based script that shows actual loading (shows ad too) and uses swf Object to talk to flash content too. It is really awesome as it doesn't require you to do changes to the FLA, it is just pure outer environment dealing. So now the question arises what's the issue then. Well the issue is that this script was made for pixels, it works if you are using width and height for flash in pixels, while I can't use pixels as I am using %ages (this way user have ability to go full screen optionally by pressing f11).
So as you can see I want that script to work with %ages that is my problem, but as I mentioned earlier I didn't came here right away I have been asking for help (Actually Begging) in over 14 forums from previous few months and of course some good people still exists some people helped me to reach a certain point (but it didn't solve the problem) So now I will provide some Markup:
Here is link to the script that I am talking about http://www.balloontowerdefense.net/jquery-preloader/jquery-preloader.html (It is the link to the creator of this script)
Here is a link to working example (flash based on Pixels) http://www.balloontowerdefense.net/jquery-preloader/example.html
Some one helped me here but it didn't work 1 month ago. The person told me that I should change the plugin Named as Preroll the changes preferred were these
Modify the plugin to use user-supplied units instead of pixels. To do this, you will need to modify two functions in the plugin, applygameiframe and showgame.
applygameiframe should be changed to:
var applygameiframe = function() {
var gc = '#'+settings.gameframe;
var iframe = $('<iframe />').attr({
"id": settings.gameid,
"src": settings.swf,
"frameborder": 0,
"scrolling": "no",
"marginwidth": 0,
"marginheight": 0
}).css({
"height":'settings.height
"width": settings.width
});
$(gc).append(iframe);
return true;
};
showgame should be changed to:
var showgame = function() {
var ac = '#' + settings.adframe;
var game = '#' + settings.gameframe;
$(ac).hide();
$(game).css({
"width": settings.width,
"height": settings.height
});
};
Once those changes are made, the inline CSS should be set to whatever you supply as parameters (i.e., 100%, 50em, etc.).
I did the changes told to be done as described above to the Preroll plugin and after that this is what I get http://files.cryoffalcon.com/MyFootPrint/fullscreen.html
Now if you let the game load (as loading screen appears) all is well done except that in the end, the game doesn't appear, it loads but when it should skip and make the game appear at that time something goes wrong. (For reference you can see this link http://www.balloontowerdefense.net/jquery-preloader/example.html here when the loading finishes then game appears)
Can Someone Fix this problem?
Note: Sorry for not providing JsFiddle but as I live in Afghanistan with 5KBps speed it is not possible for me.
I didn't provided the HTML, CSS and JS that makes up the whole demo page as I thought it will make the question very long but still if you think I should provide Please let me know in comments.
I tried my best to make the question more relevant with Relevant Markups BUT still If I am missing something I would try my best by editing it and providing it you again.
Being an accountant, I tried my best to use programmers terms, coding is my passion but I am still in learning stage of JS
UPDATE: After solving the problem here you can see now everything is fine. http://files.cryoffalcon.com/MyFootPrint/newfullscreen.html
Credit: Goes to the one who answered this question.
This seems to be just a pure css problem. You're trying to set the width to 100% while the parent of div.gamewrapper has no width or height. That's why the size is 0 and it will not show up.
The trick you need to apply is add the following to your style:
html, body, .gamecontent {
height: 100%;
width: 100%;
}
Update:
Also, remove float: left; from .gamecontent .game, and add a width and height of 1px such that it becomes:
.gamecontent .game {
margin:0px auto 0px auto;
padding:0px;
overflow:hidden;
width : 1px;
height : 1px;
}
Well, after an hour and a half of playing Bloons on your link (my untouched work load can verify that), I feel it's safe to say that the full screen features work exactly as I'd expect them to. I'm using Chrome 18.0.x.
My experience was: Click link, game loads. The loader took about 2 seconds longer to finish then it took for the "Click Here to Show the Game" button appeared. After, an ad appeared for 10seconds and then I clicked "Play" and it went right to the game. Full screen worked correctly to my knowledge, although when I left full screen the game didn't resize back down - the bottom section was cut off.
I know that doesn't answer your question, but perhaps the issue is only in certain browsers?
i found that in FF the problem seems to be the height and width of 100%. I changed the script slightly to:
$(game).css({
"width": window.innerWidth,
"height": window.innerHeight
});
and now the game shows correctly in FF.

What's the wisest way to detect if a visitor has scrolled to a certain point in a page?

I've looked at this:
http://imakewebthings.com/jquery-waypoints/#about
and would like to incorporate a similar idea into a plugin I have. Waypoints looks intriguing but perhaps more than what I need. I'm also wanting to trigger an alert (or similar) when a certain point on the page is reached.
Truth be told, this is related to Google Analytics and getting more accurate bounce rates. I'll spare you the particulars for now but my presumption is that if the visitor scrolls to certain spot on the page and then leaves before visiting any other page that such single page visit is not a real bounce. That is, they interacted with the page. It wasn't glance and go.
I have a plugin for GA and would like to integrate this idea of scrolling and/or reaching a particular spot on the page to be an event that can be tracked. But I'm casting a new for insight before I jump in and get my hands dirty.
Finally, I'm still pretty new to this so please explain clearly and if possible provide links that would lead to my further education.
You can check if the user has scrolled with the scroll event...
window.addEventListener('scroll', function() {
// Scrolled.
});
jsFiddle.
// jQuery
$(window).scroll(function() {
// Scrolled.
});
jsFiddle.
...and you can tell where they have scrolled with document.body.scrollTop and document.body.scrollLeft.
var body = document.body,
scrollTop = body.scrollTop,
scrollLeft = body.scrollLeft;
jsFiddle.
// jQuery
var body = $('body'),
scrollTop = body.scrollTop(),
scrollLeft = body.scrollLeft();
jsFiddle.

How to control the jump to a bookmark inside a page

I'm trying to achieve a page with a certain number of divs, each of which has a bookmark (a name). The problem is, when I jump to one of the bookmarks, part of the text is gone, caused by the design. I'd like to know if there's a way to change the behaviour of the bookmark, so it won't set the start of it at the top of the page, but a set number of pixels below.
The page can be accessed here: Not longer online, sorry.
The behaviour occurs when you go to any of the bookmarks (except #6, because the document ends there), like on here: Not longer online, sorry.
Can this be solved by a css property or any other way? (update) I'd prefer this over a javascript solution because I'm planning to use javascript to tab them, and keep the bookmarks in case of disabled javascript
You can do it with JavaScript using scrollBy. Put this in a load listener or onload handler:
if(window.location.hash.length > 1) {
window.scrollBy(0, -60); // Adjust to suit your needs.
}
window.onhashchange = window.onload = function () {
if( window.location.hash.length && window.scrollY > window.pageYOffset ) {
window.scrollBy( 0, -100 ); // Scroll up 100 pixels on hash change
};
};
I got the answer myself, so this is basically for references.
To ignore the 100px offset that is caused by the header, I added a padding-top of 100px to each single div element, and then I changed the links to go to the div's instead of the a elements I added. This padding-top basically makes the text appear where it should and thus solved my problem.

Categories

Resources