retain CKEditor scroll bar at cursor position - javascript

I'm using the similar code to retain cursor position for ckeditor.
var range = null;
editor.on( 'blur', function() {
range = editor.getSelection().getRanges()[ 0 ];
});
someElement.on('click',function() {
var editor = CKEDITOR.instances.editor1;
if(editor){
editor.focus();
range.select();
}
});
I'm able to retain cursor position but the scrollbar scrolls to the top.
How can i keep/retain the scrollbar at same position as of cursor's?

range.select().scrollIntoView() helped me out!!

I have several editors on a long page, and scrollIntoView() never did exaclty what I wanted: either it scrolled laso the container page, or it doesn't, or it puts the elemnt to show just one line after the viewport... so, since my need was simply to return to the previous position after a small change in the HTML with setData(), I could do the following:
let window = editor.document.getWindow().$ ;
let scrollX = window.scrollX ;
let scrollY = window.scrollY ;
[...]
editor.setData(contents, {
callback: function() {
editor.document.getWindow().$.scrollTo(scrollX, scrollY) ;
}
}) ;
I don't think that CKEditor (at least, not the 4.x series) has the proper APIs for this, so I had to go to the underlying DOM.

Related

Issue calculating table scrollbar location

So I have a script that adds a slight shadow to table edge where you can scroll, depending on the location of the scrollbar, but it sometimes doesn't work.
This is one part of it:
$('table').on('scrollstart scrollstop', function(){
if($(this).parent().hasClass('table-wrap')){
var elem = $(this),
elemBody = elem.find('tbody'),
elemParent = elem.parent('.table-wrap');
var scrolled = (elemBody.outerWidth() - elemParent.outerWidth() - elem.scrollLeft());
if(scrolled === 0){
elemParent.addClass('left_active');
elemParent.removeClass('right_active');
} else if(elem.scrollLeft() === 0) {
elemParent.removeClass('left_active');
elemParent.addClass('right_active');
} else {
elemParent.addClass('left_active');
elemParent.addClass('right_active');
}
}
});
This part sometimes I have to add "+1" to "elem.scrollLeft() --here---); to make it work.
var scrolled = (elemBody.outerWidth() - elemParent.outerWidth() -
elem.scrollLeft());
But then I noticed, some tables it helps and on others, it stops working. Meaning when I scroll to right the 'right_active' class will not disappear.
Any suggestions?
Have you tried including scrollbar width in your calculation for var scrolled?
var scrolled = (elemBody.outerWidth() - elemParent.outerWidth() - elem.scrollLeft());
I think you are on the right track but the width is probably not precise since .outerWidth() doesn't include scrollbar width. Hence, the maximum scroll width is always greater than the actual element width.

Capturing scroll on click of a button

I have a webpage where there is scroll happening to next section within the webpage on click of a button. Can someone please suggest how to capture that scroll? Code is with in the anchor tag and href is pointing to # to scroll to next section in page. I am not sure how to validate if scroll actually worked?
You could check that the anchor is scrolled at the top of the window by checking the positon relative to the viewport with getBoundingClientRect() :
browser.get('https://www.w3.org/TR/webdriver');
$("[href='#capabilities']").click();
// assert that the position of the anchor relative to the top border of the window is less than 16 pixels.
var anchor = $('#h-capabilities');
var isCloseToTop = browser.executeScript(e => !(e.getBoundingClientRect().top >> 4), anchor);
expect(isCloseToTop).toBeTruthy();
Note that if the anchor is at the very bottom of the document, the anchor will not be at the top of the window, but somewhere within.
So you should also consider this case with a more generic solution:
browser.get('https://www.w3.org/TR/webdriver');
$("[href='#informative-references']").click();
expect(isScrolledTop($('#h-informative-references'))).toBeTruthy();
function isScrolledTop(element) {
return browser.executeScript(function(elem) {
var doc = elem.ownerDocument,
viewHeight = doc.defaultView.innerHeight,
docBottom = doc.documentElement.getBoundingClientRect().bottom,
box = elem.getBoundingClientRect();
return box.top > -1 && (box.top < 25 || (docBottom - viewHeight) < 25);
}, element);
}
You can assert/check few things in this case:
the current URL to point to the correct # section:
expect(browser.getCurrentUrl()).toEqual("https://url.com/mypage#myparagraph");
check the scrollTop position of the body element (assuming it is what is scrolled - or the other scrollable container):
var body = $("body");
expect(body.getCssValue("scrollTop")).toEqual("someValue"); // or apply the "greater than" check
check the current active element (assuming there is an element focused once the "anchor" paragraph is becoming active)
solution based on your suggestion to use window.pageYOffset - compare the value before and after the click:
browser.executeScript('return window.pageYOffset;').then(function (offsetBefore) {
offsetBefore = parseInt(offsetBefore);
button.click();
browser.executeScript('return window.pageYOffset;').then(function (offsetAfter) {
offsetAfter = parseInt(offsetAfter);
expect(offsetAfter).toBeGreaterThan(offsetBefore);
});
});

