I just found out that my script is working fine in Chrome, but not in FireFox - and I can't figure out why.
This is the site in development: www.fireflycovers.com
The script should execute when one of the round green buttons is clicked. (scrolls the window to the next container)
The script looks like this at the moment:
$('.scroll').css('display' , 'block');
$('.scroll').on('click', function(e) {
var container = $(this).parent();
// Scans if last container in group
while (document != container[0] &&
container.find('~.col, ~:has(.col)').length == 0) {
// If so, search siblings of parent instead
var container = container.parent(),
nextdiv = container.nextAll('.col, :has(.col)').first();
}
// Back to first .col (when no next .col)
if (nextdiv.length == 0) {
nextdiv = $(document).find('.col:first')
};
// Animates scrolling to new position
$('body').animate({scrollTop:nextdiv.offset().top}, 1000);
return false;
});
});
Did you try debugging at all? As in, putting console.log statements throughout your method to see what the values of things are at certain times and watching it execute? Anyway, does using this help at all?
$('body,html').animate({scrollTop:nextdiv.offset().top}, 1000);
Verified from Animate scrollTop not working in firefox
You need html because firefox behaves differently when it comes to overflow.
Related
Environment: Safari 110.0.1, OSX (MacOS) 10.12.6
I am working on an image gallery type of display. There's an element that is loaded with an image by the Javascript; I want that element to have functionality on onmouseenter and onmouseout.
It would appear that I can't add those when I'm creating the img element, because the image is not loaded, and I read (somewhere, lol, it's been a long day) that an element has to be loaded before one can attach functions to it. I did try it in the HTML; no joy.
So I have a timer going, and I am trying to attach it there, but that doesn't work either - the functions are never called.
I tried starting the timer after the page is loaded, but, that doesn't work - the over/out functions still don't fire. The timer is definitely running, that's what forces the redraw if the page scaling changes, and that works. You can see what I want to happen with the mouse over/out by clicking the checkmark below the image.
Here's the page, all the HTML and Javascript code is visible there (lower on the page.) Any insight is appreciated.
The best I've been able to do so far is to get the events to attach to a surrounding div by specifying out in the HTML, where they do pretty much the right thing as far as the div is concerned. But when the mouse is over the image, it is out of the div, so the opposite of what I want happens: the onmouseout fires and the thing I want to have happen over the image goes away.
Is there some reason I can't attach these functions during the timer? Here's the timer code:
function mousingover()
{
console.log('over');
if (dismode == 1) return;
show_image_notes('mypic');
}
function mousingaway()
{
console.log('away');
if (dismode == 0) return;
show_image('mypic');
}
function ticker()
{
// var pic = document.getElementById('mypic'); // get (eventually) ready element
// var eltype = pic.nodeName;
// console.log('eltype:',eltype);
// pic.onmouseenter = function() { mousingover(); }
// pic.onmouseout = function() { mousingaway(); }
// console.log(pic.onmouseout);
// When the display is rescaled, the width of this div changes
// This is used to re-fire the calculation of where the notes go:
var myAnchor = document.getElementById('picdiv');
var xd = myAnchor.offsetWidth;
if (working == 0 && xd != xdim)
{
working = 1;
if (dismode == 1) show_image_notes('mypic');
else show_image('mypic');
xdim = xd;
working = 0;
}
tcounter = tcounter + 1;
if (tcounter > 10 || tcounter < 0) // trying to delay so image has time to load
{
var pic = document.getElementById('mypic'); // get (eventually) ready element
pic.onmouseenter = function() { mousingover(); }
pic.onmouseout = function() { mousingaway(); }
tcounter = 0;
}
}
The console confirms that I am finding the IMG with that ID, which is correct, and also that the functions are attached. They just don't fire.
I'm actively working on this, so the code for the timer will change; the page always displays the code that's in use at the moment.
I'm trying to do this with pure Javascript.
I looked at your HTML, and you have a canvas element in there along with the img element. It looks like the canvas overlays the image, yes? If so, the canvas is going to get the mouse events, and the img won't see them.
I'm trying to create an element in a Wordpress site where a piece of content begins partway down the screen, and sticks to the top of the screen when the user scrolls down.
I've tried various things, and none of them have worked. The most recent attempt uses Javascript to give and take away a class to the content I'm trying to move/fix.
The code is
jQuery( document ).ready(function($) {
alert( "test1!" );
var wrap = $("#wrap");
wrap.on("scroll", function(e) {
if (this.scrollTop > 147) {
wrap.addClass("fix-search");
alert("test2");
} else {
wrap.removeClass("fix-search");
}
});
});
The file is enqueuing properly since the first test alert ("test1" fires, but "test2" doesn't fire as I scroll down the screen. I've had that same piece of code working in a modified version of the original code on codepen (http://codepen.io/anon/pen/NqKKVN) so I can only assume this is something weird with Wordpress interacting with Javascript.
So yeah, anyone know a way to either do that I'm wanting to do in a way that will work with wordpress, or to get the above piece of code working properly?
EDIT: This has been solved. For the reference of anyone else with the same problem the piece of code that eventually worked was
jQuery( document ).ready(function($) {
var scrollTop = $(window).scrollTop();
function scrollUpdate() {
var scrollTop = $(window).scrollTop();
var wrap = $("#menu-all-pages");
if (scrollTop > 147) {
wrap.addClass("fix-search");
console.log("Menu at top");
} else {
wrap.removeClass("fix-search");
console.log("Menu at set point");
}
console.log(scrollTop);
}
window.onscroll = scrollUpdate;
});
I have implemented a similar solution in my blog a few years ago. I got it working by scripting this way:
Add a variable scrollTop which would contain the value in pixels
scrolled from the window top.
var scrollTop = $(window).scrollTop();
See, I use jquery function scrollTop applied to the selected object "window". It would return the value scrolled from the very top of the browser. It does work on Wordpress, I have tried it on my blog.
Put this code in a function scrollUpdate. We'll call it later to update
the scroll value from top
function scrollUpdate() {
var scrollTop = $(window).scrollTop();
}
The function should also contain all the logic checking the scrollTop value and thus applying styles and etc.
Let's make this function be called on every scroll.
window.onscroll = scrollUpdate;
Try it yourself!
P.S. I got a weird feeling, but you should better use hide / show instead of adding a whole css class to the page.
I have created the following application using iScroll: http://preview.na-software.co.uk/Demo/FutureLearning4/#/section-0
As the user flicks left and right or clicks the arrows in the bottom corners, the application moves the content sections it updates the history by changing the hash so that the user can move back and forth to other sections and bookmark them etc.
However! If you access a hash like: http://preview.na-software.co.uk/Demo/FutureLearning4/#/section-2 and then navigate a few sections and then use the back buttons two issues happen:
1.) It scrolls to the first screen (even though currentSection is correct, and iScroll has been told the correct section).
2.) If you click the back or forward button multiple times, you stop the animation and cause it to become confused and stick in between two sections.
Looking into the code, and seeing that the correct indexes and elements are being passed to iScroll on hashchange, and console logging out the offsets, I've discovered the issue is cause because the offsets are incorrectly set... however just doing refresh() won't fix the issue, as it will then reset the position.
Can anyone see where the problem is or see a way to fix this?
I should note that this bug ONLY happens if you come into the application on a URL that isn't section 0 and then scroll around the application. This is because the offsets will be created correctly by your interactions. But if you come into a URL like section 3, then the offsets will be incorrect and so the hashchanges don't work correctly, if that makes sense.
The hashchange method looks like:
// handle hashchange events
$(window).hashchange( function(){
// read the hash to find out what the new section number is
var nums = location.href.match(/(section)-\d+/g).map(
function(x){ return +x.replace(/\D/g,"") }
);
// set currentSection
currentSection = nums[0];
// if the hashchange was called by user scrolling
if(hashCalledByScroll){
// no need to anything as they have already updated hash and scrolled
hashCalledByScroll = false;
} else {
// find the section to scrollTo
sectionToScrollTo = $('#horizontal > .sections > .section').eq(currentSection).attr('id');
// tell iscroll to scroll to the section
horizontal.scrollToElement( '#' + sectionToScrollTo, null, null, true );
}
// hide the menu on hashchange
hideMenu();
});
Testing your site, I noticed the following: Whenever I access the site via section-3 and then enter the url for section-2, the navigation would instead send me to section-0.
I believe this is the same behaviour as you are experiencing in 1).
So I investigated and came to the following analysis:
In the function horizontal.scrollToElement( '#' + sectionToScrollTo, null, null, true )
iScroll retrieves the utils.offset(el) [iScroll.js#772] for the given el-ement. This offset tells it, where the element to scroll to is.
iScroll goes through the element and all of its offsetParents to add up their offsets. This is where things are breaking: <div class="sections"> has a negative offset to its parent, which imho it should not have.
This, in turn, messes up the scrollTo-coordinates.
To see what I am talking about: document.querySelector('.sections').offsetLeft
This has all just been analysis. My approach to fix this would be to avoid scrollToElement() and instead use scrollTo():
...
} else {
// find the section to scrollTo
sectionToScrollTo = $('#horizontal > .sections > .section').eq(currentSection).attr('id');
// tell iscroll to scroll to the section
var posLeft = -$('#' + sectionToScrollTo)[0].offsetLeft;
var posTop = -$('#' + sectionToScrollTo)[0].offsetTop;
horizontal.scrollTo(posLeft, posTop, 1000);
}
// hide the menu on hashchange
hideMenu();
});
Thus, just calculate the location of the section you want to go to yourself.
About 2) I am not sure if there is much one can do about it. Jumping around quickly breaks a lot of carousels. Maybe a delayed callback to scrollEnd, verifying the validity of the current state.
Another thing I noticed is that you can accidentally stop the transition. Try to click, hold and release the cursor midway a transition - you need to be quick.
Hope this helps.
Found not best solution and it doesn't solve main problem, but it works.
$(window).hashchange(function () {
if (hashCalledByScroll) {
hashCalledByScroll = false;
} else {
var hpage = window.location.hash;
var hpage = hpage.replace('#/section-', ''); //get number of target page
var cpage = currentSection; //number of current page
var count = parseInt(hpage) - parseInt(cpage); //difference
while (count > 0) { //if difference positive: go forward count-times
horizontal.next();
count--;
}
while (count < 0) { //if difference negative: go backward count-times
horizontal.prev();
count++;
}
}
hideMenu();
});
FIDDLE
UPDATE:
I was able to get my scroller working as desired but I feel like I have hacked around the actual issue and would love it if anyone has a more solid answer, I've updated and noted in the snippets below the new jQuery I'm using.
I'm using iScroll-4 (http://cubiq.org/iscroll-4) for an iPad/Android web app, everything's working perfectly with the swipes and scrolling but I have a table of contents at the beginning of the app that allows users to jump to specific areas of the scroller --
I'm using the iScroll function scrollToElement(element, duration) in order to jump to the different areas. Also using scrollToPage(page, duration) to allow the user to manually navigate forward and backward one page at a time.
While watching the console logs the currPageX variable updates when I navigate with the scrollToPage function and when I swipe, but when using the scrollToElement the currPageX variable does not update.
Therefore if I jump to an element and then navigate forward with scrollToPage('next', 0) it will go backwards and navigate me to the next page after the table of contents.
I have tried using the scroll.refresh() function after scrollToElement, before, putting the function inside a timeout, etc. and I can't figure out why the currPageX is not updating.
Here's a snippet of the jQuery code that I'm using the two different functions:
// TO NAVIGATE FORWARD AND BACKWARDS
$('span.control').on('click', function() {
var slideDir = $(this).attr('data-dir');
if (slideDir == 'prev') {
var tehPg = tehScroll.currPageX-1;
} else if (slideDir == 'next') {
var tehPg = tehScroll.currPageX+1;
}
tehScroll.scrollToPage(tehPg, 0);
return false;
});
// TO JUMP FROM CONTENTS
$('li[data-page="toc"] span').on('click', function() {
var toPage = $(this).attr('data-page');
tehScroll.scrollToElement('li[data-page="'+toPage+'"]', 800);
// ADDED THE FOLLOWING LINE TO MANUALLY SET currPageX after scrolling!
tehScroll.currPageX = $('#slides li[data-page="'+toPage+'"]').index();
return false;
});
Did you consider using jquery-mobile-iscrollview widget plug-in? - there is a function scrollToPage(pageX, pageY, time), works well for me...
best
M
Thanks everyone, for the quick help! Script now works. I've updated the site and code below. Maybe someone can find this code useful. :)
I've gotten the page (http://www.katmcgo.com) to fade in as desired using jQuery. However, it only fades in on the index page -- all subsequent pages load as normal.
I have the following script in the header of each page (including the sub-pages that are not fading in); it is included in each page using PHP:
$(document).ready(function() {
function fadePage() {
// Target the tags you want to effect with the fade
var fadingTag = "section";
var fadingTag2 = "hr";
var delay = 0; // Initialize delay - Should start at 0
var delayStagger = 600; // Delay stagger - Time between elements fading in
var fadingNum = document.getElementsByTagName(fadingTag).length; // Find out how many elements you need to hide
// Get and fix the overall document height before it disappears (which will happen when elements are hidden)
var pageHeight = $(document).height() + "px";
$("#wrapper").css("height", pageHeight);
// Hide all targeted tags
$(fadingTag).css("display", "none");
$(fadingTag2).css("display", "none");
// Fade each targeted tag in, one by one
for (var i = 0; i < fadingNum; i++){
$($(fadingTag).get(i)).delay(delay).fadeIn(delayStagger);
$($(fadingTag2).get(i)).delay(delay).fadeIn(delayStagger);
delay += 350;
}
}
fadePage();
});
I've been racking my brain as to why this is happening, and doing searches to the find the answer, but coming up with nothing...
This page is in the early stages, so I'm just doing dev in Firefox and Safari... fade works in both, but only on the first page. Any help would be greatly appreciated.
install firebug in firefox. your getting an undefined element[0] on all pages except index.php.
Edit:
wrap your s3Slider call inside an if statement checking if the element exists.
if( $('#slider').length ) {
$('#slider').s3Slider({
timeOut: 3500
});
}
Alternatively you could not output that code from the server if your not on the index page.
You have an error coming from s3Slider.js on all of your subsequent pages. Probably because the slider element does not exist on those pages, but the plugin is still being called.
The fade script probably works fine.