scroll to a div when scrolling, and scroll to top when div disappear

I have 2 divs on my webpage. first div is "#pattern" (red one), and second on is "#projets".(blue one)
when use scrolls for the first time, the window scrolls automaticaly to the the second div "#projets". I'm using jquery scroll-To plugin.
it works nice, even if when the users scroll with a large amount of scroll there could be on offset from the "#projets" div... If someone has an idea to correct this would be nice, but that's not my main trouble...
Now i'm trying to scroll back to the top of the page ("#pattern" div) as soon as "#pattern" div reappears when scrolling, the red one. so basically it should be as soon as the offset from the top of my screen of my div "#projets" is supperior to 1.
I've tried so many solutions without results, using flags, multiple conditions... it can be the same kind of thing as on this page, but user should be abble to scroll freely inside the page, not scrolling from hash to hash :
http://www.thepetedesign.com/demos/onepage_scroll_demo.html
here is my html :
<div id="pattern"></div>
<div id="projets"></div>
my css :
#pattern {
height:300px;
width: 100%;
background-color:red
}
#projets {
height:800px;
width: 100%;
background-color:blue
}
and my jquery :
var flag=0 ;
$(window).on('scroll',function(){
var top_projets_position = $("#projets").offset().top - $(window).scrollTop();
if((flag==0) && $(window).scrollTop()>1){
$(window).scrollTo('#projets', 500);
flag=1;
}
if($(window).scrollTop()==0){
flag=0;
}
});
here is jsfiddle :
http://jsfiddle.net/jdf9q0sv/
hope someone can help me with this, I can't figure out what I'm doing wrong, maybe a wrong method ! thanks
It looks like you need to track 3 things:
The scroll direction occurs.
The area you are currently viewing.
If scroll animation is currently happening (we need to wait until it's done, or problems will occur).
http://jsfiddle.net/vx69t5Lt/
var prev_scroll = 0; // <-- to determine direction of scrolling
var current_view ="#pattern"; // <-- to determine what element we are viewing
var allowed = true; // <-- to prevent scrolling confusion during animation
var top_projets_position = $("#projets").offset().top + 1;
$(window).on('scroll',function(){
var current_scroll = $(window).scrollTop();
if(current_scroll < top_projets_position && current_view=="#projets" && current_scroll < prev_scroll){
scrollToTarget("#pattern");
}
if($(window).height() + current_scroll > top_projets_position && current_view=="#pattern" && current_scroll > prev_scroll){
scrollToTarget("#projets");
}
prev_scroll = current_scroll;
});
function scrollToTarget(selector){
if(allowed){
allowed = false;
$(window).scrollTo(selector, {
'duration':500,
'onAfter': function(){ allowed = true; current_view = selector;}
});
}
}
This is just a quick solution based on your original code. A better solution would be to do something more Object Oriented (OOP) and track values in an object. Perhaps take an array of elements on object creation, grab all the boundaries and use the boundaries in your scroll handler to determine when to scroll to the next div.

Getting current page position in IE8 when scrolling

Reference is this page:
http://demo.mypreviewbetasite.com/laverona/menu.html
File in question: http://demo.mypreviewbetasite.com/laverona/scripts/menu.js
The page works as expected in Firefox and Chrome, where as the user scrolls, the position of the window is checked against the position of my sub-menu, so that before it gets scrolled out of view, its position is set to fixed.
However, in IE8, the window position never gets updated as the user scrolls. My testing has shown that IE gets through all the functions, but only updates the windowPos variable when the page loads.
What can be done so that this page behaves the same in IE as it does in FF and Chrome?
this is from jquery documentation:
"The .offset() method allows us to retrieve the current position of an element RELATIVE TO THE DOCUMENT."
I can't understand why FF or Chrome return $('html').offset().top relative to the client screen/ It seems that IE's approach is more predictable.
Try that (use .scrollTop property of the DOM element instead of .offset().top):
$(document).ready(function(e){
//alert("subPos: " + subPos);
//first find the position of the things to sticky
submenu = $("#sub");
//submenu.removeClass("no-js");
subPos = $("#sub").position();
subPos = subPos.top;
var preScrollHtml = document.getElementsByTagName('html').item(0).scrollTop;
var preScrollBody = document.getElementsByTagName('body').item(0).scrollTop;
var checkPos = function(){
var scrolledHtml = document.getElementsByTagName('html').item(0).scrollTop;
var scrolledBody = document.getElementsByTagName('body').item(0).scrollTop;
if (preScrollHtml !== scrolledHtml) {
windowPos = scrolledHtml;
}
else {
windowPos = scrolledBody;
}
preScrollHtml = scrolledHtml;
preScrollBody = scrolledBody;
calculate();
}
var calculate = function() {
subPos = 64;
if (windowPos >= subPos){
$("#sub").addClass("fixed");
$("#minestre").css("marginTop", "50px");
}
else if (windowPos < subPos){
$("#sub").removeClass("fixed");
$("#minestre").css("marginTop", "0px");
}
//Setting text fields to show the values of everything can help in debugging
$("#windowpos").val(windowPos);
$("#subp").val(subPos);
}
//every time the window scrolls, this function is run
if ($(window).scroll){
$(window).scroll(checkPos);
}
else if(window.onscroll){
window.onscroll = checkPos;
}
});
I know this is old, but for new people coming to this question, you may want to check out Andy's answer to a similar question (which also seems to solve this one): https://stackoverflow.com/a/11396681/1793128

Find DOM elements at top and bottom of scrolling div with jQuery

I have a scrolling div containing list items. I have this boilerplate scroll event defined
$("#scrollingDiv").scroll(function(e) {
});
Inside of this scroll event function, how can I figure out which elements are at the top and bottom of the currently visible area?
You could try computing the positions of the list items with respect to the scrolling <div> and then scan the positions to see which ones match up with the scrollTop of the <div>.
Something like this perhaps:
var base = $('#scrollingDiv').offset().top;
var offs = [ ];
$('li').each(function() {
var $this = $(this);
offs.push({
offset: $this.offset().top - base,
height: $this.height()
});
});
$("#scrollingDiv").scroll(function() {
var y = this.scrollTop;
for(var i = 0; i < offs.length; ++i) {
if(y < offs[i].offset
|| y > offs[i].offset + offs[i].height)
continue;
// Entry i is at the top so do things to it.
return;
}
});
Live version (open your console please): http://jsfiddle.net/ambiguous/yHH7C/
You'd probably want to play with the fuzziness of the if to get something that works sensibly (1px visible hardly makes an element the top one) but the basic idea should be clear enough. Mixing in the height of #scrollingDiv will let you see which <li> is at the bottom.
If you have a lot of list items, then a linear search might not be what you want but you should be able to solve that without too much effort.

Categories

Resources